POWERED by FUSION

My name is Jake Marsh. I'm a developer, designer, and writer.


Subscribe via RSS or Twitter.

#ios Posts

CoreData + AFNetworking = AFIncrementalStore

Posted

Another amazing open-source project from @mattt and the AFNetworking guys: AFIncrementalStore.

AFIncrementalStore is an NSIncrementalStore subclass that uses AFNetworking to automatically request resources as properties and relationships are needed. I had noticed NSIncrementalStore in the iOS 5 docs a while ago, but it was this article that got me to realize how unbelievably cool it was.

I can't tell you how much this is going to revolutionize the way many apps integrate with their backend API systems.

Please do yourself a favor and go checkout the project's README immediately.

Create Static Content Screens with Ease!

Posted

I often find myself needing to create what I call "static content" UITableViewControllers. Whether it be a "Support" or "About" screen, or possibly a simple "Login" or "Settings" screen, I find myself writing a ton of annoying, repetitive, boilerplate code for these types of screens all the time.

What's a guy to do? Enter: JMStaticContentTableViewController.

Check it out on Github here.

What Exactly Is It?

A UITableViewController subclass that allows you easily and simply display what I call "static content". An example of such content is what is found in iOS's built-in Settings application. Or a simple "About" screen. Or a "Login" screen. Or any number of simple screens that might display or collect information.

All this is done using some really cool methods that use blocks. It also allows you to easily create UITableViewControllers that collection information.

It is very much a library in the making. It is quite functional and usable already, as you will see if you read on, however, there is a TON more that could be done with this library, I'd love to hear where everyone thinks it should go and how it could best be adapted to fit everyone's needs.

That being said, JMStaticContentTableViewController might not be for everyone, but if you've ever built a whole UITableViewController implementing full UITableViewDataSource and UITableViewDelegate methods, and so on, and so on, then you likely know how much time this library could save you.

Keep reading for some awesome stuff.

Example Usage

Adding a section and a cell

Here's a simple example of adding a section and a cell to your UITableView. You would likely write this code inside your viewDidLoad method inside your JMStaticContentTableViewController subclass.

Note that you are passed in some very important objects, JMStaticContentTableViewSection, JMStaticContentTableViewCell and a UITableViewCell. You can configure the UITableViewCell exactly as you would normally. We also use the JMStaticContentTableViewCell object to setup things like UITableViewCellStyle and the reuse identifier.

JMStaticContentTableViewSection also allows you to setup things like the section titles.

As you can see we also get a nice looking whenSelected: block, this allows to write code that will be run whenever our cell is tapped, a perfect place to, for example, push on a UIViewController.

- (void) viewDidLoad {
    [super viewDidLoad];

    [self addSection:^(JMStaticContentTableViewSection *section, NSUInteger sectionIndex) {
        [section addCell:^(JMStaticContentTableViewCell *staticContentCell, UITableViewCell *cell, NSIndexPath *indexPath) {
            staticContentCell.cellStyle = UITableViewCellStyleValue1;
            staticContentCell.reuseIdentifier = @"DetailTextCell";

            cell.textLabel.text = NSLocalizedString(@"Wi-Fi", @"Wi-Fi");
            cell.detailTextLabel.text = NSLocalizedString(@"T.A.R.D.I.S.", @"T.A.R.D.I.S.");
        } whenSelected:^(NSIndexPath *indexPath) {
            [self.navigationController pushViewController:[[WifiViewController alloc] init] animated:YES];
        }];
    }];
}

Inserting A Cell At Runtime

This will behave just like addCell: above, except it will animate nicely into place.

- (void) _someTaskFinished {
    [self insertCell:^(JMStaticContentTableViewCell *staticContentCell, UITableViewCell *cell, NSIndexPath *indexPath) {
        staticContentCell.reuseIdentifier = @"WifiNetworkCell";
        staticContentCell.tableViewCellSubclass = [WifiNetworkTableViewCell class];

        cell.textLabel.text = network.networkName;
        cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;

        cell.indentationLevel = 2;
        cell.indentationWidth = 10.0;
    } whenSelected:^(NSIndexPath *indexPath) {
        // TODO
    } atIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:YES];
}

Inserting Multiple Cells At Runtime

Same as above, except here we're wrapping our work in calls to beginUpdates and endUpdates, again retaining all of our UITableView's built in "magic" while still getting to use our nice, convenient syntax.

// Somewhere else you'd probably load some data somehow,
// then want to insert rows for the new items in that data.

