Here's a Live Template to generate a common delegate pattern in AppCode, JetBrain's Objective-C IDE.
Saturday, 21 April 2012
AppCode Delegate Pattern Live Template
Thursday, 19 April 2012
Script to automatically create retina and non-retina versions of images
I often get sets of files from graphic designers for iOS apps. Ensuring that the standard and @2x versions of all the files are present and correct is a bit of a pain, for the artist and for myself. The number of times there's been a mispelling in one of the images has been.. well .. many.
Instead I now ask them to send only the retina versions of the images, without the @2x tag in the filename (this has caused confusion).
I then run this script on the whole folder of files, and out pops a folder containing all the files properly renamed and resized. I use the incredible useful 'sips' command-line application that comes with OSX.
The fiddly bit of this script was working out the new size of non-retina images. Yes, they're half the size, but sips doesn't support percentages.
Credit to (person on superuser.com who I'll find eventually) for the neat sed command to extract the pixel size from the output of sips.
Note: clearly the file extension part can be done better. But it works for me right now.
Instead I now ask them to send only the retina versions of the images, without the @2x tag in the filename (this has caused confusion).
I then run this script on the whole folder of files, and out pops a folder containing all the files properly renamed and resized. I use the incredible useful 'sips' command-line application that comes with OSX.
The fiddly bit of this script was working out the new size of non-retina images. Yes, they're half the size, but sips doesn't support percentages.
Credit to (person on superuser.com who I'll find eventually) for the neat sed command to extract the pixel size from the output of sips.
Note: clearly the file extension part can be done better. But it works for me right now.
Thursday, 5 April 2012
Get version number of live app on App Store in Phonegap app
A nice feature you might want to add to your iOS app is to notify the user when a new version is available on the App Store. Of course the user can go to the App Store manually and install the update, but we've noticed quite a few users don't do this very often. Some carefully-judged prompting is bound to help.
It turns out there's an API that Apple run that can return, in a handy JSON or JSONP format, the metadata for a particular app on the app store. This includes both the version number of the app, and even better, the 'what's new in this version' text.
You can use this information on your app's startup to check if a new version is available, and tell the user what's in it, and then finally, link them to the update page for the app.
Here's some bare-bones bits of example code to get you going. You'll need to know your app's Apple ID (e.g. 387022138). You can find this in the iTunes Connect interface). I'm also assuming that you're using jQuery or Zepto in your app.
The below also works in the browser.
// Alert the version number and release notes of an app.
$.ajax({
url:"http://itunes.apple.com/lookup?id=<APPLE ID HERE>&callback=?",
success:function(data) {
if (data && data.results && data.results.length) {
alert(data.results[0].version);
alert(data.results[0].releaseNotes);
}
}
});
Here's the full list of data you might want to use:
To open iTunes looking at your App's update page open the following URL:
itms-apps://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftwareUpdate?id=<APPLE ID HERE>&mt=8
It turns out there's an API that Apple run that can return, in a handy JSON or JSONP format, the metadata for a particular app on the app store. This includes both the version number of the app, and even better, the 'what's new in this version' text.
You can use this information on your app's startup to check if a new version is available, and tell the user what's in it, and then finally, link them to the update page for the app.
Here's some bare-bones bits of example code to get you going. You'll need to know your app's Apple ID (e.g. 387022138). You can find this in the iTunes Connect interface). I'm also assuming that you're using jQuery or Zepto in your app.
The below also works in the browser.
// Alert the version number and release notes of an app.
$.ajax({
url:"http://itunes.apple.com/lookup?id=<APPLE ID HERE>&callback=?",
success:function(data) {
if (data && data.results && data.results.length) {
alert(data.results[0].version);
alert(data.results[0].releaseNotes);
}
}
});
Here's the full list of data you might want to use:
![]() |
| Screengrab showing properties of the response from the API call. Click to view full size. |
To open iTunes looking at your App's update page open the following URL:
itms-apps://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftwareUpdate?id=<APPLE ID HERE>&mt=8
Tuesday, 28 February 2012
How to link to unreleased App Store apps
For a client I'm making an app that comes in 'full' and 'lite' versions. The client wanted to have a button in the lite version that opens the full version in the App Store on the device. Now this was a little bit tricky because both the full and lite versions were in progress and hadn't been released yet. They didn't even have names.. I needed to release both apps at the same time so testing the link worked seemed impossible.
The solution was to have the 'upgrade' button link to simply open an html page on a site I own in Safari on the device. Doing this meant I could alter what the link actually did at any time.
Once the client had set up the apps in iTune Connect, I asked for the Apple ID of the full version of the apps (shown in iTunes connect on the App Info Page).
I then updated the HTML page that was opened by the app to contain the following (replacing the 123456789 with the real app ID of course).
<script type="text/javascript">
window.location = "itms-apps://itunes.apple.com/app/id123456789?mt=8"
</script>
Now when that button is pressed, Safari flashes up briefly (but doesn't actually display the page) and then the App Store app opens and displays the app. Voila!
Ah, I hear you say. Can't I just use the app name rather than the Apple ID? Well, yes you can. Here's a load of different ways of linking to apps on the app store.
For me though, these options weren't so good as my solution because:
- There a fairly fiddly way the actual name is converted to a url-friendly name. Easy to get wrong.
- My app names weren't finalized at the time of writing anyway.
- If the client changes the name of the app, the link will break.
Friday, 2 December 2011
Vertically Centering Multi-Line text in CSS
There are many, many blog posts on this subject already, but I've struggled to get many of the methods to work so I'm saving this for posterity.
<div class="label">
<div class="label-inner">
foobar<br>baz
</div>
</div>
.label {
display: table;
width: 300px;
height: 200px;
border: 1px solid black;
}
.label-inner {
display: table-cell;
vertical-align: middle;
text-align: center;
}
Result
Wednesday, 16 November 2011
Android Phonegap :active CSS pseudo class doesn't work. A workaround..
If you're building a cross-platform Phonegap app, you may well run in to the issue that your CSS :active pseudo-classes simply don't work when running on Android. They may work on your a (link) elements, but not on div or others.
Luckily there's a simple workaround. This workaround will continue using the fast, native, JavaScript-free :active class on iOS, and drops back to using the JavaScript on Android.
Note that you can use the $(".my-button, .my-other-element, .even-more-elements") jQuery syntax to bind the events to other classes too.
Luckily there's a simple workaround. This workaround will continue using the fast, native, JavaScript-free :active class on iOS, and drops back to using the JavaScript on Android.
- First, in your CSS, find every instance of the :active class. Add another rule that maps a class called fake-active to the same style.
E.g.
.my-button:active {
background-color: blue;
}
Becomes:
my-button:active, .my-button.fake-active {
background-color: blue;
}
- Now, in your document ready event, when running on Android only, attach event handlers for touchstart and touchend to all the classes that have used :active. Make these add and remove the fake-active class.
if (navigator.userAgent.toLowerCase().indexOf("android") > -1) {
$(".my-button")
.bind("touchstart", function () {
$(this).addClass("fake-active");
})
.bind("touchend", function() {
$(this).removeClass("fake-active");
});
.bind("touchcancel", function() {
// sometimes Android fires a touchcancel event rather than a touchend. Handle this too.
$(this).removeClass("fake-active");
});
}
Note that you can use the $(".my-button, .my-other-element, .even-more-elements") jQuery syntax to bind the events to other classes too.
Thursday, 10 November 2011
Edit AndroidManifest.xml in Android Phonegap Build App
Phonegap build is an awesome service that allows you to convert a bunch of HTML files into actual mobile apps for iPhone, Android, Blackberry, and more. It's great, so great in fact that Adobe recently bought the company behind it (Nitobi).
You can read more about the details at their site, I won't repeat it all here.
I've been playing around with the Android version of this for a client project I've been working on, and came up with a bit of a problem. There's a file called AndroidManifest.xml that every Android app includes that sets up loads of important stuff such as the intent filters and the permissions needed to run the app.
Phonegap build allows you to change some of these settings using it's config.xml system. But for other settings you are, it seems, stuck. I needed to change the intent filter for one of my activities, and there was no way that the config.xml could do this. I posted on their forums and the very helpful guy said they may add the feature in a future release.
In the meantime though, I found another way.
It's possible to decompile the apk file that you download from Phonegap Build, change the AndroidManifest.xml file, re-compile, re-sign, and install it onto your device.
Getting the tools we need
I'm assuming that you have the Android SDK installed, if not install it and follow the instructions to put the build tools into your path.
First you need to download apktool. This great tool allows you to decode and re-encode apk files. Download it and follow the instructions to install for your platform.
We're also going to use:
Re-building the APK file
If you try to install the new apk file you'll find that it fails with an invalid certificate error.
This is because apktool doesn't re-sign the apk. It's pretty easy to re-sign the APK with the development certificate (which is what Eclipse uses when making APKs for testing).
Here's how:
Your APK is now ready for installation!
You can read more about the details at their site, I won't repeat it all here.
I've been playing around with the Android version of this for a client project I've been working on, and came up with a bit of a problem. There's a file called AndroidManifest.xml that every Android app includes that sets up loads of important stuff such as the intent filters and the permissions needed to run the app.
Phonegap build allows you to change some of these settings using it's config.xml system. But for other settings you are, it seems, stuck. I needed to change the intent filter for one of my activities, and there was no way that the config.xml could do this. I posted on their forums and the very helpful guy said they may add the feature in a future release.
In the meantime though, I found another way.
It's possible to decompile the apk file that you download from Phonegap Build, change the AndroidManifest.xml file, re-compile, re-sign, and install it onto your device.
Getting the tools we need
I'm assuming that you have the Android SDK installed, if not install it and follow the instructions to put the build tools into your path.
First you need to download apktool. This great tool allows you to decode and re-encode apk files. Download it and follow the instructions to install for your platform.
We're also going to use:
- jarsigner - part of the Java JVN (I have a binary at /usr/bin/jarsigner)
- adb - part of the Android SDK installation (my binary is at ~/android/android-sdk-mac_x86/platform-tools/adb)
Extracting the APK file
- Download the apk file for your app from Phonegap build.
- Open up the terminal and type (substituting your folders for path/to and filenames where appropriate)
apktool d path/to/yourApp.apk path/to/output-folder
- This will extract the contents of the app into the folder output-folder.
- The AndroidManifest.xml file will be at the root of that folder.
Re-building the APK file
- Once you've finished making your changes, you can rebuild the APK file from the contents of the output-folder
apktool b path/to/output-folder path/to/yourAppV2.apkRe-signing the APK
If you try to install the new apk file you'll find that it fails with an invalid certificate error.
This is because apktool doesn't re-sign the apk. It's pretty easy to re-sign the APK with the development certificate (which is what Eclipse uses when making APKs for testing).
Here's how:
By default the development certificate is in the ~/.android folder. When you run this, it'll ask for a passphrase - use android.jarsigner -verbose -keystore ~/.android/debug.keystore path/to/yourAppV2.apk androiddebugkey
Your APK is now ready for installation!
adb install path/to/yourAppV2.apk
Subscribe to:
Posts (Atom)

