Container View Controllers in Swift

If you are using a ‘Container View’ in Xcode’s storyboards it’s likely that you want to get a handle to the view controller you create inside the container view. Surprisingly, there isn’t an obvious way to do this. However, you can use the ’embed segue’ to find the handle to the container views because when the container view is added the embed segue is called. So when you create the container view give the embed segue a unique identifier and then you can grab the handle to your view controller in the prepareForSegue method as follows…

var myController: MyController?
var myOtherController: OtherController?

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    guard let ident = segue.identifier else {
        return
    }
    switch ident {
    case "MyEmbedSegueIdentifier":
        myController = segue.destinationViewController as? MyController
    case "MyOtherEmbedSegueIdentifier":
        myOtherController = segue.destinationViewController as? OtherController
    default:
        break
    }
}

Stripping print and debugPrint in Swift for release builds

When building an app for release with Swift you should make sure that any of the print and debugPrint statements you used when building and debugging the app are disabled.  The reason for this is that if you leave them in then they will unnecessarily slow down the app since every write to console output takes time.

In Swift you can easily do this by redeclaring the print and debugPrint functions using these two lines of code…

func debugPrint(items: Any..., separator: String = " ", terminator: String = "\n") {}

func print(items: Any..., separator: String = " ", terminator: String = "\n") {}

We simply declare the functions again but with empty implementations of {}.  When you’re building and testing your app just comment these two lines, but when complete make sure you uncomment them before release.

You should place these two lines at the top-level of your code.  That means, do not put it inside a class, extension or protocol declaration.  A good place to put them is at the top of your AppDelegate file, before the AppDelegate class and not inside it.

Alternatively, simply create a brand new Swift file in your project and call it something like ‘ReleasePrint.swift’ and put the code in there.  Basically, it can be anywhere as long as it is top-level and not inside another class.

Finally, you may find it useful to always see the output from print and debugPrint in the simulator, but never on the device.  If you want to do this you can use the architecture flags to automatically turn the output on and off as follows…

#if !arch(x86_64) && !arch(i386)

func debugPrint(items: Any..., separator: String = " ", terminator: String = "\n") {}
func print(items: Any..., separator: String = " ", terminator: String = "\n") {}

#endif

How to: Create a bootable installer for OS X El Capitan 10.11

With OS X El Capitan 10.11 you can create a bootable installer so that you can install using a USB device such as a USB flash drive or external USB hard drive.  Just follow these steps…

1) Download the OS X El Capitan 10.11 installer from the Mac App Store but once its on your machine and opens up make sure you DO NOT click install.  If you click install then the install will take place and the installer application will automatically be deleted afterwards.  So you don’t want that if you want to have the installer on a handy USB device, so just download it but don’t install.

2) Insert your USB device and use Disk Utility to format it (this will obviously erase everything on the USB device so make sure you’ve copied anything you need off it beforehand).  Name the drive ‘OSXInstall’ (without the quotes).  Note that the installer needs at least 7GB free space so your USB device will need to be at least that size.

3) Open Terminal.app and run the following command…

sudo /Applications/Install\ OS\ X\ El\ Capitan.app/Contents/Resources/createinstallmedia --volume /Volumes/OSXInstall --applicationpath /Applications/Install\ OS\ X\ El\ Capitan.app --nointeraction

Because you are using sudo you will be asked for your password before the command starts running so make sure you type in your password and press return to start the process.

4) You’ll see some output in Terminal letting you know it’s copying files.  The bit that takes the longest is the one that says ‘Copying installer files to disk’ and it can take 10 minutes or longer depending on the speed of your USB device so be prepared for a bit of a wait at that point.

 

When that’s done your USB will be ready with the bootable installer. It will also have been automatically renamed to ‘Install OS X El Capitan’.  You can now use it as a bootable USB installer on any Mac.

Ad Blocking in iOS 9

In iOS 9 Apple have made it possible for developers to create content blockers for Safari, which means we can finally create ad blockers for our iPhones and iPads. In my spare time I’ve been experimenting with this and created a simple ad and tracker blocker.

Now that it’s pretty much complete I’ve been running it on my own devices, and by using the web inspector I can get detailed page load times when browsing. I expected an improvement, but I’ve got to say that I am blown away by the difference this ad blocker makes to load times. With the blocker enabled I’m getting about 3 to 4 times faster loading than without. In some cases I’m getting almost 9 times faster loading! I can’t believe that for years we could all have been getting these speeds on our mobiles if sites just hadn’t put so many adverts and trackers into their pages.

Here’s a comparison of some of the load times I see on Safari in iOS 9 with and without the content blocker enabled. In all cases, the lower number is with the blocker enabled 🙂

macrumors.com = 1.26s, 5.4s
arstechnica.co.uk = 1.66s, 2.69s
mobile.nytimes.com = 2.38s, 3.63s
reddit.com = 839ms, 1.06s
uk.ign.com = 974ms, 3.04s
engadget.com = 2.88s, 6.63s
iphone.appleinsider.com = 1.21s, 3.6s
dailymail.com = 1.02s, 9.64s

Amazing right? The difference this makes is far, far more than any year-on-year hardware upgrade we could have got. This is better than going from say 3G to LTE/4G. Browsing feels soooooo much better and more responsive. I’m retrospectively angry now that I know sites have been so much slower than they could have been, but I am really happy we now have a way to fix this.

I’m going to release this content blocker and I hope people like it, but regardless of whether you use mine or another one, I can not recommend enough that everyone who uses iOS gets and installs some ad blocker once iOS 9 is publicly released. Believe me, your browsing experience will be a whole level better once you do.

Apple Sept 9th, 2014 Event Predictions

Here are my predictions for todays event…

Two new iPhones, 4.7″ and 5.5”. They will both be shipping 1-2 weeks after the event. They will have a new A8 SoC and M8 motion chip. They will, unfortunately, most likely still have 1GB RAM. Better camera, better speakers, better battery (particularly on the 5.5”). Both phones will act more like iPads than the current iPhones… for example, when you rotate to horizontal in Mail.app you’ll get the split view that shows the inbox and the email at the same time. They will have NFC and Apple will announce payment partnerships with VISA, Mastercard, etc. Since a dude from the PassBook team said about 6 months ago that there were major new additions coming in iOS8 that would make PassBook way more frequently used I’m pretty sure the payment stuff will be put into that app.

The big three-story structure that Apple is building directly across from the conference hall is a fake house kitted out with HomeKit stuff so that Apple can demo that properly. This seems obvious to me after seeing a similar, much smaller, setup from Qualcomm at MWC. I’ll be really surprised if it isn’t this.

New iPads will be announced and will ship 1-2 weeks after event. Will have Touch ID and same as the iPhones will have A8, M8 chips.

The current 5s will move down to replace the 5c. They won’t bother wrapping it in plastic like they did to differentiate the 5c since it’s smaller size will differentiate it from the new phones anyway. The 5c will be discontinued so that they have Touch ID right across their iPhone and iPad lines.

There will be a watch announced on the 9th, but it won’t be shipping until January. This is so that it can go through all the FCC regulations and because Apple couldn’t meet holiday demand on a new product category. The watch won’t work on it’s own, or will be almost useless. It will be designed as an addition to an iPhone and/or Mac. It will show notifications and support quick responses to things like messages and calls. It will provide an audio link back to your iPhone so that you can do things like use Siri with it. It will track health stuff like steps, temperature, GSR, heart rate. If you forget your phone and start to walk away without it the watch will alert you. It will be able to act as remote for the current Apple TVs and for HomeKit stuff. Basically, Apple will be massively increasing device-to-device integration with all new and old products.

iOS 8 GM will be released immediately after the event. It will go public the same time as the two new phones ship, 1-2 weeks later.

Yosemite won’t be released at the same time as iOS 8. It will come out about a month later. Might seem weird because you need both to get all the handoff features, but they did a similar thing when they released iCloud Keychain with iOS 7 being out a bit before Mavericks, and I def think Yosemite is behind iOS 8 currently as far as stability goes.

There will be a Jony Ive video with him talking about the design and manufacturing of the new watch.

Immediately after the event everyone will say the watch and HomeKit stuff is terrible and that Tim Cook’s Apple can’t innovate, and then the stock price will plummet until after the sales figures for the new iPhones and watch start coming in and people see they are selling like crazy, then the stock will go up very, very slowly.

WiFiFoFum Intrepid

I’ve been working on a new version of WiFiFoFum with Malc.  The codename we’ve used for the project is Intrepid, and it’s basically a complete rewrite of the WFFF codebase to get it compatible with iOS 7.

As many of you will know, WFFF for iOS has languished for some time due to Apple’s policies around Wi-Fi scanning.  Years ago WFFF was kicked out of the official App Store and we subsequently put it in Cydia.  Although it found an audience in Cydia, it got harder and harder to develop the app when Apple were not only denying us access to the iTunes Store distribution channel, but also seemed to be doing everything they could to block developers from accessing the Wi-Fi functions in iOS devices.

Dynamically Loaded felt it was time to try to push the boundaries again and, thanks to some simply stunning and ground-breaking work from Malc, he and I have created a version of WFFF that works wonderfully on standard iOS 7 devices… no jailbreak required!

I’m particularly proud of Intrepid.  A decade ago Malc and I were the first to figure out Wi-Fi scanning on Windows Mobile devices, and released WFFF as the world’s first widely available, mobile wireless scanner.  Half a decade ago we were the first to discover how to achieve Wi-Fi scanning on the iPhone, which led to the first iOS version of WFFF.  When Apple changed the Wi-Fi frameworks a couple of years later we again were the first to discover how to scan using new techniques.  Finally, when Apple completely removed Wi-Fi access via the iOS frameworks, even when using the hidden techniques we had discovered, I thought we’d never again be able to provide Wi-Fi scanning on jailed iOS devices.  However, with Intrepid we’ve done it, and I can’t wait to release it publicly and make the world’s best Wi-Fi scanner available to all iOS devices once more.

Our new scanning methods do not break ANY of the iTunes App Store rules so we will be submitting it to Apple and hope to have WiFiFoFum Intrepid available through the official store.  However, there are never any guarantees with Apple, so if for any reason they do not allow it into the store we will be making it available directly through the Dynamically Loaded site.

Intrepid will be ready for release soon, but in the meantime here are some screenshots of it running on my own jailed iPhone 5.

Network Utility in OS X 10.9 Mavericks

In OS X 10.9 Mavericks the very useful Network Utility app has been moved from its previous location in /Applications/Utilities to /System/Library/CoreServices/Applications. You can activate it by navigating to that folder and simply opening it as normal.

There is also another way to activate Network Utility. Simply open up the ‘System Information’ app, which can still be found in Applications/Utilities, then in the menus at the top of the screen open up the ‘Window’ menu and select ‘Network Utility’.

mavnetutil

How to: Create a bootable installation for OS X Mavericks 10.9 and above

UPDATE: With the release version of OS X Mavericks there is now a much easier way to create a bootable installer. Simply follow these steps.

1) Download Mavericks from the Mac App Store but do not click install. If you install then after it upgrades your machine the installer will be automatically deleted.

2) Insert a USB flash drive and use Disk Utility to format it, name it ‘Untitled’. The installer takes over 4GB so you’ll need at least an 8GB drive.

3) Open terminal and run the following command…

sudo /Applications/Install\ OS\ X\ Mavericks.app/Contents/Resources/createinstallmedia --volume /Volumes/Untitled --applicationpath /Applications/Install\ OS\ X\ Mavericks.app --nointeraction

4) You’ll see some output in Terminal letting you know it’s copying files. When that’s done your USB will be ready with the bootable installer.

iOS 7 thoughts

I am both excited and scared about the upcoming iOS 7 release.  Excited because it’s a chance for Apple to introduce many new and innovative features, and scared that if Apple don’t do this then we could see iOS sales really struggle for the next cycle.

iOS 6 was a relatively small update over iOS 5.  Whilst iOS 5 brought us some hefty new features like iCloud and Siri, iOS 6 brought much smaller improvements, and its main novel feature was the change from Google to Apple for Maps.app, which suffered some serious issues at launch.

If Apple follows its typical timeline for major iOS updates then it’s likely we’ll see the first developer previews of the next major update, iOS 7, in the next couple of months.  Given the increased competition Apple is seeing from the latest versions of Android, I believe iOS 7 has to be a significant upgrade with many new features. Apple have let iOS somewhat stagnate over the last few years, and they have to address that now.

When Steve Jobs first showed the iPhone he boldly stated it was 5 years ahead of the competition.  It’s been over 5 years since its release now, the competition has caught up, and Apple have to innovate with this update.  The new hardware this year will be incremental updates, with the iPhone 5S, a retina iPad mini, and minor form factor changes to the full-size iPad.  So, this is an ideal year for Apple to focus on their mobile software.  With a major change in iOS management, the departure of Scott Forstall, there must surely be momentum for not only a substantial software update, but room for a change in the ethos of iOS.

I expect to see a lot of major changes, and I have an extensive wishlist of improvements and new features that would take pages to write out, but what follows is a condensed list of what I think are reasonable guesses for what we could potentially see in iOS 7.

Integration

For a long time Apple has boasted of not just the ease-of-use of their devices, but of easy integration between devices.  In iOS, there is a great deal that could be improved in this area.  For example, many of us now own both an iPhone, an iPad and a Mac, or some combination of these.  However, when a call comes in on an iPhone, there is absolutely no notification of it on the iPad or Mac.  For me, this is often frustrating.  Sometimes whilst at home I leave the phone in one room whilst I’m on the iPad or Mac in another.  When my phone rings in the other room I don’t hear it, and even although I’m holding my iPad or have my laptop on my lap there is no notification to tell me who is calling.  By simply having the iPhone send a push notification to your other devices in this situation you would never unintentionally miss a call.

A slightly different, but annoying, behaviour occurs just now with FaceTime calls.  When I receive a FaceTime call all my devices ring, which is great.  However, if I answer the call on my iPhone then later on when I pick up my iPad it still has a notification that says one missed call.  However, the call wasn’t missed, I did answer it on my iPhone.

There’s so much more that could be done with improving device-to-device integration in iOS, but I think these are two good, basic examples of where some improvement could be easily implemented.

Remote

I am confident Apple is going to release a full television product, and when they do I think iOS devices should integrate with it to be a remote and a second screen.  I would expect iOS 7 to either have this functionality, or at least the seeds of it.  iOS devices should be able to perform as a remote and/or second screen for Apple TVs in a much more functional manner than they currently do.  For example, when viewing a movie on an Apple TV the iOS device should not just allow you to perform the standard remote controls such as play, pause, forward, rewind.  The device should also show additional useful information and functions.  For example, information about the movie, genre, actors, social functions where you can comment on the movie and participate in discussion.

Quick Access to Settings

I frequently use the Do Not Disturb feature that iOS 6 introduced to silent my phone.  However, accessing the setting that turns this on and off is slow and frustrating, primarily because I first have to find the Settings app.  Similarly, turning Wi-Fi on and off is slow.  Indeed, it is worse as it isn’t at the root level in the Settings app so you have to go into the Wi-Fi section to find the on/off toggle.  Commonly changed settings such as Do Not Disturb, Wi-Fi and Bluetooth power should be easily accessible from the Notification Centre pulldown.

Multitasking Improvements

I’m not sure about this one, as Apple has invested a lot of time and effort in creating a backgrounding system based on apps requesting the right to run in the background as they get location updates or play audio.  However, there are so many reasons for apps to run in the background that Apple have failed to anticipate and have been added in an ad hoc manner over the years that I think it’s time they just gave up and let apps run in the background if they like.  They could still require that users have to give permission for apps to do this, but instead of trying to section backgrounding into location, audio, VoIP the app could simply ask for background permission, which would allow apps to get the right to execute in the background for any reason, rather than just the ones Apple are able to think of right now.  A good example of a reason to run in the background that Apple hasn’t anticipated is to monitor the accelerometer.  I’ve tried to get an app to do this to track user activity levels for a fitness app, but since when it comes to movement Apple only anticipated the need for location backgrounding, an app that wants to track activity simply can’t run in the background (unless it also requests permission for another reason that is sanctioned by Apple, such as location).

Open Up the System

The jailbreak community is still thriving.  Just 24 hours after the release of the Evasi0n jailbreak there were over 1 million people who had used it.  Whilst I don’t normally have my own iOS devices jailbroken, there is a clear demand for it.  Although having iOS tightly locked down initially benefited Apple as they first began releasing iPhones, it’s time they opened up access to the device and OS more for developers.

Android is relatively open, and this allows developers to provide many novel and exciting apps that just aren’t possible in iOS.  Apple have already implemented a solution in OS X where users can decide to allow apps from the Mac App Store only, developer-signed apps, or any apps.  iOS should have the same settings in order to allow users to feel absolutely secure in using iOS Store Apps, whilst at the same time allowing them to experiment with the bleeding edge apps if they so desire.

Readster

I’ve just released a new RSS app called Readster.  I designed and created it with Malc.  We spent a long time thinking about how best to display news in a beautiful yet intuitive way, and I really think we achieved it.  As part of the app I also created a full-screen in app web browser mode, similar to Safari in iOS 6.  Pretty pleased with the way this app turned out.  If you are interested you can grab it by clicking here.