// Normal table view functionality is completely retained, for example,
// here we're inserting a bunch of cells inside a beginUpdates/endUpdates block
// so all our new cells will animate in simultaneously and look awesome.

[self.tableView beginUpdates];

for(SomeModelObject *o in self.awesomeModelObjects) {
    [self insertCell:^(JMStaticContentTableViewCell *staticContentCell, UITableViewCell *cell, NSIndexPath *indexPath) {
        staticContentCell.reuseIdentifier = @"SomeCell";

        cell.textLabel.text
    } atIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:YES];
}

[self.tableView endUpdates];

Animation

Anytime you ask JMStaticContentTableViewController to animate the inserting or deleting of cells or sections, it will use the UITableViewRowAnimation style of UITableViewRowAnimationAutomatic under the hood, so all of your animations will look great. This style was added in iOS 5.

Example App

So for fun (and to aid me in developing the library, determine its needs) I started using JMStaticTableViewController to attempt to re-create the built-in iOS Settings application. This exists in a sort of "half-finished" state inside the library's Github repo

Some things to try in it are:

  • Wi-Fi, go into the Wi-Fi section and notice how the rows appear after "searching for networks" (this is obviously simulated). Also try disabling and re-enabling Wi-Fi. Notice how the rows appear and disappear with correct animations.

  • The Notifications section also demonstrates showing some content.

  • Cells that shouldn't be "selectable" (like cells containing UISwitch controls) aren't selectable.

  • Normal UITableViewDelegate methods still work, so implementing things like like adding a UIActivityIndicatorView next to a section title are no more or less complicated than before.

It is, like I mentioned, unfinished, meant merely as a tool for you to checkout and get some perspective on how the library might be used in the "real world". More completion of the example as well as any other examples are very welcome, please feel free to submit pull requests.

Example App Screenshots

           

iOS Version Compatability

JMStaticContentTableViewController supports iOS 5 and up.

Adding To Your Project

CocoaPods (The New Easy Way)

If you are using CocoaPods then just add this line to your Podfile:

dependency 'JMStaticContentTableViewController'

Now run pod install to install the dependency.

Manually (The Old Hard Way)

Download the source files or add it as a git submodule. Here's how to add it as a submodule:

$ cd YourProject
$ git submodule add https://github.com/jakemarsh/JMStaticContentTableViewController.git Vendor/JMStaticContentTableViewController

Add all of the files inside the folder named "JMStaticContentTableViewController" to your project.

ARC

JMStaticContentTableViewController uses Automatic Reference Counting (ARC). You should be using ARC too, it's the future. If your project doesn't use ARC, you will need to set the -fobjc-arc compiler flag on all of the JMStaticContentTableViewController source files. To do this in Xcode, go to your active target and select the "Build Phases" tab. In the "Compiler Flags" column, set -fobjc-arc for each of the JMStaticContentTableViewController source files.

"This Library is Bad, and You Should Feel Bad"

This is my first try at building a system like this for this purpose, there are already a ton of things I plan on "fixing", improving, and re-doing. I wouldn't really be a good developer if I didn't hate all my code once I was done would ? ;)

I'm totally open to suggestions/fixes/hate mail/etc just let me know in a pull request, issue or even on twitter, I'm @jakemarsh.

That being said, this is a very opinionated library. It makes assumptions and defines conventions that might not fit perfectly with everyone's codebase or app. If you are one of those people, please feel free to submit a pull request so we can talk about it and maybe get some of your desired changes worked in.

Check it out on Github here.

App Review: Podcasts for iOS

Posted

Banner Image

Yesterday, Apple released a new flagship iOS application: "Podcasts". Yep, only a few days after I predicted such a thing, it happens.

As I said before, I had no inside information about the app. Although, I did hear a few rumblings at WWDC that the new Podcasts application was initially intended to be demonstrated during the WWDC Keynote, but was cut at the last minute.

So, was I right? Did Apple announce a full-fledged "App Store-style" backend interface for publishers to manage their podcasts? Push notifications for when new episodes are released? Let's dive in and find out.

Where I Was Wrong (For The Moment)

No new backend system was announced or released. However, a clue or two hinting at future improvements to this new system can be found in the app. I found two references to the concept of "paid" podcast episodes when playing around with the application. One mentioned "free" episodes, thus suggesting that some episodes might cost money. Another offers the option to "Redeem Code", again suggesting that some episodes may not be free.

Redeem Button

I'm not done holding my breath on Apple offering an "App Store-style" backend system to allow publishers to sell episodes or even subscriptions to their shows.

Apple also hasn't brought any sort of push notification functionality to market with this intial release of Podcasts. I don't have any hard evidence here, but given the obviousness of providing push notifications for when new episodes are available, as well as automatic background downloads, I'd say it's only a matter of time before these features are implemented.

The new iOS Application

First, the facts: Podcasts is a pretty feature-rich universal iOS application that runs on both the iPhone and iPad. It requires the device to be running at least iOS 5.1. It allows users to discover and subscribe to podcasts, as well as download or stream individual episodes.

It's always a fun time when Apple releases a new flagship iOS application. Their latest releases of iMovie for iOS and iPhoto for iOS have boasted some pretty great user interfaces and seem to be quite well received by users. Let's see if Podcasts follows suit.

Top Stations

Top Stations Screenshot

Apple chose a pretty interesting direction for it's "Top Stations" feature in Podcasts. I'm guessing their intention was to give those users who aren't as familiar with podcasts a way to quickly listen to something that might interest them. A sort of "channel surfing" concept for the couch-potato-would-be-podcast fans. It definitely delivers on the "channel surfing" concept, but educated users likely won't be too intrigued by this feature. From what I can tell, by default "Top Stations" seems to choose an episode at random from the currently selected show and begin playing it automatically. Possibly a neat way to discover new content, but I don't see many users heading back for a second or third use.

Subscribing

Catalog Featured Screenshot

With Podcasts, Apple has essentially done for Podcasts what they did for books with iBooks: A separate iOS app, that you have to install from the App Store, that when launched, can "flip around" to reveal the place where you discover and download media. Even the animation for the flip back and foward matches iBooks pretty closely.

Catalog Top Charts Screenshot

The Podcasts "catalog" interface, sadly, is still a giant web view. Not surprising given that all of Apple's "store" interfaces on iOS are designed this way, but boy does it show. The interface is uncharacteristically slow and unresponsive. I found tapping on a "subscribe" button to hang on almost every podcast I was attempting to subscribe to.

Playback

Oh boy. Welcome back to skeuomorphic-town. Well, if you're listenting to an audio podcasts at least. Watching video podcasts shows the video of the desired episode full-screen with the expected video controls. But load up an audio epsiode and you're in for a treat.

Playback Tape Deck Screenshot

It's literally a tape deck. Immediately recognizable and impressive. I really love how well this interface comes across on the iPad, a device that not's too far off in size from actual tape recorders of the 1970's and 80's. I tested out the app on my iPhone 4S and iPad 3, and just as an aside, the app truly shines on the iPad 3. This type of graphical treatment on the iPad 3's retina screen really helps solidify Apple's stronghold on the "holy cow that looks awesome!" market. During playback, the podcast's cover art is displayed on top of a translucent "plastic" cover sitting on top of two spinning tape deck heads with "tape" running between the two decks. As you progress in the episode you're listening to, the tape visually transfers from the left to right side, just as it would on a real-life tape deck, quite an impressive effect. The control buttons located at the bottom of the screen appear to "press in" when tapped. They resemble the buttons of that old-school (now seemingly ancient) tape recorder you found in your parent's attic that time.

One nice touch is the speed control. As you change the rocking slider control from "turtle" to "hare", the tape decks begin to visibly ramp their speed up and down. Many podcast apps on iOS offer ability to speed up or slow down playback of episodes, but this sort of immediate and obvious user feedback feels like something only Apple could deliver.

Should you switch?

Tough to answer. Podcast clients are like RSS Readers, Twitter clients or E-mail applications: no one application can please everyone. With "Podcasts", Apple has served up a fairly strong competitor in to the "iOS podcatcher application" market, assisted greatly by what I'm calling the "default choice" factor. They own the platform, "Podcasts" comes close to appearing as the "default" application for interaction with Podcasts on iOS.

I personally still love Instacast for iOS. It too, is a universal iPhone and iPad app. Like Apple's "Podcasts", it uses iCloud to sync subscriptions, playback positions and played/unplayed states of episodes. As an added bonus, Instacast already does support push notifications for new episodes of shows you're subscribed to.

So while I would highly suggest anyone who has read this much of this article to check out "Podcasts", I think Apple has a few releases to go before this app starts to become the obvious choice.

"Podcasts" is available now for iPhone 3GS, iPhone 4, iPhone 4S, iPod touch (3rd generation), iPod touch (4th generation) and iPad devices running iOS 5.1 or later.

Here's the App Store link.