
iOS Development Tips If You're Just starting Out - discovr
http://stuartkhall.com/posts/ios-development-tips-i-would-want-if-i-was-starting-out-today
======
danilocampos
As long as the beginners are drifting by, lemme say this:

Every nib you use is a boatload of code you don't have to maintain. Use nibs.
Can they solve every problem? Goodness no. But they're a great way to get the
basics of your views laid out. They give you an easy way to preview the
behavior of your view when layout changes.

And they're very forgiving when you change your mind. Changing text alignment?
One click. Want to change the balance or padding of some elements? Nudge them
around with a real time preview until you're happy. Mess with different color
combinations in your UI to your heart's contentment.

Doing all your view layout in code gets damn tedious when you have to compile
and run each time to check your results.

Every now and then some crackpot will come along and tell you never to use
nibs. Ignore them. Use nibs when they make sense for your workflow. End
sermon.

~~~
sandofsky
In all the teams I've worked on, designers have worked out pixel positions and
text alignment by the time I see the mocks. I don't find much value in
realtime feedback.

Nibs are handy if you're sticking to stock UI and stock behavior. Programmatic
layout takes longer to setup the boilerplate, but once it's in place, I find
it about as easy to work in code as nibs. With complex designs, I find it
significantly easier to work programmatically.

~~~
danilocampos
> In all the teams I've worked on, designers have worked out pixel positions
> and text alignment by the time I see the mocks. I don't find much value in
> realtime feedback.

Very few beginner iOS developers will have a design team at their beck and
call.

~~~
kalms
But some of us are both ;)

~~~
jimbokun
And what do you think of NIBs, from the perspective of each of those two hats
you are wearing?

~~~
kalms
Being fairly new to this, and doing a large amount of experimenting, I enjoy
being able to quickly mockup a (sort of) working prototype, without having to
type too much code. During the learning process, you just want an interface,
and not much else.

I guess it comes down to workflow, and that's always a personal thing.

------
MehdiEG
A surprisingly good list. Beyond the xib issue, which other have talked about,
I would add a couple of points:

\- If developing a trivial utility app you're expecting to release quickly,
target iOS version N-1. Any user who is more that one major iOS version behind
won't be the type of user who will download your app (or any app really).

If developing anything more ambitious, target the latest iOS version only and
take full advantage its new APIs. By the time you're ready to go mainstream (a
few iterations of the app under your belt, nailed your marketing strategy,
etc), there will have been at least one new major iOS version released and any
time and effort you spent writing code for older iOS versions will have been
wasted.

(talking from experience here :)

\- Before writing a single line of code, sort out your logging. At the very
least, use a handful of macros like [0] to print the class, message name and
line number when logging and to exclude debug log statements from release
builds. Or check out something like CocoaLumberjack (haven't tried myself yet
but writing this made me realize I need to sort out my own logging system so
will give it a shot).

[0] [http://stackoverflow.com/questions/969130/how-to-print-
out-t...](http://stackoverflow.com/questions/969130/how-to-print-out-the-
method-name-and-line-number-and-conditionally-disable-nslog)

~~~
MehdiEG
One last tip that bit us hard: beware of universal apps (apps designed for
both iPhone and iPad).

Once you've published your app as universal, there is no way back. You can't
decide in a subsequent update to revert to an iPhone-only or iPad-only app -
Apple won't let you.

So if you start with an iPhone app, and then put together an iPad version of
the UI just to try out and publish it as a universal app, you'll be stuck with
having to provide an iPad version of your app for the rest of times. Even if
you realize that the iPad version isn't worth it for your app and that nobody
uses it, you won't be able to discontinue it.

So think very carefully before flicking that switch.

~~~
josephlord
Interesting point.

You also won't be able to charge different prices for the iPad and iPhone
versions either. Although you probably could make separate in-app purchases
that get offered based on device type.

------
kevingibbon
Utilizing storyboards and xibs is one of the best way to decrease development
time. Stop the coding madness!!!!

The only people I still know that avoid heavy utilization of these do not
understand how to properly use them. Go learn!

