Category Archives: iOS

These posts are syndicated from my iOS Dev Diary over at pinkstone.co.uk.

The format is slightly different with more code snippets and less explanations. I had originally designed it as a notebook in iOS Development – now you can follow along if you’re interested.

How to load a different storyboard depending on screen size in iOS

As much as I appreciate the idea of Auto Layout, I don’t think it likes me very much. In turn, I don’t like Auto Layout very much. The pain and hassle it takes to make several UI elements fit well on a 4 inch screen as well as a 3.5 inch screen regularly drives me crazy. On paper it’s a great idea – but in reality not fit for prime time.

Screen Shot 2013-12-31 at 08.56.22

It’s not a coincidence that we can choose completely different storyboards for iPads and iPhones. Let’s take the same approach when dealing with the two different iPhone screen sizes by loading different storyboards.

Here’s how: First, finish one version of your storyboard. Next select it and head over to File – Duplicate. Give the second one an appropriate name, then tweak your UI elements so that they look nice on the other screen size.

Now add this to your AppDelegate.m:

This method returns the following UIStoryboard file:

  • Main.storyboard on 3.5inch devices
  • Main-4in.storyboard on 4inch devices

Now we need to make sure it gets loaded appropriately. We’ll take care of it in AppDelegate.m like so:

This overrides the default storyboard that’s declared in your project settings. You can expand the above method by checking which iOS Version the device is running, and of course returning an iPad storyboard too.

In your face, “Auto Layout”!

How to dismiss the iOS Keyboard when the done button is pressed

It has puzzled many generations how to get rid of the keyboard when the user is done entering text into an iOS text field. There doesn’t seem to be an obvious action we can attach to make this happen.

iOS Simulator Screen shot 31 Dec 2013 05.45.27

That’s because rather than looking at the keyboard itself, we need to look at what actually brought it up in the first place: the UITextField. Even though the text field can trigger an action, we don’t want to touch that for dismissing the keyboard. All we need to do is to implement the following method from its delegate protocol:

This method is called whenever the return button is pressed. We return YES to agree, and resign the text field’s first responder status which takes the user focus away from it.

Since this is a protocol we *should* really conform to it formally by declaring it in the header file. It appears to work without this step, but let’s play it by the rules here:

Note that you need to connect your text field’s delegate in Interface Builder to the class that’s implementing the above method (i.e. self), otherwise the keyboard won’t be dismissed. To do this, control-drag from the text field to the orange square at the bottom of your view controller and select “delegate”. You can verify this in the connections inspector:

Screen Shot 2013-12-31 at 05.55.36

Links to the latest Social Icons

InBug-60px-RFacebook, Twitter & Co. change their brandings every now and again, and every time I need them for a project I keep scrambling to find the official links. Well no more – here’s a list of them all:

How to increase your Build Number automatically every time you build your Xcode Project

Xcode includes something rather magical called the Apple Generic Versioning Tool. With this tool you can increase your Build Number automatically every time you hit “Build and Run” in Xcode.

Here’s how you can add it to your project. I’m using Xcode 5.1 here with a new Single View iOS project. But this will work just fine in other versions of Xcode.

By default, Version and Build are set to 1.0 (in your app target, under the General tab). We want to leave Version alone and only increase Build.

Screen Shot 2013-12-30 at 12.05.06

Head over to the Build Settings tab and find the “Versioning” section. It’s easiest to just search for it. In here, set the Current Project Version field to your initial build – let’s say 1 for this example.

Screen Shot 2013-12-30 at 12.10.10

Now select the Build Phases tab. Click on the little plus icon in the top left corner and select New Run Script Build Phase. This will allow us to execute a small script every time we build.

Screen Shot 2013-12-30 at 12.11.39

Open the little triangle next to Run Script and underneath the Shell field, add this bit of code. You can even add multiple lines, it’s like a little text editor.

Here’s what it should look like:

Screen Shot 2013-12-30 at 12.15.03

And that’s it! Hit CMD+B a few times and head back to the General tab to see your Build Number magically increased. You can now retrieve this value from you main Bundle (explained in my previous article).

