Archives

All posts by mike

Detective 1.1 is now available. This was a major rewrite to support Twitter’s 1.1 API and handle changes to Twitter’s authorization. Rather than asking you to log in to Twitter with a login window, it will now ask your permission to use your Mac’s Twitter accounts.

To celebrate the release, it’s now 50% off (0.99) through the end of WWDC on June 15.

For more information, visit the Detective page or download it here.

Detective is 50% off – only $0.99 – until Jan. 5!

Detective 1.0.3 is now available. It fixes some rendering bugs in Mountain Lion & a problem that sometimes caused it to stop updating when the Mac wakes from sleep. Version 1.0.3 runs only in Mountain Lion and uses notification center instead of Growl.

The next update will restore support for Growl & older versions of Mac OS X.

I’ve decided to open source PicSlide, which was one of my first iOS games. It isn’t selling enough to make it worthwhile updating for the iPhone 5. When I looked at the code I didn’t find it too embarrassing and it didn’t make me want to vomit, despite being written in 2009, so I decided to share it. Some pieces like scaling & slicing images and doing Quartz drawing may be helpful as sample code.

The source code is now available on Github at https://github.com/mike3k/picslide

Nexus 7

I’ve had a Nexus 7 for two weeks and there are lots of things I love about it and some things I really dislike.

Good:

  • I love the size. After using it, I really want a 7″ iPad.
  • I really like the universal back button at the bottom of the screen.
  • The soft home button moves to the correct position when you use it in landscape mode.
  • Rearranging icons is less annoying than in iOS.
  • Widgets can be placed on the home screen.

Not so good:

  • UI is ugly. No rounded corners, shadows, or gradients. Everything looks flat & square.
  • Endless march of notification icons across the top of the screen.
  • Many of my favorite apps aren’t available for Android. The only Twitter app I use is Echofon because it’s the only one that syncs my mute settings as well as unread tweets. It isn’t available on Android, which seriously limits my ability to use Twitter on the Nexus 7.

For a long time I dismissed the rumors of a 7″ iPad, but after using the Nexus 7 it makes perfect sense. A 7″ tablet is a lot more comfortable to use than a 10″ tablet, yet the amount of screen real estate is just as usable.

I’ve submitted a minor update to Sugar Rush which changes the FaceBook SDK to use the latest API so sharing will continue to work. It also adds support for built-in Twitter accounts in iOS 5 or later and updates the Kiip SDK to the latest version.

Sugar Rush Free gets a much bigger update. In addition to those SDK changes, I’ve renamed it to Sugar Rush Lite and added in-app purchase to get rid of the ads & height limit. You can also buy Donuts, which will make it functionally equivalent to Sugar Rush Pro. Both Sugar Rush Lite & Sugar Rush Pro now share the same Game Center leader board & achievements.

When I submitted an update to Detective, I discovered a few tricky things related to sandboxing and embedded helper apps.

In order to support ‘start at login’ in a sandboxed app, you need to embed a helper app that launches the main app (the entire process is described here). What I didn’t realize is that the helper app also has to be signed, or it will fail to let you start it at login. However, when you sign the helper app, it will include its own embedded provisioning profile, so when you try to submit your app, it will be rejected with the following message:

Invalid Provisioning Profile Location – The provisioning profile for your Mac OS X app must be located in the Contents directory of the main app bundle. A provisioning profile is optional, but you cannot submit more than one.

One of the suggestions in Apple’s developer forum is to remove the embedded profile from the helper app. Note that deleting the embedded profile doesn’t affect the actual code signing. After some experimentation, I found that the easiest way to do it is to add a Run Script build phase to the main application that deletes the profile from the helper app:

#!/bin/sh
rm ${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Contents/Library/LoginItems/DetectiveLoginHelper.app/Contents/embedded.provisionprofile

After doing this, I was able to submit the app successfully.

Apple will soon require all Mac apps submitted to the app store to be sandboxed for heightened security, which means it needs to request permission for doing even basic things like accessing files or connecting to the internet. A lot of things like disk burning aren’t allowed at all in the sandbox, and some things like sending AppleEvents require temporary exemptions which will be phased out.

One common task that’s complicated by the sandbox is adding a login item. A good tutorial on creating login items is available at delite studio, although some changes to the code are needed. That code follows Apple’s earlier guideline of using LSRegisterURL to register your helper app. However, I found that it always fails with error -10819. According to an Apple engineer in Apple’s developer forum, you should not call LSRegisterURL in a sandboxed app.

Note that your application can’t add itself as a login item. You need to write a simple helper app that launches your main app and it must be included in the main application bundle in the relative path /Contents/Library/LoginItems/.

The method for adding & removing a login item turned out to be very simple:

- (void)addLoginItem {
    NSString *ref = @"com.madebynotion.myLoginHelper";
	if (!SMLoginItemSetEnabled((CFStringRef)ref, true)) {
		NSLog(@"SMLoginItemSetEnabled failed.");
	}
}

- (void)removeLoginItem {
    NSString *ref = @"com.madebynotion.myLoginHelper";
	if (!SMLoginItemSetEnabled((CFStringRef)ref, false)) {
		NSLog(@"SMLoginItemSetEnabled failed.");
	}
}

If you need to find out whether your login item is enabled, here’s a way to do it:

-(BOOL)appIsPresentInLoginItems
{
    NSString *bundleID = @"com.madebynotion.myLoginHelper";
    NSArray * jobDicts = nil;
    jobDicts = (NSArray *)SMCopyAllJobDictionaries( kSMDomainUserLaunchd );
    // Note: Sandbox issue when using SMJobCopyDictionary()
    
    if ( (jobDicts != nil) && [jobDicts count] > 0 ) {
        
        BOOL bOnDemand = NO;
        
        for ( NSDictionary * job in jobDicts ) {
            
            if ( [bundleID isEqualToString:[job objectForKey:@"Label"]] ) {
                bOnDemand = [[job objectForKey:@"OnDemand"] boolValue];
                break;
            } 
        }
        
        CFRelease((CFDictionaryRef)jobDicts); jobDicts = nil;
        return bOnDemand;
        
    } 
    return NO;
}

Although this method works and seems to be the preferred way to do it in the sandbox, it’s less optimal than the old non-sandbox method, since your login item won’t appear in the users & groups preference panel’s login items list and can only be turned on & off from your own application.

Sugar Rush 1.2.5 and the new Christmas bonus pack is now available. The Christmas pack adds a new theme with new candies and high-scoring new bonus items. In addition, special bonus power items and premium items such as donuts will appear more frequently, making it easier than ever to get new high scores. Sugar Rush is still free. The Christmas pack is available as an in-app purchase for $0.99.

New Christmas theme.png