Invalid IPA: The keychain-access-group in the embedded.mobileprovision and your binary don’t match.

Update 2014/03/12 This QuickLook plugin is a great way of seeing what’s in your provisioning profiles: https://github.com/chockenberry/Provisioning

Provisioning profiles are such a delight.  My latest battle with them involved getting the following error:

Invalid IPA: The keychain-access-group in the embedded.mobileprovision and your binary don’t match.

The background to the situation is this: I’d run out of devices on one of my Apple Developer accounts and needed to send out a test build to some new users. So I created a new bundle ID in my second account, re-archived the app and sent it out. The tester came back with the above error when they tried to install it.

The problem lay with me not changing the application-identifier and keychain-access-groups values in the entitlements file. These need to match the new provisioning profile values. The values for these changed because I was using a different developer account. keychain-access-groups is easy to miss as it’s folded when you open the entitlements file in Xcode.

You’ll find the correct values in your provisioning profile as well as in the App IDs page in the iOS Provisioning Portal.

Another error I hit with my second dev account was:

entitlement ‘application-identifier’ has value not permitted by a provisioning profile

This turns out to be caused by signing the IPA with the wrong identity. How did I manage that you ask? I was using my auto archive script and I’d forgotten to change what identity to use when signing. There’s two hours sleep I’ll never get back.

Previously: The executable was signed with invalid entitlements. (0xE8008016)

A Sunday Afternoon Project: KMMapList

I’ve been toying with the idea of doing another version of the Pint of Plain app and one of the things I want to change is list of bars you first see when you open the app. During the week I ended up on Dribble and saw a screenshot from an app called Chow Now.
What I liked about this is that the extra detail about the restaurants is present at the bottom where’s there’s more room to breath.  It’s a nice combination of the now traditional map and list views.  I’m guessing that tapping a pin will make the scroll view move and swiping the scroll view highlights the pin.  The details at the bottom are far more detailed than a normal call out and there’s enough room to have the phone number tapable as well as leading to a more detailed view.

Now I’m sure this will be easy to build with [REDACTED] in iOS 6, but I want something I can use now as other wise it’s an idea that would lie rotting in my brain.  I also wanted to play with reusable UIViews built with Interface Builder as a test for a couple of future app ideas.

I’ve a first pass of my code in a repo on GitHub  and I’ll probably be poking at it a bit more over the next few weeks.  For something that I kicked about for a couple of hours today the core of it is there and I’m happy enough with the result.  It’s not as pretty as the example from Dribble, but that was never going to happen with my cack handed design chops.

Functionally there but just not pretty

There’s probably quite a few improvements that could be done to the current code (apart from the obvious hard coding of the data points).  It’d probably be better if the off screen views were generated just in time rather than all at once and I’ve still to figure out how it’ll handle a large number of annotations.  Still, it’s a good proof of concept and worth moving along.  We’ll see how it goes over the next little while.

Clickable Skin on a Website

I was asked the other day how Broadsheet.ie does the horrible clickable ad skins so I may as well document it here as well. I can’t remember how I exactly figured it all out but I’m sure posts on stackoverflow.com helped as well as looking at the source of the likes of entertainment.ie to see what they did. As always, this works for me and your mileage may vary.

First we set up the css for the background image:

body {
       background-image: url(/images/some_image.jpg);
       background-attachment: fixed;
       background-repeat: no-repeat;
       background-position: center top;
       cursor: pointer;
}

#page {
       cursor: auto;
}

This pins background image to the center of the page so if the user resizes the window it doesn’t move. It does mean that a user may not see it if their browser window is narrower than the background image.

To make the pointer turn into a hand when the user is hovering over it, you need the ‘cursor: pointer;’ line. However this makes the cursor a pointer everywhere, so for the actual content of the page ‘cursor: auto;’ needs to be set so it will use the correct default when hovering over content that is not a hyperlink.

Next we need to capture clicks made on the background. This is done using some JQuery:

function recordOutboundLink(link, category, action) 
{
   _gat._getTrackerByName()._trackEvent(category, action);
   setTimeout('window.open("' + link + '")', 100);
}

jQuery(document).ready(function() {
       jQuery("body").click(function(e) {
               var target = jQuery(e.target);
               if (target.attr('id') == 'body_id')
               {
                       recordOutboundLink('http://www.karlmonaghan.com','outbound', 'karlmonaghan')
               }
       });
});

