Hacker News new | comments | show | ask | jobs | submit login
How to Write Good iOS Apps (coffeetimerapp.com)
171 points by AshFurrow on Sept 2, 2011 | hide | past | web | favorite | 62 comments



The article was good in breadth but lacked depth.

For deep-dives into the nitty gritty of Cocoa Touch, we've learned minute important details from digesting countless hours of WWDC videos that make all the difference.

http://developer.apple.com/videos/wwdc/2011/

Especially the perennial classic, "Designing Apps with Scrollviews"


In case anyone else is looking for “Designing Apps with Scroll Views”, it's actually from WWDC 2010: http://developer.apple.com/videos/wwdc/2010/


"Seriously, it'll be worth it not to learn about manual memory management."

This is not true at all and it is a very dangerous suggestion. Automatic Reference Counting indeed makes memory management an awful lot simpler (often you don't have to do any explicit memory management at all with it) but you still need to learn about it and understand it, otherwise all sorts of bad things will happen like memory leaks due to circular references (delegates come to mind) and crashes due to the autorelease pool high-water mark eating up all the memory on iOS devices.


Even if you're going to use a technology to avoid dealing with manual memory management, it's critical to learn it anyway. It's such a fundamental and important part of Cocoa development, not only because of how important it is to making efficient apps, and to not crashing, but also because you need to understand concepts and conventions of ownership in Cocoa. You need to know what you're doing when you're casting CoreFoundation and Foundation types. You need to know what a pointer is, know what a dangling pointer is, know how you can pass a pointer to a pointer to get a second return value from a method (`NSError`[1] is a pretty common Cocoa convention). Know what a singleton is.

And after you've learned all of this, you can also do some really neat things with Cocoa's dynamic runtime. Things like invocation building using a category and code like this (or similarly, store and queue up actions on the Mac's Undo manager):

    [[NSInvocation invocationBuilderWithTarget:self] aRandomMethod:arg];
Once you understand memory management, you can start using blocks, and even storing blocks. You need to understand how copying a block retains every object in the stack, and why raw type variables become immutable in a block. Then you can start to really have fun with awesome powerful technologies like Grand Central Dispatch.

Also, in Objective-C you should never user the Garbage Collection feature. And Automatic Reference Counting, while awesome, is not production-ready yet. Apple will not approve apps with it yet—I know, I've been rejected for trying to use it in an app.

[1]: HN's markdown parsing is a little funky, this is meant to say:

    NSError**


"Also, in Objective-C you should never user the Garbage Collection feature."

Why not? On the Mac, the garbage collection process is offloaded to another CPU. Any performance hit is more than made up for the fact that developers probably messed up the retain counts.

Memory management is a thing that you have to get perfect or your app will crash. I personally trust ARC or GC more than I trust myself.


iOS's Objective-C doesn't support garbage collection. iOS 5 will add support for Automatic Reference Counting, but no real garbage collection. So if you are writing cross-platform Objective-C code that must support iOS devices and Macs, then you can't rely on garbage collection. And if you must support iOS < 5, then you can't rely on Automatic Reference Counting either.


Not quite right. There is some support for ARC for iOS 4 (that is bundled with the compiled app). Some more at http://stackoverflow.com/questions/6308425/ios-5-best-practi... .


It's foreseeable that GC will go the way of the dodo in one of the next OS X releases. (They didn't mention GC once at the WWDC talks. Not even in the memory management related talks.)

> I personally trust ARC or GC more than I trust myself.

I don't. Reference counted memory management is so easy that I never had the problem of leaking/crashing apps because of forgotten retain/releases. The most common memory management related bug for me are hidden retain cycles. (Which ARC doesn't really address.)

But ARC is pretty nice for the stupid UI boilerplate code which saves you from writing huge -dealloc methods. For critical code (Obj-C and C intermixing) I tend to disable ARC.


> Apple will not approve apps with it yet—I know, I've been rejected for trying to use it in an app.

Just change the Info.plist of your app (so that it looks like it was built with the non beta of XCode), re-codesign the bundle and upload it. (Have tested it with OS X apps. No guarantee for iOS.)


I think that if you master UIView and MVC as Apple prescribes it, you learn the conventions you need for proper memory management in ARC. Knowing the conventions is going to suffice.

My argument wasn't to go and be naive about memory management. It was to not worry about it right now. Memory management makes the already steep learning curve of Objective-C even steeper, and can scare away newcomers.


