Recent Updates Toggle Comment Threads | Keyboard Shortcuts

  • Jay Versluis 10:52 pm on July 28, 2014 Permalink | Reply
    Tags:   

    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!

     
  • Jay Versluis 6:41 pm on July 26, 2014 Permalink | Reply
    Tags:   

    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:

        if ([myDate laterDate:today] == myDate) {
            NSLog(@"myDate is LATER than today");
        } else {
            NSLog(@"myDate is EARLIER than today");
        }
        
        // likewise:
        if ([myDate earlierDate:today] == myDate) {
            NSLog(@"myDate is EARLIER than today");
        } else {
            NSLog(@"myDate is LATER than today");
        }
    

    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:

        if ([myDate compare:today] == NSOrderedAscending) {
            NSLog(@"myDate is EARLIER than today");
        }
        
        if ([myDate compare:today] == NSOrderedDescending) {
            NSLog(@"myDate is LATER than today");
        }
        
        if ([myDate compare:today] == NSOrderedSame) {
            NSLog(@"myDate and today are THE SAME DATE");
        }
    

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

     
  • Jay Versluis 12:12 pm on July 24, 2014 Permalink | Reply
    Tags: , ,   

    How to reset your iCloud Ubiquitous Container 

    In this screencast I’ll show you how to reset your iCloud Ubiquity Container from an iOS device. This will clear up anything you’ve saved in iCloud Documents and iCloud Core Data and also simulates “first installation”.

    Sometimes when you test the same app over and over the container can get corrupted, error messages start flooding in and ultimately your app doesn’t behave as expected – making you doubt your sanity, alienating your friends and family and giving you more grey hair then you need.

    If the above still doesn’t work, turn your devices off and on again, restart Xcode and reboot your Mac – a useful tip often forgotten with pesky bugs that don’t make sense (thanks to Eric for reminding me of this).

    In a nutshell:

    • remove your app from all devices – this is important because running apps, or existing apps launched will assume there’s data in iCloud and they will try to communicate with your (defunct) container
    • remote all data from the container as described in the video (on iOS, head over to Settings – iCloud – Manage Storage – find your app and select it, hit edit and delete all data)
    • now re-deploy the app to each device via Xcode

    For Core Data: the first app that’s launched checks to see if data exists in iCloud, and if not will create the iCloud store. Subsequent apps will see this has been done and read the changes from those mysterious log files.

     
  • Jay Versluis 1:33 pm on July 22, 2014 Permalink | Reply
    Tags: , restore,   

    Completing an iCloud Restore when it’s stuck on apps deployed from Xcode 

    Screen Shot 2014-07-22 at 13.30.25

    When you update a device with a new iOS Version (beta or not) and restore an iCloud Backup, said backup gets stuck while trying to bring back your own apps that you have deployed with Xcode. The iCloud backup is only saving your app’s data, but not the actual bundle. The idea is that iCloud can bring those back from the App Store.

    This means that apps you’ve deployed from Xcode, say as test apps or those still in development, are not on the App Store and hence cannot be brought back. When iCloud restores, it tries really hard – and as a result gets stuck in an endless loop.

    The implication is that you cannot deploy a new iOS version over the air when this happens – because the previous restore needs to finish first before applying the new one. However, getting rid of those non-existent apps is impossible – because the standard “tap wiggle and press x” method doesn’t work. Neither does any of the other methods. This leaves us developers stuck with darkened icons like these and a never ending restore loop:

    Screen Shot 2014-07-22 at 13.31.00

    How do we fix’er, Cap’m?

    You can deal with this in several ways:

    Option 1: deploy the new iOS Version via iTunes and do not restore an iCloud backup. This however leaves you with lost data and is probably only good as a last resort, of if you don’t care about existing data.

    Alternatively you can restore an iCloud backup, but you’ll be stuck in the restore loop again – albeit with a new version of iOS.

    Option 2: re-deploy your old apps from Xcode to the device so the restore can finish. As soon as the last app is installed, the new iOS Version can be applied over the air.

    If you no longer have access to the old apps fear not: as long as you can remember the Bundle ID, just create a new dummy app with said Bundle ID and deploy that – it’ll make the app on the device “deletable” again. iCloud doesn’t care and will finish the restore.

    Note that you must bring back every old app and get rid of any dark icon you have on your springboard for this to work.

    Screen Shot 2014-07-22 at 13.31.11

    What if I don’t remember the Bundle ID’s?

    That’ll be a problem… You’ll have to guess. Usually when you deploy something with a title like “Test App”, then spaces in your Bundle ID will be replaced with a dash (as in com.yourdomain.Test-App). Capitalisation is important here: com.yourdomain.Test-App is seen as a different app than com.yourdomain.test-app.

    If you’re not sure about the title of your “dark apps” (because usually it says “Waiting” during the restore attempt), try to hold one down, then press the x as if you’re deleting them. The deletion will silently fail, but the standard iOS Alert View will be displayed asking if you’re sure – and in doing so will display the title of this app.

     
  • Jay Versluis 9:41 am on July 21, 2014 Permalink | Reply  

    How to test if your app needs an upgrade 

    Screen Shot 2014-07-21 at 09.37.32

    Sometimes you want to implement a new feature in your latest release which relies on an existing feature to be amended in some way. For example, you’ve added iCloud functionality to your app and now you need to upgrade the store file.

    It’s important that such internal upgrade routines only run once when necessary and not every time your user launches the app. The simplest way to do this is to set a user default value after the migration, and test if it exists on every run of your app. If it does, the migration is not necessary. If it does not, we haven’t upgraded the app yet.

    Here’s a quick example of how you can implement this. I’m doing this in the AppDelegate’s didFinishLaunchingWithOptions method:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        // check if an upgrade is necessary
        if (![[NSUserDefaults standardUserDefaults]boolForKey:@"didWeUpgrade"]) {
            
            // let's upgrade
            [self upgradeApp];
            
            // and remember for next time
            [[NSUserDefaults standardUserDefaults]setBool:YES forKey:@"didWeUpgrade"];
            [[NSUserDefaults standardUserDefaults]synchronize];
        }
        
        return YES;
    }
    
    #pragma mark - Upgrade Checks
    
    - (void)upgradeApp {
        
        // add your upgrade code here
        NSLog(@"Just upgraded your app. On the next run, this does not happen again.");
    }
    

    Be wise with the choice of your naming conventions for BOOLs and methods and make a note of which version of your app needed this upgrade. For example, add something like “upgraded Core Data with new string values as of version 1.3″.

    I’m saying this because you may need to upgrade again with another feature in the future, and you don’t want to confuse yourself, or run the old upgrade routine again in error. Just thought I’d mention it – you’ll thank me later ;-)

    Here’s a quick demo project on GitHub:

     
    • amitsbajaj 2:10 pm on July 21, 2014 Permalink | Reply

      Thanks Jay for creating this and this is really perfect! :) I’m so sorry for yet another question.. I know I’m so close now!..

      So in my scenario:

      App Store version with data (no iCloud)
      Update to iCloud version
      Data migrates to iCloud
      Other devices pick up data *
      Run the app again and it doesn’t use the new “migrated” store **

      Starting with **, when I run the app again, because the user defaults not is true (i.e. it exists), it doesn’t go to the upgrade method, which makes sense, but the logging in the console now doesn’t reflect iCloud usage at all and it looks like it’s reverting back to using the local storage. So my question is, when I migrate to use the iCloud store the first time the app is run, how do I set it so that the app always uses that store instead of reverting back to the local store when iCloud is available, and the account is the same?

      I’ll ask this separately without wanting to confuse too many things!

      Thanks again Jay!

      • Jay 3:48 pm on July 21, 2014 Permalink | Reply

        No problem at all! Without seeing your code, my hunch is that the puzzle lies in the custom initialiser for the persistent store coordinator. That’s where you setup the store file, and that’s where you’ll either use iCloud with Core Data or not. Therefore, you need to find a way to “fork” the initialiser with a similar if/then statement as in the example above.

        So if the app has been upgraded, and now runs again, the initialiser needs to setup the persistent store coordinator with iCloud. If not, it needs to be set as it always has been.

        The easiest way to do this is to setup the options dictionary differently. Something like this:

        - (NSPersistentStoreCoordinator *)persistentStoreCoordinator
        {
            if (_persistentStoreCoordinator != nil) {
                return _persistentStoreCoordinator;
            }
            
            NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Upgrade.sqlite"];
            NSError *error = nil;
            
            // get a reference to your iCloud URL
            NSURL *cloudURL = [self grabCloudPath:@"iCloud"];
            
            // setup options depending on migration
            NSDictionary *options = nil;
            if ([[NSUserDefaults standardUserDefaults]boolForKey:@"didWeUpgrade"]) {
                options = @{NSPersistentStoreUbiquitousContentURLKey: cloudURL};
            }
            
            _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
            if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
        
                NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
                abort();
            }    
            
            return _persistentStoreCoordinator;
        }
        

        Let me know if that works for you (and if it makes sense).

    • amitsbajaj 5:07 pm on July 21, 2014 Permalink | Reply

      Thanks once again Jay! An amazing help. I thought after I wrote it that it’s a bit hard without code and I was putting something together when your answer came through and that worked like a charm. The forked if-else statement worked perfectly in the persistentStoreCoordinator, like you have in the snippet you posted.

      So the if is evaluating if the userDefaults does exist and it contains the iCloud options and else evaluates without userDefaults and it contains the non-icloud options. It works like a charm because when the second device is connected in, it shows there’s no user defaults and it migrates the data successfully, but the next time it’s run, it works like a charm showing that userDefaults does exist and therefore to use the iCloud options.

      Honestly, you’ve managed to in one day, help me out with issues I’ve been having for quite some time!

      Thanks so much for this – I really appreciate it :)

      • Jay 5:31 pm on July 21, 2014 Permalink | Reply

        I’m so glad it helped you! I know what it’s like – these things can drive you crazy. And I honestly thing that Apple could have made it all a little less complicated… Good luck with the app!

  • Jay Versluis 12:33 pm on July 13, 2014 Permalink | Reply
    Tags:   

    How to fix a Region Mismatch on your Apple ID 

    Screen Shot 2014-07-13 at 12.09.00I have two Apple ID’s: one for the UK and one for the US. It’s not a problem for an iOS device two switch between store regions, even though it’s an annoying user experience. It should happen automatically.

    However, I had a problem several times now whereby my UK account shows my US billing address – and even asks me to verify my payment details. Trouble is, the UK account shows my US billing address – something I’ve never setup, and hence it’s impossible to verify my credit card due to the region mismatch.

    Most Apple Support staff are clueless when you bring this problem up, because “it’s impossible for our system to do that”. I know it’s a strange one, so here’s some proof from iTunes:

    AppStoreRegionMismatch

    Before I forget how to fix this again, let me tell you HOW this problem came to be:

    Unbeknownst to me I had added the email address of my US account as an alternative email address to my UK account. The App Store really doesn’t like this, and hence mixes up the addresses – particularly because my UK account no longer has a credit card on file.

    How to fix the Region Mismatch Nightmare

    A very nice gentleman from Apple named Melvin had the solution – he suggested the following:

    • login to https://appleid.apple.com using the account that needs fixing
    • select your language at the bottom right if needed
    • click “Addresses” and remove outdated ones
    • edit the single remaining Address and change it to the desired region and country
    • edit your Phone Number (doesn’t have to match the region – I added a US phone number to my UK account, just make sure you add the correct country code)
    • hit save and log out

    This will fix the problem. It’s probably best to remove alternate email addresses that are associated with other accounts, otherwise this problem will come back to haunt you (under Name, ID and Email Addresses).

    When you first log in here, you may be prompted to change your password to a more up-to-date one. Mine for example did not begin with a capital letter, and Apple no longer allow such passwords.

    Back on your iOS device

    If you now try to buy something from the App Store on your iOS device you may still be greeted with the verification dialogue, showing your (outdated) address and credit card information.

    Fix this by selecting “NONE” under credit card, tweak your phone number, and the verification will be successful.

    Another mystery solved!

     
c
Compose new post
j
Next post/Next comment
k
Previous post/Previous comment
r
Reply
e
Edit
o
Show/Hide comments
t
Go to top
l
Go to login
h
Show/Hide help
shift + esc
Cancel
Password Reset
Please enter your e-mail address. You will receive a new password via e-mail.