Last, but not least, we need to change the body tag:

<body id="body_id">

What the javascript in the document ready block does is capture click on the page. The id of the element clicked on is retrieved and if it was the id we’ve assigned to the body itself we call the recordOutboundLink function. This function takes 3 parameters – the URL the user should be brought to, the event category and event action. We use this function so we can record the click in Google Analytics for our own information. If you’re not interesting in the stats (but really, you should be) you can replace this line with a just a document.open call.

Personally I’m neither fond of this sort of advertising nor convienced that it’s particularly effective (although it will very effectively annoy your users) but if someone is willing to hand over a ball of money for it so be it.

Auto-Versioning and Auto-uploading to TestFlight/HockeyApp When Archiving in Xcode

I’ve been playing with TestFlight this week with some of my apps.  The main aim of my experimentation was to have the version numbers of my apps incremented and the IPA automatically uploaded when I archive a project.

There’s a lot of posts already on various parts of the process, but I’d thought I’d document the whole process I went through as there were a few tweaks to be made on the snippets of code I found.

I’ve projects both in local SVN repos and on GitHub so I need to be able to create version numbers from both. Another wrinkle is that I sometimes use HockeyApp as well, so I decided I may as well be prepared for those occasions and include it in the script.

The first step was to increment the version number. A post from Stackoverflow gave me the starting point and with a few minor tweaks I ended up with this:

This script needs to be run before Xcode does a build. To do this, it should be added as a ‘Pre-action’ to the build function. Edit you scheme, click the down arrow beside ‘Build’, select ‘Pre-actions’ and then on the + at the bottom left of the box on the right. You’ll be given two options and you’ll want to select ‘New Run Script Action’.  Select your target in the drop down beside ‘Provide build settings from’ and paste the script from above into the box below that.

Now when you archive your project the Bundle Version will be updated.

For git, we just adjust the REV line:

We could have used something like ‘git describe –dirty’ here instead, which would produce something like 1.2.1-1-ge03a85c-dirty as the version number. But when you submit the app to Apple if the version number isn’t all digits your app will fail validation so you’ll have to manually change it beforehand. Since this is something I’m prone to forget so I’d rather just have the digits.

After the version number has been updated, Xcode creates the archive and then we need to create the IPA upload it.  This is done by adding a script to the ‘Post-actions’ of the ‘Archive’ action.

Justin Miller’s post ‘Automating Development Uploads to TestFlight from Xcode‘ got me most of the way creating and uploading the IPA to TestFlight. There’s been a few forks of the original gist, and I ended up extending one by c0diq to include uploading to HockeyApp. I also added a couple of extra flags to make the script less chatty when you know you want to upload the IPA on archive and when you know the code signing identity to always use.

Something to note is that HockeyApp is less tolerant of duplicate bundle versions than TestFlight so if you’ve not made any commits since the previous version, the upload will fail. You’ll be able to see the error returned by HockeyApp in the error dialog and more details in the log.

That’s pretty much it. It seems to be working fine at the moment but I’m sure I’ll end up with a few more refinements as time goes on.

A Sunday afternoon project: Providing App Store stats via JSON

Last month Apple announced their auto-ingest tool for fetching the download and update statistics for apps.  The tool downloads the stats for a particular day or week as a gzipped CSV file that you can then process yourself.  This is far nicer than having to try and scrape the numbers from the iTunes Connect page although the daily numbers are still restricted by a two week limit and the weekly by 13 weeks.  Hopefully in the future you’ll be able to retrieve further into the past (assuming the data still exists).

I’d a bit of free time this weekend and decided to have a poke at this and see if I could  grab the data and present it in a easily consumed format (i.e. JSON).  Another reason for looking at this is because I have two iPhone Developer accounts and it’s be nice to see the data from both as one graph rather than having to log in and out.

To that end I wrote a couple of lumps of PHP to ingest and process the stats which is available on GitHub (https://github.com/kmonaghan/itunes-connect-auto-ingest).  There’s a couple of small steps to get it all to work.

First, create a database (or just use an existing one) and create the table in schema.sql.

Next, edit boot.php.  Here, you need to put in your database details and the details for each iTunes Connect account you have.  To do this you need to put in an array with the following key pairs:

array('username' => 'iTunes Connect username',
'password' => 'iTunes Connect password',
'vndnumber' => 'VND number',
),

The username and password are the details you use to log into iTunes Connect.  You’ll find the VND number if you log into iTunes Connect and go into ‘Sales and Trends’.  It’s the number beside your name at the top left of the screen.

Update: From the comments, this is how you find the Vendor ID (VND):

Choose Sales and Reports.

Choose “Reports” from the top left menu (Where default is “Top Content”).
From the form that will be shown, choose monthly report and download.
The downloaded file will be of format S_M_(VendorID)_TIMEPERIOD.TXT

You can have as many of these accounts as you want and the ingest script will check each one.

Now all the details have been set up, you can ingest the data from Apple.  This is done by simply running ingest.php.   If it’s the first time the script has been run, it will look back 14 days.  Otherwise, it will look in the database for the last successful day there was an import and attempt to import all days since then.  After your first import, you should create a cronjob to run this script once a day to capture the latest stats.  If the downloaded tar files are 0 bytes, check your login details and VND number.

Once all the data is in the db, we can view it via daily.php which outputs the results as JSON.  This will by default output the total number of units downloaded for all apps in the last month.  It can take four parameters:

  • apple_identifier: A particular app identifier.
  • product_type_identifier: This can be 1 (default) which is downloads or 7 which is updates.
  • from: The date to get the stats from.  Expected as dd/mm/yyyy.  Defaults to 32 days ago.
  • to: The date to get the stats to.  Expected as dd/mm/yyyy.  Defaults to yesterday.

And that’s that!  There’s some Javascript in stats.html which consumes the JSON and uses the Google Chart Tools to display the results.  An example of some live data using my own apps is available here.

This is very much a works-for-me lump of code, so it may not do exactly what you want but it should be easily extendable to provide exactly what you want.  It will certainly not cover every error condition.  I’ll probably add bits and pieces to this as I think of a stat I want to visualise or I come across a bug unexpected feature.

Something I might consider looking at in the future is writing a clone of the iTC Mobile app that utilises the saved data.  It’d be a nice little project to try out Core Plot.

The executable was signed with invalid entitlements. (0xE8008016)

Update 2014/03/12 This QuickLook plugin is a great way of seeing what’s in your provisioning profiles: https://github.com/chockenberry/Provisioning

The code signing for iPhone apps can drive me batty sometimes.  It rarely works first time for me and the errors you get are completely unhelpful.  It doesn’t help that for a variety of reasons I’ve 3 developer profiles on my work machine.

Today, I’ve been getting the following:

The executable was signed with invalid entitlements.

The entitlements specified in your application’s Code Signing Entitlements file do not match those specified in your provisioning profile.

(0xE8008016)

The very least they could do here is list which entitlements are not matching.  To figure this out, you need to view the provisioning profile and find the Entitlements key.  It’ll look something like this:

<key>Entitlements</key>        
<dict>                
    <key>application-identifier</key>               
    <string>7X895L3TS6.com.your.app</string>                
    <key>aps-environment</key>                
    <string>development</string>                
    <key>get-task-allow</key>                
    <true/>               
    <key>keychain-access-groups</key>                
    <array>                        
        <string>7X895L3TS6.*</string>                
    </array>       
</dict>

You need to make sure the contents of your Entitlements.plist match these exactly.  After you’ve made your change, clean your project and rebuild.  Your app should now install and run on your device.

TTWordPress – a Three20 library to display a WordPress blog in an iOS app

DEPRECIATED use KMWordPress instead.
DEPRECIATED use CBPWordPress instead.

TTWordPress is a library I wrote to easily display a WordPress blog in an iOS app.  I originally wrote it for the Visionary.ie app and was then able to expand on that to create the Broadsheet.ie app.  Since I found it useful, I thought I’d release it into the wild and see what happens.

To provide the data from a WordPress blog is a nice machine readable format, the excellent JSON API plugin is used.  Obviously, it needs to be installed for the iOS to be able to retrieve anything but that’s a trivial matter.  If you want users to be able to comment on posts, you need to activate the ‘Respond’ controller in the API settings.  On the iOS side of things, the library uses Three20 for the consuming the JSON and displaying the information in tables.

To use the library in your own app, you first need to add Three20 to your project (if you’re not already using it).  Open the example TTWordPress project and copy the WordPress folder and all its contents to your project.

To point the library at your own blog, you need to edit the following line in TTWordPress.h:


#define WP_BASE_URL @"http://ttwordpress.karlmonaghan.com/"

In this file, you can also change the default title for the latest posts view and the way dates are displayed for posts and comments.

Then in your AppDelegate, add the following includes:

#import "WordPressBlogViewController.h"
#import "WordPressAddCommentViewController.h"

Then add the following lines:

[map from:@"tt://examplepostlist" toSharedViewController:[WordPressBlogViewController class]];
[map from:@"tt://blog/author/(initWithAuthorId:)" toViewController:[WordPressBlogViewController class]];
[map from:@"tt://blog/category/(initWithCategoryId:)" toViewController:[WordPressBlogViewController class]];
[map from:@"tt://blog/post/comment/(initWithPostId:)" toModalViewController:[WordPressAddCommentViewController class]];

The first line sets the path to a view controller that will list the latest posts from your blog, the second shows the posts belong to a particular author, the third from a particular category and the fourth is the modal pop up for making a comment.  The assumption here is that the list of posts from your blog will be a tab in your app hence being a shared view controller as opposed to the other two which are created and destroyed on demand.

The final step is to call the latest post view controller from somewhere.  In the sample project, it’s added to the UITabViewController. Once you’ve done that, compile and run your app and you should see your blog posts.

The code is available via a Git repo at https://github.com/kmonaghan/TTWordPress.

If you do use it, I’d love to hear from you.

The icon used is from the excellent Glyphish set.

DEPRECIATED use KMWordPress instead.

Pint of Plain V2.0

Last week, the V2.0 of my Pint of Plain app was approved for sale on the Apple App Store.  It’s a major update of the app, with most of the code base completely rewritten.  I think this version is a vast improvement on V1.2 and I’m planning a few more updates once I get some free time again.

What’s been interesting (for me anyway) to see over the last week is the number of people that download the update.  From what I’ve seen from previous updates, the bulk of users will update in the first week and then a trickle after that (in a classic long tail style graph).  Since it was approved, there’s been 1,144 downloads.  This compares to about 10,000 total downloads since the app was released in December ’09.

It’s a useful app to test out various libraries I come across so I decided I’d mention the ones I used this time around.

Three20

The core functionality of the app uses the fabulous (if a little delicate) Three20 library.  Using the table classes and JSON library meant I could quickly rebuild the primary screens of the app.  The crowning glory though is the photo gallery.  It’s pretty straight forward to add a slick gallery once the images have been pulled from the API.

I have been frustrated though that when a new version of Xcode is released, the library needs tweaking before it works again.  There’s been promises to improve this in future releases, so fingers crossed there.

The lack of documentation is a hinderance as well.  This is mitigated by the fact that most of the methods are well named.  Still, when you’re not sure where you should be even looking, it can be annoying.

Appirater

Appirater is a great little library for quickly adding an alert reminding people to rate the app.   I’m not hugely convinced that a good rating boosts downloads all that much, but since this is so simple to use it’d be a shame not to add it.

InAppSettingsKit

In this version of Pint of Plain, there’s a few more settings the user can tweak.  I doubt many people ever look at the various settings you can change in the Settings App so I wanted to offer an in app alternate.  InAppSettingsKit does all the heavy lifting for you and like Appirator, so easy to include it was a no brainer.

MapKitDragAndDrop

In the old version of the app, a bar’s location was simply determined by using the GPS and only used if the accuracy was under 50m.  This was never a great solution and I wanted to give the user the option of dropping a pin the right location.  While search for how to do the drag and drop, I came across MapKitDragAndDrop which did everything I needed.

Glyphish

Not a code library but rather a set of icons, Glyphish is a great resource.  There’s an icon for nearly every tab you need and they’re all beautifully crafted.

I think the fact that there’s so many libraries and resources out there now shows how iOS has matured as a platform.  Every time I go to find out how to do something I’ve seen in another app, there’s a library for it.  It certainly makes development much easier than when I first looked at it all over 2 years ago.