I spent the first month struggling with memory management, and kept being paranoid about "autorelease". Now, I ONLY use autorelease (well in 99% of cases). I don't get why so many people say be careful about autorelease. It makes things so much simpler and prevents mistakes from not releasing after allocating. I wish I learned this much earlier.


when you autorelease, the reference goes into an autorelease pool that is drained later. So you will likely end up using much more memory than you need to. Since iOS runs on memory constrained devices, this could mean the difference between running smoothly and crashing due to memory warnings all the time.


Well, be careful with that. A lot of properties in Cocoa and Cocoa Touch are not retained automatically (delegates, data sources and so on). If you just autorelease them you will have problems.

The other reason people are careful about autoreleases is because, obviously, objects in the autorelease pool won't get deallocated until the pool is drained, which normally happens in the main application loop. Normally, this is not a problem, but if you do memory-intensive things (like dealing with images or other media) in a loop that means that you will consume a lot of memory before the autorelease pool gets drained. This might get other apps killed (on iOS 4+), and ultimately, yours too.


The other problem with autorelease is when you release too many times; the autorelease pool gets drained down the road, and your app crashes in some other situation (inconsistently) at a time unrelated to when you made the mistake.


Autorelease isn't a silver bullet for Obj-C memory management. There are a number of cases in which you would NOT want to autorelease objects - tight loops, for example.

If you're already in the habit of autoreleasing everything you +alloc, why not just release it when you're done with it instead?


because like I said it's easy to forget when to do that. Example

UIView* view = [[UIView alloc] init]; ...do a bunch of stuff [view release] <-- you have to remember this

vs. UIView* view = [[[UIView alloc] init] autorelease];

Of course I know about the cases where we have tight loops,w hich is why i said 99 of the time.


Personally I only use autorelease when I create an object I'm not responsible for. For example, if I create a view somewhere for another object to utilize. I also like knowing that as soon as I'm done with an object that it gets killed and the system can reclaim the memory.


I think saying "very dangerous" is a bit over the top.

The worst that will happen is that you might get a circular reference and leak memory. This may (or may not) cause your app to eventually crash.


Disappointingly obvious? In summary: learn, somehow, how the major APIs work, and then use them.


The new big nerd ranch iOS guide 2 is phenomenal. I should have read it before writing my first 4 apps through trial and error.


I've heard really good stuff about their in-person training too. I'm actually a big fan of the intensive in-person training. It's expensive, but I've found it to actually be worth it (for professional work at least).


I was looking for a modern training program (I started iOS App dev back before apple had a 3rd party lib) for a new guy, and this was my choice for best one. I also like the Xcode 4 book that recently came out.


> I should have read it before writing my first 4 apps through trial and error.

I wouldn't say that. I consider learning by trial and error far more valuable than reading the best books on a topic.

If you read the guide now you get more out of it. You have done the groundwork yourself - now it's time to hone your skills :)


I lost it at "If you don't want to make your apps intuitive and easy to use, I hear OpenOffice is looking for some Java developers."

Hilarious, great article.


I also enjoyed "...which is in turn rendered by OpenGL, which we don't care about because we don't hate ourselves."


Though it would be nice to have some understanding of OpenGL. It's gold worth if your UI runs sluggish and you try to fix that. Understanding how OpenGL handles things helps a lot.


> No, wait. Yes I am. I taught a course at my university on the topic.

Teaching a course seems to be an excellent way to learn the basics. It does not make you an expert, though - that needs a couple years of practice.


Considering the attitude towards testing in this article.. How much would someone generally pay for say a testing consultant to test their app for them?


depending on the size of the app, anywhere from $10 to $50 for a complete regression test and useful feedback on the app. I've never paid anyone though as it's easy to get friends to beta test


Where can you get testing like this? Is there a site or service available?


Some good automation frameworks are FoneMonkey and KIF


Whatever. Life is way too short for some of us. Sign up for the Corona SDK and just have fun.

Creating good apps has nothing to do with the tools you use, it is how you use them ... And more importantly than that, knowing how to design, polish, shine, and pay attention to detail is what makes a good app. Maybe adhering to some standard UI styles and layouts as well.

EDIT: Wow, I'm bummed that this is getting down-voted. Maybe reply with WHY you are down-voting because developing GOOD apps in Corona is much easier than the route described by the author of this post.


