I’ve been busy with a lot of annoyances like real life, but I’ve completed a rewrite of the database generation script for MyConbook, which introduces multi-convention support in preperation for the iOS app, as well as a redesign of the Android app I’ve been working on in my spare time. I’ve also been working on the side with an art site (which will remain unnamed) as a part-time developer, which has been eating at some of my extra outside-work development time.
I have a couple blog posts I really want to get to, including some about project planning and organization (similar to my Trello post, this time about OneNote). I’ll have to get to writing those soon, but I’m not dead.
Anonymous said: Hello Andrew, I start developing an android application and I arrive to check the if the airplane mode is changed and this work fine . but now what I want to know is the event on checking the checkbox of airplane mode . I get the event of airplane mode change but I want to do something when user click on airplane mode and before connection change to airplane in other way I want the event on keypress of airplane mode checkbox. I 'm waiting with please for your response.
Sorry, this isn’t possible! I assume you’re already listening to the broadcast event for the airplane mode change, but that’s the only thing an application is allowed to do when someone is switching into airplane mode from the settings menu.
Anonymous said: yes i was wondering how to make a bot like your groompbot but make it post things from a different channel and reddit
Groompbot is open source, so you can already use it and configure it for a different YouTube channel and subreddit.
If you go to https://github.com/andrewneo/groompbot you can check out the project, and see what you need to get going. It’s as simple as installing gdata and praw for Python, setting up the configuration file, and running the script at a regular interval.
I’ve been on vacation for the past few days and have put a lot of work into MyConbook for iOS. I’ve uploaded a video of my progress, have a few pieces left to do (including graphics) but at this rate I shouldn’t be long before I can submit it.
I’ve started using Trello for task management. Before, I would just have a huge list of things I wanted to do seperated by task in Evernote. This is okay to an extent, for simple lists, but I’ve found Trello is a wonderful way of going about managing tasks.
I’ve moved a lot of these sorts of lists into Trello, including for all my software projects as well as several other personal things (like stuff around the house, day job items, etc.) and find it to be a very well structured way of organizing my data. I like how instead of just having a basic “todo” list, I can customize each board however I like, allowing multiple categorizations, different approperations of tags (the colors), and especially multi-user support. I could so see a team working with it as a “to do” list instead of purely a bug tracker. Each item can have comments, due dates, images, even multiple checklists. The concept of moving a todo list out horizontally makes it a very powerful way of organizing data.
The screenshot above is for MyConbook. The layout for that is a pretty standard todo list, but if I wanted to I could create separate lists for upcoming conventions, Android, iOS, Web, etc. and organize everything independently. Not restricting me to how the application feels I should do things makes me want to do everything this way. I had been considering setting up a bug tracker just to track these sorts of things. I feel that this lets me do both - each project can be both a to-do list and track bugs I want to take care of. If a project has an external bug tracker, like on say Github, I can still add an item here and handle public communication and resolution externally.
It’s been a long while, unfortunately with no progress on the iOS version of MyConbook. But, after Google released their Tablet App Quality Checklist I figured it was time to do what I had thought about starting around June, and implement a tablet UI for MyConbook for Android.
When Android released Honeycomb (version 3.0), they added a UI concept called Fragments. Fragments are these neat, versatile elements in Android because they can be used in a number of ways - from simply being an entire Activity, to being a portion of an Activity, to just being a code block with a lifecycle. Fragments are simply classes that can be added to a layout (a view is actually optional), so this way you can have independent UI pieces in play at once.
I’ll get into Fragments themselves more at another time. For MyConbook specifically, a bit of a task had to be undertaken. I figured the best way to display the UI for tablets would be to have two split (~30%/70%) panes when a tablet device is landscape. This would usually involve a list on the left side, and a details view on the right, though this wouldn’t always be the case.
So to start, this meant I had to convert all of my existing Activities to Fragments. This isn’t too hard, but there are special things you have to pay attention to in the activity lifecycle that are different for fragments. You can get away with leaving them alone if it’s the only thing being called, but when you start to get into reuse you have to make sure your UI is being built in onCreateView instead of onCreate, for example. Converting most of the elements wasn’t too difficult, especially as many of them were already at least FragmentActivities, since MyConbook uses ActionBarSherlock.
Turning existing UI elements into fragments is one thing, displaying them at the same time is another. Normally, from one activity, you would simply start an Intent to display another activity, and pass along the arguments to be displayed. However, if you’re showing more than one fragment on the screen, the changing fragment needs to be created and informed via the parent activity. So, you would enter an “activity” like the schedule, and it would initiate the day select list in the left side fragment. Tapping one of these elements would normally create another activity, but in this case we want to show another fragment on the right, so the fragment code is created and the message for which day was chosen is passed along by a function, instead.
Creating and message passing by a parent gives us an advantage. Due to the way Android handles view layouts, if we’re not on a large screen in landscape view, the right side fragment container will not be inflated. So we can tell at runtime that it is not there, and instead replace the existing “left side” container (the only one, on any other size/orientation) with the new fragment. Fragments have automatic back-stacking, so we can pop it off and go backwards automatically without having to manage it.
I’ve implemented this for a few of the activities, and it seems to work rather well on both phones and tablets. Overall, however, I’d like to move to having one activity where the “action” is simply determed by a dropdown in the ActionBar instead, and never change layout away from that default split mode unless rotating the screen. This would be a little more complicated (I haven’t gotten menus in the Action Bar working yet, as is, for example) but with properly designed code it should be easy for this single activity to initialize an “action” and allow each action to handle its own tasks as is.
Right now I don’t have much in the way of pictures to help this make more sense, but once I’m closer to being done I’ll try and add some code snippets to make sense of it. Moving to Fragments and a split UI has been rather intimidating to me, since it requires a lot more code than plain activities do, but after a point it just starts to click.
I meant to write this up a bit ago, but I wanted to write something short (since it’s still in progress) about an older project I’ve gotten back to, called Muftec.
1 2 + print
Okay, one last post. Just wanted to show a diagram of the storyboard for the iOS version. The Storyboard feature is really neat. I hated doing UI work before they added this, it just seemed convoluted. I’m sure it’ll get worse when I actually get into talking to the UI from the code. Designing the workflow is a lot nicer now, though, at least, and I can see that it works even without data by running it in the Simulator.
In addendum to the previous post, I was reminded that I wanted to write a quick bit on using Git. I mostly wanted to mention, that instead of dropping the source for FMDB into my project, I included it as a submodule so the code is pulled in from the Github repository when you clone the project. This can help with licensing and stuff when I get around to that part. I’ll talk about licensing later, though I do note I have plans to make the source available for the Android, iOS and web versions of MyConbook.
For Git in general, I find it rather awesome. I used to use SVN a lot, and was confused why you would want a distributed source control system. There are plenty of blog posts that will explain Git better than me, but I find it much more valuable, particularly just pointing out the fact that your local repository doesn’t affect any of the others - so you can go ahead and break yours, create branches, merge like crazy, and only send back what you mean to send back.
Both Eclipse and XCode have a good integration for using Git, and no matter what source control you’re using, having it is better than nothing. I’m a little weird and don’t like to commit a project until I have something that “works”, even if it compiles. Otherwise I feel that I’m just going to be committing a lot of changes as I work out how I want to structure an application, and I could have saved time and trouble by waiting. I can miss out on some things like wanting to see how I did something in the past, but the turnover is so short at this early stage in a project that it’s not really worth it. That’s just me, though.
This is how the app looks so far. I didn’t have too much time to work on it today, kept getting distracted and finally got to head out to Hacker Dojo at about 8:30PM. Was hoping to get a key, but wasn’t able to yet, unfortunately, will try again later this week.
Anyway, I figure I’ve done enough with the UI (general layout) that I need to start being able to make it actually do things by pulling in the data.
Unfortunately, compared to Android, iOS has no real developer-friendly support for talking to databases. Core Data works if you’re maintaining your own data (which is usually the case, but not for MyConbook) but otherwise you have to use the native sqlite3 library, which means calling into C code. On Android, this is accomplished much more easily with the SQLiteDatabase class and cursors, then it can be presented as a content provider to be consumed with a wonderful new feature in Android 3 called a Loader. MyConbook uses this method on Android to present data to the UI without accessing the data source directly.
Back to iOS, fortunately there is already an Objective-C wrapper for SQLite called FMDB. I plan on using this for the iOS version. But since we have to deal with the database more or less directly, I’ll be writing a bunch of code to access the data. It will end up working similarly to a read-only ORM (we don’t write back to the sqlite DB). There will be a bunch of boiler code but I’m going to try and use inheritance as much as I can to keep it from getting too messy.
Basically, there will be a class for each “row”, which will contain a function to read the content of the row from the database and populate itself. The goal is to only read what data is nessicary in order to reduce data access times when trying to build the UI. Pulling in the entire table is much slower than reading a single row when that’s all you need. TableRows in iOS load on demand, so we can asyncornously load and display a row. Load from the database, parse the result and put it into an object, which is then bound to the UI view. Not too difficult!
It would be a lot nicer if there were ORMs written for iOS, but to be honest most of the time you’d be using Core Data anyway. I made a weird use case by having the application download a pre-built SQLite database from a server. If I wanted to tackle this a little differently (and I’ll probably have to in the future if I decide to support incremental data updates) I’d download a JSON file from the server instead, then dump that content into a local Core Data structure. Core Data uses SQLite anyway, but it’s used transparently, and only shows the developer the ORM side. This would be convienient but I’m going to try and keep the current route I’ve been using for the other version in order to avoid parsing JSON on iOS (which is another pain). As a note, a JSON structure is already being generated for the web version, at the same time as the SQLite database, so there’s no reason it couldn’t be used instead. I just don’t see it being easier than the database to use on device, especially when we need to do things like searches.
Originally, the Android version loaded the entire database into an object structure when it first started. I don’t remember if it ever worked that way once it was released, but there was an actually fair amount of exploration that went on in the month or so I had before the first convention where the app would get used. It was originally written before the Loader API was released, and fortunately most new Android features that don’t use something built into the core are backwards compatible either by using the Android Support Library, or just copying the code out of the repository and putting it into yours. Both loaders and the Action Bar (with the help of ActionBarSherlock) are both handled this way to work on lower Android versions in MyConbook.
So, this is probably as far as I’ll get today. I have an idea how I want to structure the database, and I’ve written up most of how it’s going to get done. The next time I get back to work on this (maybe tomorrow, with any hope) I’ll probably spend the time writing out the classes and the code the handle converting the SQLite results into objects. I’ve spent most of this post writing up how that works, anyway, so I’ll probably get more into the actual code and structure next time.
Page 1 of 2