Kudos to nekno who was kind enough to share this knowledge on Stackoverflow:

How to read you App Version and Build from the Main Bundle

The required Version and Build numbers you add to Xcode make it into your app’s Main Bundle. You can retrieve those values from the Main Bundle and use them in your app.

Here’s how:

iTunes Connect reads both of these. Your “new version” is what’s displayed in the App Store, while the build is a more arbitrary thing you can set yourself.

Note that both values are floats, and that you need to increase them with every version. If you decrease either of them, iTunes Connect will complain next time you submit a build.

What are the button indexes in a three-button UIAlertView

iOS Simulator Screen shot 30 Dec 2013 09.50.43

The cancel button is always index 0, and all other buttons in the array start at index 1 counting up.

For completion, here’s how to create it:

And here’s how to react to it:

This is a delegate method, so the reacting class needs to conform to the UIAlertView Protocol like so:

How to restore your single In-App Purchase in iOS

This is an addition to my previous article. To allow uses to restore their In-App Purchases you can expand on the previous article and include the following method in your Shop class. This needs to be public so it can be called from your main class:

Much like submitting a payment, this now submits a “restore request” to the app store, which in turn will get back to us via the observer delegate. Here’s the implementation from before (still in AppDelegate.m), with the addition of a fleshed out reaction to the restore:

We let the user know about a successful restore (or failure) via an alert view. Since I’m calling this multiple times it was easier to create a method for this:

Note that you should validate the purchase before restoring it. The Apple documentation goes on a bit about receipt validation without describing a way to actually do it.

How to restore your single In-App Purchase in iOS

This is an addition to my previous article. To allow uses to restore their In-App Purchases you can expand on the previous article and include the following method in your Shop class. This needs to be public so it can be called from your main class:

Much like submitting a payment, this now submits a “restore request” to the app store, which in turn will get back to us via the observer delegate. Here’s the implementation from before (still in AppDelegate.m), with the addition of a fleshed out reaction to the restore:

We let the user know about a successful restore (or failure) via an alert view. Since I’m calling this multiple times it was easier to create a method for this:

Note that you should validate the purchase before restoring it. The Apple documentation goes on a bit about receipt validation without describing a way to actually do it.

How to create a single In-App Purchase in iOS 7

This “simple everyday” feature has caused me many headaches on many occasions. Implementing a simple unlockable feature isn’t as straightforward as it perhaps could be – and I’ll make it as simple as possible (so I won’t forget next time I need to add it to an app).

In this example we’re going to have one single feature that is already setup in iTunes Connect. It’s a non-consumable feature, such as “The Full Version”. To keep all our methods together in one place we’ll create a new NSObject class called “Shop”. This is where we’ll do most of the coding. Later we’ll also add code to the AppDelegate class.

This is a LONG article – grab a coffee and don’t get overwhelmed. It’ll take several tries to get comfortable with this matter (it’s not just you).

Let’s start with our new Shop class. It’ll have two properties – these can be private:

One holds an array of product identifiers (reverse domain notation, matching those in iTunes Connect), the other holds our actual product. Here’s a custom initialiser for the first property – it creates an array with one item (so you can expand with more products later):

Our Shop class needs a public method that can be called from the class that’s initiating the purchase. Here it is:

It looks more complicated than it really is: we’re initiating an SKProductsRequest with our Product ID and call its start method. The App Store will come back to us in a moment by calling methods of the SKProductsRequestDelegate protocol.

When we’re ready to initiate the purchase, create a new Shop instance and call this method. Use a property to hold your Shop instance, otherwise the instance is likely de-alloced before a response is received.

The App Store will get back to us with the products title, description and price a bit later on. Note that for a response to be received, your device needs to be online. So before calling the above method, make sure you’ve checked for network connectivity – and if that’s not available, don’t call the method.

Which reminds me: let’s make our Shop.h file react to the response by adding said protocol:

The SKProductsRequestDelegate Method

The App Store calls this method when it’s ready – no matter if the product exists or not. All we have to do is implement it:

The App Store will give us the actual SKProduct which we’ll grab hold of in our self.mainProduct property. If the user can make payments, the Store UI is called giving the user a choice to buy the product. If in-app purchases are disabled, the user gets a different UI explaining the problem.

We’ll also check if this product is invalid – which of course it shouldn’t be, but it’s good for testing. Typos can lurk everywhere.

Store UI

In our example we’ll have a UIAlertView that displays either a buying choice or an explanation as to why the user can’t buy anything. These methods are called by the above:

The first method looks a bit difficult, but it’s all code from Apple’s Guidelines. We use a number formatter to display the localised price with correct currency symbol. Next we’ll bring up a UIAlertView with the title and description of our product – this comes directly from iTunes Connect. You can translate your product there with a localised version.

The second method is called if in-app purchases are switched off on the device (under Settings – General – Restrictions).

Making the Purchase

Since we’re using an alert view here to react to the purchase, its delegate needs to react. In my example this happens in a different class – not the Shop class (hence the above alert views’ delegates are set to self.delegate rather than self). Therefore we need a second public method in our Shop class which our main class can call if the user decides to go ahead with the purchase. Here it is:

It’s short and sweet: create an SKPayment object with our product (glad we’ve saved it earlier), and add it to the SKPaymentQueue. In English: tell the App Store that our user wants to buy the product.

Now App Store goes to work and will get back to us in a moment. It will post notifications about the outcome, to which we can listen by conforming to another protocol. But we can’t implement those methods in our Shop class because it could be called at any time – even long after a purchase. Imagine the old “connection goes dead” ploy right after a user hits the buy button. By the time he’s back online it may be decades later.

App Store will remember that a payment was successful (or not) and will want to tell our app about it. So the only place we can put those delegate methods is in AppDelegate. The good news is we’re done with our Shop Class – just make sure those two public methods are declared in Shop.h:

Conforming to the SKTransactionObserver Protocol in AppDelegate

I only touch AppDelegate in rare circumstances, and this is one of them. First let’s tell him that we want to conform to said protocol (in AppDelegate.h):

Next, in AppDelegate.m, implement the following observer methods. We need to do this so that AppDelegate will listen to notifications posted by the App Store and react accordingly. This is the part I thought was a bit sketchy and confusing in Apple’s In-App Purchase Programming Guide:

The following method is called when the App Store gets back to us, and since AppDelegate is now the observer, we’ll listen to them at all times when our app is running:

We use a for-in loop to react to every transaction in the queue. Conceivably users could have bought multiple products, that’s why – however unlikely in our case. Depending on the current transaction’s transactionState we can react accordingly. For simplicity I’ve only covered a successful purchase here, you get the idea with the comments in the other sections of the switch statement.

In our “success” scenario, we need to unlock the full version (i.e. set a BOOL in NSUserDefaults or iCloud) and save the transaction receipt for later fraud detection and validation. If you’re offering downloadable content this is the time to download it.

When all these things have finished, you need to tell the App Store that you’re done processing this transaction so that it is removed from the SKPaymentQueue.

Save Receipt and Unlock Full Version

For completion, here are two methods that save the receipt and saving a “fullVersion” BOOL in NSUserDefaults. Your app can check this next time a premium feature is used. If the user has bought your product, go ahead and make it available. If not set, display the Store UI:

Note that the transactionidentifier string is only available in iOS 7 and later. iOS 6 and earlier can similarly save the full receipt object as data. The Apple Documentation has more on how to do this.

Saving receipts isn’t strictly necessary, but if you do then you can check a valid purchase with the App Store sometime later.

How to open the LinkedIn App from your own iOS App

Here’s a sample action that tries to open a LinkedIn Profile with the LinkedIn App. If it’s not installed, it opens a link to the profile in Safari. If that doesn’t work it gives a log message (please handle appropriately in your own code):

Note that currently you can only link to personal profiles, not to company profiles.

To create a dynamic web button with follower count (or not), check out the LinkedIn Developer Portal and load the code into a small UIWebView.

At the time of writing it appears that none of the LinkedIn provided plugins are actually working anywhere other than the preview. Looks like we’ll have to use a standard graphic instead until this is fixed.