Corona is five different flavors of awesome. If you want to write 2d iphone apps with 2d physics.

If you don't want to, you will have to look elsewhere though.


That's not true.

Now you can develop for Android AND iOS with Corona, plus, you can use their Native UI API to create actual apps with Corona, not just games:

http://developer.anscamobile.com/content/native-ui

Check out their showcase:

http://developer.anscamobile.com/showcase/

I'm not affiliated with Corona other than that I'm a subscriber and developer who uses Corona and loves the heck out of it.


Not to be too negative, but out of the 15 apps in the showcase, the only three that are not games and have a native looking UI are:

Canyon County National Parks - looks good, but scrolling is noticeably non-native in several ways, and the app is oddly slow sometimes

Drum Toy - takes forever to load, ugly sliders

iSleepWell - UI is confusing and difficult to use (tap areas too small)


The one thing I would recommend people do is not use Interface Designer. It bloats your code base and adds more complexity to the view hierarchy. It might be good to quickly mock-up a prototype, but not much else.


I am a full time iOS dev: I cannot imagine professionals who completely avoid interface builder.

For some screens, it is certainly faster and easier to programmatically build them up, but for the vast majority of screens, your comment seems to tell more about a willingness to learn than a desire to make good apps.

Perhaps you stopped trying to use it during the Xcode3 days? Now, almost any hairs it did have got shaved off in the Xcode3->4 transition.

I'm not saying use it for all adjustments to views, sometimes those go faster in code, but it is by far the better way to do almost every view.


I admit I did stop using it during XCode3. I got so use to it I haven't yet used it in XCode4. I meant it more as a better way to understand the iOS view hierarchy, not necessarily the faster way to build apps. But building faster apps doesn't make them better.


If you do the exact same amount of functionality in a shorter period of time, it frees up that time to then go make another part better. More features. More testing. Faster Release. More documentation. Accessibility features.

If you prefer to boil each grain of rice separately for a pilaf, and it tastes the same at the end, you just wasted a lot of time in the kitchen for no good reason other than you've not stopped and learned how to boil them all at once.

Try the new Xcode4 book: http://www.amazon.com/Xcode-Developer-Reference-Richard-Went...

It goes into IB's newest incarnation. IB is also fantastic when adding assecessability functions to your app. Another reason to add accessability functions to your app (beyond being a good human being who lets not-fully sighted people use your app) is that it allows kif to work: http://corner.squareup.com/2011/07/ios-integration-testing.h... (play the video).

I'm not a IB Zealot, I make views manually when it makes more sense to or IB is just not doing it's job with any speed, but "0" is not the amount anyone should be using it who makes non-game apps.


Your analogy doesn't really apply since you still have set the properties in Interface Builder. It's more like i'm just using a different stove. It does some, but not all. And most of the steps it does do are default for the class anyway. I like the finer grained control. If you're used to it the time difference is negligible.


>It's more like i'm just using a different stove.

Sure: http://www.goodtimestove.com/