~~~
jsankey
I started out using XIBs, but also found myself moving a lot of my controllers
away from them as soon as things got non-trivial. The biggest problem I found
was weak layout support, so if you had a lot of dynamic content in a screen,
it was easier to make a flexible layout in code.

I also agree that the lack of "diffability" for XIBs, despite them being XML,
is a pain.

Maybe I was missing something, but my experience matches the OP.

~~~
robterrell
Perhaps you're missing something. XIBs are arguably among the most powerful
features of Cocoa. I built an app with a really complex, dynamic layout using
them (look up "Panna" in the App Store). Working with an evolving design and
changing team, with layout elements often changing and getting tweaked in tiny
ways... Well, if I did the entire layout in code, I would have needed a full-
time developer just for the ongoing GUI changes. I agree that dynamic layout
support was weak pre-constraints, but it was still a much better development
experience, and now you can do really complicated things without any code at
all.

If you're just talking about some buttons in a toolbar, go nuts, but otherwise
it's worth the time investment to learn.

~~~
andrewroycarter
100% agree. IB makes for faster development time, easier maintenance, and it's
way better for auto layout if you're targeting iOS 6.0

~~~
ravenger00
I think there's a case to be made though, that using IB when starting out
doesn't make you fully understand how UIViews work. So starting out I'd
probably recommend you make your own views programmatically to know what
you're hooking into.

That said once you get that base level of understanding, nibs and storyboards
are huge time savers, and are the way to go.

~~~
MaxGabriel
While using storyboards definitely meant that I didn't understand things like
how my root view controller got set up, I don't think it abstracts too much.
Most importantly, using Interface Builder allowed me to explore the properties
of views and get immediate feedback on how they're made. I still go back to a
Storyboard when I need to figure out what combination of UIControl content
settings I need.

------
jsankey
Pretty good tips. Re: being aware of retain cycles -- this is not just for
blocks but really in general. When you start out you should immediately learn
the conventions and adhere to them strictly. (Unfortunately the APIs don't
always, I'm looking at you NSURLConnection!)

Another tip: try both Xcode and AppCode: <http://www.jetbrains.com/objc/>.
It's a subjective thing but for myself AppCode is far better (it helps that I
also use IDEA for Java, including Android).

~~~
mikec3k
As annoying as Xcode can be sometimes, I can't stand AppCode. It doesn't feel
like a native app, and it seems very fiddly and even less user friendly than
Xcode.

------
xedarius
I've been programming iOS for a couple of years now and some of those tips
where useful to me!

Anyhow as we're contributing top tips, my one is 'Always run your app on
target hardware.'

Don't rely on the emulators, especially if your're doing OpenGL work. You will
only know your framerate by running your app/game on the real hardware.

~~~
bennyg
This is huge.

Running on the emulator is good if you haven't paid the $100 to put it on
device yet. After that, you better be running on your device every time.
There's so much to be said for actually holding the device and using your app
like your normally would, instead of pointing and clicking with a mouse. Even
the pixels and text-size/color are WAY different when on the device.
Seriously, do this if you aren't already.

~~~
eliperkins
Well this is a bit of a sweeping statement.

I don't think you ALWAYS have to run on your device. Emulators are much faster
at launching and getting to it. I use the emulator for a majority of quick
fixes, layout changes, API debugging, etc. I move over to the device when
things are nearing a point where I need to test real-world things.

Using the emulator is fine, just be sure to test on the device before you
deploy.

------
rogerbinns
The thing I have missed the most with Objective C is the lack of a code
tidy/formatting tool. All Xcode can do is alter the indent on each line which
isn't useful. Regular indent etc do not support the language. There is an
uncrustify tool in various SO answers but it is a good example of how not to
do things (eg by default it does nothing - there are no presets, it is very
flaky).

I wish Google provided tidy tools with their style guides, or Apple did
something with Xcode.

~~~
alxndr
Have you tried JetBrains's AppCode? <http://www.jetbrains.com/objc/>

(I haven't but their RoR-tailored IDE RubyMine is the only IDE I've enjoyed
using after it for less than a week.)

~~~
rogerbinns
I haven't but I did look at the page as it was linked in the article. I never
saw any mention of code formatting. An example of what I expect is like the
Eclipse Source > Format option which will go in and make everything consistent
including making lines less than 80 chars, adding space around operators (I
never put in spaces which goes against almost every style guide), ensuring the
arms of if/else always have braces etc.

I actually do most of my iOS development by running emacs on my Linux box and
using sshfs to access the files on the Mac. I use command line tools for
compilation/running/debug. I did originally start out using Xcode but it gets
in the way of the coding. (My work involves a library that functions in the
background and has no user interface.)

AppCode hasn't seemed worth the effort to investigate and $200 is rather a lot
to spend on a code reformatter. (Also only running on MacOS makes it
significantly less useful to me.)

~~~
jasonlotito
AppCode is $100.

$200 is you purchase a company license, which means anyone at the company can
use it. If you are the only person using it, you only have to pay $100.

~~~
rogerbinns
AppCode is $100 if you make the purchase using your own money and are not
reimbursed in any way by the company. I try to keep work and personal stuff
very separate and have no personal need for AppCode. $100/200 is still pretty
steep for a code reformatting tool!

"If you, as an individual, are purchasing a product license using your own
funds, then the personal license is right for you.

Personal licenses are not available to companies in any way or form. Transfer
of personal licenses to any third party and/or reimbursement for personal
license purchase by a company are prohibited by the Personal License
Agreement."

~~~
jasonlotito
Yes, I'm aware of this. I was simply clarifying the pricing is not $200, but
$100 for a single-person license. There has been confusion in the past
regarding this, people assuming that if you use one of their products for
business, you must purchase a company license. Even if you only use AppCode
for work stuff, you do not need to purchase a company license.

------
vignesh_vs_in
For starters, do go through the iOS development by paul hegarty videos from
here, [https://itunes.apple.com/gb/itunes-u/ipad-iphone-
application...](https://itunes.apple.com/gb/itunes-u/ipad-iphone-application-
development/id473757255)

The 15 hours of video is the best investment of your time if you want to jump
start into iOS development.

------
tylerc230
CocoaPods (<http://cocoapods.org/>) is a really easy way to integrate 3rd
party libraries into your iOS and OSX projects. It follows a similar pattern
to bundler for ruby; you just specify a library by name and a version number
in your Podfile and CocoaPods handles the rest. Another suggestion is to use
categories on Cocoa classes for operations you do often. It cuts down on code
duplication and makes your code more readable. One I use in every single
project is a category on UIView allowing me to do such things as 'myView.x =
5.f' instead of pulling out the views frame, updating the frame and then
setting the frame again. I also agree with the other commenters that IB should
be utilized when possible. It makes iterating on UIs much faster, easier and
less error prone. +1 for using blocks though, how did we ever get by before?

------
PhilipA
I wished that when I started out with iOS development, that I knew that to get
success on the App Store, 80% is marketing, and 20% is the quality of the app.

~~~
gurkendoktor
iOS development != App Store success. This would actually be my advice for
anyone starting out:

1\. Make an app that looks awesome as a reference (and don't expect anyone to
ever, ever use it)

2\. Get a job as an iOS contractor

3\. If you have enough experience _and_ a good idea, make your decision
between a reliable cash flow and becoming an App Store cowboy. But only then.

~~~
PhilipA
Definately a good idea. Hopefully it will change so good apps will be more
important than marketing, but this will only happen if Apple changes their App
discovery...

------
gurkendoktor
If you use ARC from the start, then can you really understand block retain
cycles (which are just two bullet items below)?

I would absolutely try to write one or two "Hello World" apps without ARC
first. CMIIW but Xcode will highlight any instance where you do things
differently than ARC would, there is plenty of feedback on what you are doing.
And once you feel confident enough, upgrading the project just takes a few
clicks.

And I found ARC to be super easy not in spite, but _because_ I came from C++
:) it is shared_ptr vs weak_ptr all over again. Don't memcpy() them, don't
create cyclic references, beware race conditions when testing if a weak_ptr is
still there ...

~~~
mirkules
I love your advice: start out learning how to manage memory and it only gets
easier. While ARC is great compared to manual memory management, it doesn't
work on non-Objective-C object, such as CFRefs (when dealing with sound, for
example).

~~~
gurkendoktor
It's even worse when you have to mix CFRefs and Objective C. Without ARC you
don't need any __keywords to do so, and when you switch you know where they
come from.

------
Zev
Mostly a really good list. My only nitpick is:

 _RegexKitLite - Powerful regular expression support_

Use NSRegularExpression instead. It's built into the OS (in Foundation) as of
iOS 4, which is below the minimum target you have (if you support the iPhone
5).

------
morganb180
Thanks - as it happens I'm about 3 months in to learning Objective-c and iOS
development. This is super helpful, as many of the tutorials online are dated.
Right now I'm working through the Ray Wenderlich stuff which is really good,
at least as far as I can tell.

w/r/t using the visual XIB/Storyboard interface vs. coding the views, I've
found early on that while the nibs and storyboards make it easy to prototype
and visually hook stuff up, looking at some of the apps I admire (apps like
Clear, Rise, etc.), makes it pretty clear that I will need to code these views
up myself to achieve some of those interactions. Unless I'm missing something
(which of course I am, I'm a NOOB) I don't see how most of those can be done
right from the nibs.

edit: also, if anyone has any other recommended links/resources, I'd love any
recommendations. Thanks.

~~~
MaxGabriel
Eh, I wouldn't be so sure. I remember from the WWDC 2012 presentation that the
iPhoto team talks about how they used xibs in their workflow, and iPhoto is an
extremely impressive app. There's also the fact that you can do alot of setup
with a xib or storyboard, and then do relational layout programmatically.

~~~
objclxt
iPhoto is an interesting one: the _layout_ is done programatically, but the
xibs are used to load the images. For example, the brush panel is all animated
and arranged in code, but xibs are used to hold the brush PNG images since it
reduces the code burden (of manually creating the UIImageViews, etc etc).

------
shizwizzle
Good article, I like these because there are a lot of things I wish I knew
when I started iOS development as well 'back in the day' :) Couple nits:

-XIBs are awesome and you should strive to use them, falling back to layout in code when the XIB fails to meet your requirements. Though I'm also finding storyboards hard to swallow for complex projects. -Blocks and GCD are great tools but with great power comes a lot of complexity and consideration, they could easily get beginners in trouble. I ain't saying don't use em, but There Be Dragons Here.

Bravo on bringing up Singletons, thats something I only recently discovered
and wish I had sooner. Also, I feel like a primer on delegates, protocols,
notifications and selectors: when to use what and why, would also go a long
way in the beginning.

~~~
rimantas
My take is similar: I prefer XIBs, but I avoid storybords.

------
goronbjorn
I would add Crashlytics (<http://try.crashlytics.com/>) to the list of good
crash reporting services.

~~~
chaitanya
Seconded. I would add that crash reporting is pretty seamless with Crashlytics
-- the dSYMs get uploaded automatically everytime you build (and it works with
Jenkins too).

Don't know how things are with Testflight right now but when we worked with
them last year we had to right our own script to upload the dSYM. Also
Testflight does a lot more than just crash reporting so it might be too big a
hammer if you just want automated crash reports.

------
maximveksler
Thank you. I’m hobby learning iOS development. Have some experience with C,
but mostly knowledge of linux, java and devops stuff.

Here are the resources I’m using:

Started with:
[https://developer.apple.com/library/ios/#referencelibrary/Ge...](https://developer.apple.com/library/ios/#referencelibrary/GettingStarted/RoadMapiOS/chapters/Introduction.html)

Then, plan to get a feel of the language will read
[http://developer.apple.com/library/mac/#documentation/Cocoa/...](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html#//apple_ref/doc/uid/TP40011210)

Then I was thinking to go watch [https://itunes.apple.com/il/course/coding-
together-apps-for-...](https://itunes.apple.com/il/course/coding-together-
apps-for-iphone/id537447071)

Also, a book that seems good to read
[https://www.bignerdranch.com/book/ios_programming_the_big_ne...](https://www.bignerdranch.com/book/ios_programming_the_big_nerd_ranch_guide_rd_edition_)

Other suggestions and insights are appreciated.

~~~
cageface
This book was the most useful of the many iOS books I read when I was getting
started.

<http://shop.oreilly.com/product/0636920023562.do>

------
activepeanut

      Otherwise you can just use git submodules.
    

I would recommend against it. They become a real pain down the road.

I wish I had something to suggest as a replacement. We're still trying to
figure that one out ourselves. We just know we won't use submodules again. For
now, we're manually managing disjoint repositories.

~~~
MaxGabriel
The replacement is definitely the article's first suggestion: Cocoapods.
Cocoapods is awesome and is rapidly being adopted by major repositories like
AFNetworking, Kiwi, TTTAttributedLabel, MagicalRecord, and more:
<http://www.cocoacontrols.com/cocoapods>

It has been super easy compared to git submodules.

~~~
activepeanut
Do you have a non-Apple-specific suggestion? We do cross platform development,
so Cocoapods aren't an option.

~~~
MaxGabriel
Unfortunately, no.

------
josephlord
My tip for beginners would be that while ARC is great if you use KVO you need
to make sure that you consider the object lifecycles and remember to remove
observers before they are deleted otherwise you risk occasional crashes in
strange places.

------
fphilipe
Can someone explain to me why I should use dispatch_once at all when a simple
check whether the static variable is nil would suffice? It always seems so
cluttered.

Compare this:

    
    
      + (MyClass *)sharedClass {
          static MyClass *_shared = nil;
          static dispatch_once_t onceToken;
          dispatch_once(&onceToken, ^{
              _shared = [[MyClass alloc] init];
          });
          return _shared;
      }
    

...to this:

    
    
      + (MyClass *)sharedClass {
          static MyClass *_shared = nil;
          if (!_shared)
              _shared = [[MyClass alloc] init];
          return _shared;
      }
    

Is there any difference regarding performance?

~~~
eliperkins
Should you call the singleton on multiple threads, there is a chance you could
get inconsistent results based on a race condition. Using GCD ensures that the
singleton is truly only created once.

------
jkubicek
I would highly recommend downloading and installing DCIntrospect[0]. It's
designed to let you tweak layout in the simulator, but what it's really useful
for is probing the UI in large, complex apps. Need to tweak the font size on a
specific element, but you have no idea what that view class is? Enable
DCIntrospect, click on the element, log its class name and properties. This
has saved me, literally, hundreds of hours of debugging time over the years.

[0] <https://github.com/domesticcatsoftware/DCIntrospect>

------
joslin01
I've gotten bit a lot by putting a gesture recognizer on an UIImageView and
forgetting to set the image view's userInteractionEnabled property to true.

------
canthonytucci
Good tips. Though I might say that for many tasks NSOperationQueue can be even
easier/simpler for someone just starting out than GCD.

------
coryl
Here's a quick tip: you can also disable arc for older libraries should you
need to integrate them into your ARC project.

Just use the -fno-objc-arc flag
([http://stackoverflow.com/questions/6646052/how-can-i-
disable...](http://stackoverflow.com/questions/6646052/how-can-i-disable-arc-
for-a-single-file-in-a-project))

~~~
wsc981
Alternatively you can also enable ARC for classes. This might be useful when
you're working with a non-ARC project and want to include some ARC code. Use
the switch -fobjc-arc to enable ARC for selected classes.

I'm currently using this switch to gradually migrate a non-ARC project to ARC.

------
mmorey
Good list. There is some more great tips at
[http://stackoverflow.com/questions/155964/what-are-best-
prac...](http://stackoverflow.com/questions/155964/what-are-best-practices-
that-you-use-when-writing-objective-c-and-cocoa) .

------
verelo
Thanks for writing this, we're a bit beyond this stage but it certainly
reiterates a lot of our learnings. Good to validate that i'm not insane or the
only one feeling some of those pain points.

------
pjmlp
Nice comment about ARC.

I think we need a few programmer generations until everyone is fine with some
form of automatic memory management in all programming languages.

------
e28eta
Instead of manually running Clang's static analyzer (Build->Analyze), I'd
recommend setting your project up to always analyze after building.

------
so898
Great tips!! I really hope I have read these tips before I start my last
project, which I spent one night to make it localize...

------
codyko
Wish this article was around when I started. These are all things I've learned
to use and embrace every day. Great tips!

