Yearly Archives: 2014

How to access values from the iOS Clipboard (from copy and cut operations)

Screen Shot 2014-09-03 at 16.39.32iOS has a class called UIPasteboard which lets you access the last value that a user has copied or cut to the clipboard (or pasteboard).

The class has a singleton which lets you access a string like so:

This will work fine when any kind of text is involved. Copy/Cut/Paste is also available for images from the Photos app though, and you can access the latest UIImage like this:

Note that those two values are mutually exclusive: if you’ve copied an image, then the text string will be nil, and when you’ve copied text then the image value will be nil.

The UIPasteboard class is very versatile and lets you do all kinds of things – check out the Class Reference for more information:

How to add ordered image uploads in WordPress for iOS 4.0.3

AppIcon76x76@2xI’ve finally figured out how to tweak WordPress for iOS so that images are uploaded in the correct order. I had been working on this fix for so long that the project has now changed and the file in question is no longer called in the current version of WordPress for iOS (4.1.3 at the time of writing).

The team are already working on a much better solution for inserting images, but until then the following works fine for me. Perhaps it’ll come in handy for future projects.

Before version 4.1.x, image uploads happened in a file called WPMediaUploader.m (found in Classes/Controllers/Media). In its uploadMediaObjects method, a for/in loop sends each object to an upload routine which inserts the relevant code into the post editor via a notification.

The trouble was that all uploads happen concurrently and hence the upload that finished first is inserted, neglecting the order in which the images were picked. Here’s the original method:

I tried a LOT to fix this, and the solution that works best is to wait for the first upload to finish and only then submit the next object to the upload queue. Here’s how I did this.

First I’ve added two new properties to the class: one holding the current array of media objects, and an int to count which object is currently uploading:

In the uploadMediaObjects method I’m storing this array in my property and start the first upload. I’m also incrementing the counter so we can keep track of all uploads in another method:

We also need a method that can be called via a notification when the current upload has finished:

If another upload is required we’ll submit it, incrementing the counter. If not, we’ll reset those properties via a cleanup routine (more on that in a moment).

The observer that we’ve setup will be called after an upload, no matter if successful or not. For clarity I’ve added it twice (but of course it’s enough to add it once at the end of the method):

While I was testing this I’ve noticed that this class isn’t initialised again when you start another post, so our properties still contain (the wrong) values on our next post. Hence we need to do a bit of cleanup when we’re done by removing the observer and resetting our properties:

In case someone hits cancel during our uploads we must make sure we also call the above, otherwise we’ll experience another crash when we write the next post:

And that’s it! I’ve created a fork the project with the above changes:

The “real” WordPress project is also on GitHub, fork away:

After WordPress 4.1 the project has been split into smaller chunks which will make it easier to integrate parts of WordPress into our own apps soon. See what else is available:

How to open the Pinterest App from your own iOS App

Pinterest_Badge_RedYou can open Pinterest links from your iOS app directly in the Pinterest app if it’s installed. This includes direct links to a user, a user’s board, or a specific pin.

In the following code snippets we’ll do just that, and if the Pinterest App is not installed on the device we’ll open the link in Safari instead. These methods can be hooked up to a UIButton.

Note that for this to work, users need to be logged in to the Pinterest App – otherwise the app opens with a login prompt and not the link we want.

Opening a Pinterest User Profile

Much like on Twitter, users on Pinterest have handles. Mine is versluis2000, and my Pinterest URL is http://www.pinterest.com/versluis2000. Here’s how you open this user via the Pinterest app:

Trying to display your own Pinterest User Profile may crash the Pinterest App – at least that’s what happened in my tests.

Opening a Pinterest Board

Users on Pinterest can pin links to their boards which work like collections or categories. Those boards have slugs that appear after the user handle. I have a board called iOS Projects which has the following URL: http://www.pinterest.com/versluis2000/ios-projects/

Here’s how we can open one directly in the Pinterest App:

Opening a Pinterest Pin

When a user finds a link on the web and pins it, the link will receive a unique numeric ID. Such an ID is independent from the user who pins it. Here’s a pin to a sketch of a Polaroid camera I drew: http://www.pinterest.com/pin/76279787413881109/

Let’s open this pin in the Pinterest App:

How about pinning something directly from my own app?

If you’d like users to pin something directly from your app, take a look at the iOS Pin It SDK – brought to you by the friendly folks at Pinterest. The article also explains the deep linking structure we’re using in the above examples:

Care for a Demo Project? https://github.com/versluis/Pinterest

Creating Multiple In-App Purchases in iOS

In this screencast I’ll show you how to create multiple in-app purchases in you iOS app. The first part is a quick overview, and the second part shows how I’m tinkering with the code (members only).

This is based on an earlier tutorial in which I’m explaining how to create a single in-app purchase – if you’d like to follow along, you can find it here:

In a nutshell we’ll duplicate the earlier Shop class, add our new product identifier and amend the StoreKit observer method, as well as the alertView so that it can unlock the correct product.

The source code for this project is available on GitHub: the master branch is the earlier tutorial with a single product, and the Multi-IAP branch is what’s shown in this video.

This content is for members only.

How to fix “The identity used to sign the executable is no longer valid” error in Xcode

Screen Shot 2014-07-28 at 22.17.57It happens to all of us: your Apple Developer Membership is up, you renew it for $99 per year and you think you can get back to work. But no. The friendly folks over there made sure that nothing lasts forever – including your Provisioning Profiles.

The above error is easy to fix and only involves 57 steps per app. The abridged version:

  • head over to the Apple Member Center
  • find the Provisioning Profiles section
  • click the ones saying “invalid” or “expired”
  • edit and regenerate them
  • back in Xcode, refresh your profiles

The principle has been the same for a while, but every year the position of those items changes a bit. Here are some screenshots for the few seconds that remain in July 2014. It’ll probably be all outdated as soon as I hit publish. But until then, here goes:

Head over to http://developer.apple.com and hit Member Center at the top right. Find something like Certificates, Identifiers and Profiles:

Screen Shot 2014-07-28 at 22.31.08

It’s a link that takes you to a section similar to this:

Screen Shot 2014-07-28 at 22.32.13

Select Provisioning Profiles (under iOS or Mac Apps, depending on your app) and you’ll see a long list of all profiles you’ve ever created. Pay attention to anything that’s not green in the left hand column, indicating expired or invalid profiles:

Screen Shot 2014-07-28 at 22.21.02

Find the profile in question and hit Edit. For Development Provisioning Profiles, you’ll find that your Development Certificate is no longer selected. Simply select it, add (or remove) any devices for this profile, then click Generate at the bottom. The next screen will offer you to download said profile – but since we’re using Xcode 5 or 6 we can ignore this step.

Screen Shot 2014-07-28 at 22.21.40

Distribution Profiles behave much the same: your Distribution Profile is deselected. Simply select it and hit generate. Again ignore the generous download offer and select Done instead.

All those little red and yellow symbols should look green and calm like this:

Screen Shot 2014-07-28 at 22.22.27

I know what you’re thinking: “Hey, I’ve got 30+ profiles sitting there – isn’t there a way to renew all of them in one fair swoop?” – Of course there isn’t, don’t be ridiculous!

Back in Xcode

Now that the profiles are fixed, let’s tell Xcode about them. Head over to

Xcode – Preferences – Accounts – select the account in question – select View Details.

On the bottom left corner of that window you’ll see something like a refresh icon. Click that and Xcode will communicate with the Member Center and pull in those new profiles.

When Xcode has finished, hit “done” to close that window and head over to your target, select Build Settings and find the Code Signing section (you can search for it if that list is a little long and confusing for your taste).

Reselect your provisioning profile and – in theory – Xcode should now deploy your app correctly.

Notice that I said “in theory” – because sometimes this doesn’t work. In which case, you can try the following options:

  • Build – Clean
  • restart Xcode
  • close your project, then restart Xcode
  • remove the app from your device, restart Xcode and re-deploy
  • find a different hobby because profiles take all the fun out of developing with Xcode

Idea for a bumper sticker: Honk if you hate Provisioning Profiles!

How to compare two NSDates

Screen Shot 2014-01-07 at 12.55.39Comparing NSDate objects should be as easy as comparing two numbers. But because NSDate objects are complex, it’s not an easy task.

Lucky for us the NSDate class has several ways of dealing with this conundrum.

Imagine in the following examples that we have the objects “today” and “myDate”, the latter of which we would like to compare to today. We want to know, is myDate earlier or later than today?

earlierDate and laterDate

The easiest two to remember (for me) are earlierDate and laterDate. Here’s how they work:

laterDate returns the NSDate object which is later, earlierDate returns the earlier one.

compare

For those brains that are wired like a frigging computer we also have the compare method, which compares the results to three much less intuitive enumerations:

The latter option can be good if you need to make sure the two dates are identical.