Modern constraints(http://developer.apple.com/library/mac/#recipes/xcode_help-i...), for instance, are insane to edit manually with no visualization on any complicated screen.

Perhaps you're just building tons and tons of tableview cells or something else automatically laid out for you, so you're not really feeling it (or are too strident a believer of your position to learn then judge, rather than judge first). But if you do any manual layout at all, there are huge wins within days of starting to learn the tool.

It feels like I'm discussing with someone contending that zip files are as good as source control here.


Were talking about iOS and the Interface Builder, not MacOS. I do not develop apps for the Mac, but I agree using Interface Builder would make sense for "larger" screens with more ui elements. To be clear I used Interface Builder for over a year until I decided it was better for ME to programmatically add ui elements.


http://developer.apple.com/library/ios/#recipes/xcode_help-i...

Is the iOS link to the same article. I just hit the wrong one in google.

>The one thing I would recommend people do is not use Interface Designer. It bloats your code base and adds more complexity to the view hierarchy. It might be good to quickly mock-up a prototype, but not much else.

Is the issue. If you yourself wish to do things a different way, that's fine, but it should be clear to people that this is a you thing, not a thing that's really accepted by anyone much who does this. Have fun not using it, it's fine, I'm not working with you in particular.


Would you care to qualify that. In my experience it has been the exact opposite -- setting up your UI in Interface Builder has always reduced the amount of code necessary and has allowed quite complex view hierarchies to appear pretty much flat in code. And I'm taking about iOS UIs, for which a bunch of the code saving goodies of AppKit Interface Builder are not available -- things like Cocoa bindings and the new auto layout machinery in Lion.


I find that added generated NIB files just dirty the code base. Of course this is just my preference. However, when I was a beginner, beginning to create more advanced views, I found it easier to programmably add them then to use Interface Builder. I like to be in control of my views and it helps me better visualize the view hierarchy. One example, was trying to create a UITabController with UINavigationController's for each tab. It can be done with Interface Builder, but it takes a lot of steps.


I still don't understand how a bunch of stored-to-file object graphs "dirty the code base" but I guess you are right -- it is a preference thing. Believe me, I have weirder quirks than that when it comes to coding.

Your example, however, is probably amongst the worst to support the argument you are making. Here are the steps to create a tab bar view with four tabs, each containing a navigation view, and those containing alternating table views and plain views:

- drag out a UITabBarController

- remove the two default UIViewControllers instantiated with it

- drag out to the tab bar four UINavigationControllers

- select each tab and drag out to the center area of the view a UITableViewController or UIViewController

- customize to your heart's content

- there is no step six…

In my guestimate this will take at least 20 lines of boilerplate code, even with the minimal amount of customization. And you’d be missing out on all the rest of the benefits of NIBs, like the ability to see (and to some degree test) your UI without having to build and run your application or the ability to send it off for localization to a collaborator.


I think during XCode3 I just really started to hate NIB's haha. They seemed slow to initiate and load. I admit that i haven't yet used Interface Builder in XCode4 and it apparently has fixed a lot of those "weird" bugs.


No, no it doesn't take a lot of steps. Perhaps I'll do a screencast to prove it.


I find the exact opposite.

For example, instead of drawing a table programmatically, I can drag it into my view from Interface Builder's default list of objects. I can edit the table's properties quickly and easily.

And that's just one tiny example. Suppose you have a complex interface with loads of different buttons, sliders etc, custom backgrounds - you would have to set everything in code (e.g. button background images, button type, x and y co-ordinates on the view). In my admittedly limited experience that adds massively to the amount of code you have to write. It's crazy not to use IB in my opinion, but each to their own.


You're crazy town.

How does it add more complexity to your view hierarchy exactly?

Most people are getting away from doing their UI's in code and moving back to their proper place in IB.

This is done almost entirely in IB:

http://www.youtube.com/watch?v=Tk8HCkqZsNU

As is this:

http://shavevideo.com/

I'd still be typing if I did it in code.

Weird.


Some random advice about the first video -

It's unfortunate that the Default.png is a photo when the UI doesn't seem to vary enough to exclude the standard preview shot.

In the adjustments view, "Finish" should be "Done". And tapping it should not trigger a flip animation-- it's too distracting.

Also, the music is extremely loud.


Thanks for the feedback.

Not sure what you mean by the standard preview shot?


> It bloats your code base and adds more complexity to the view hierarchy.

How so?

All Interface Builder really does is serializes the objects, much like you would any other object supporting NSCoding. The net result is that an instantiated view from IB should be identical to one you created manually.

IB certainly isn't the right tool for all situations, but its design is pretty clever with tight integration with the rest of the system. I can't see any reason not to use it, when it is appropriate.


> It bloats your code base and adds more complexity to the view hierarchy.

Care to be more specific?


What's Interface Designer? Or do you mean Interface Builder?


Yep, sorry. Interface Builder. Shows how much I use it haha.


Lots of downvotes, but I completely agree with you.


Go mess with MonoTouch or whatever if you want. Then go grab a fruit roll-up, think about what you did, and realize you should have just learned Objective-C.

OK, but why?

Seriously, it'll be worth it not to learn about manual memory management.

I'm confused - MonoTouch presumably has garbage collection, but Objective-C lets you 'not learn about manual memory management'. What's the deal?


Seriously, it'll be worth it not to learn about manual memory management.

I believe he's making reference to the inclusion of automatic reference counting in iOS 5.


Exactly. That's why you have to pay the $100 for the dev license - to get Xcode 4.2 beta.


Ahah. So the mention of MonoTouch is a red-herring? Weird.

EDIT: @tptacek What confused me is there's no reason given to avoid MonoTouch, so I latched onto the memory management comment, to try and make sense of the text.


No, you're conflating two different points he's making. The MonoTouch jab isn't about memory management.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: