Swift Regex Deep Dive
iOS MacOur introductory guide to Swift Regex. Learn regular expressions in Swift including RegexBuilder examples and strongly-typed captures.
The release date for the long-awaited Apple Watch has not yet been announced, but the nerd herd here is hard at work learning how to program with WatchKit. We believe that the 4th beta of Xcode 6.2 is a rather stable version of what we should expect for the public release of iOS 8.2 and WatchKit early this year.
With the first beta release of WatchKit in November of last year, developers noticed concurrency issues between WatchKit Extensions and their hosting iOS counterparts, mainly due to a lack of ability to communicate between the two separate processes during runtime. And what if the hosting application was not running at all on the host device? This is a very likely scenario if users were to play around with their Apple Watch while their iPhone was asleep in their pocket. These issues presented serious challenges to providing a seamless user experience.
Previously-available solutions included:
With the release of Xcode 6.2 Beta 2, Apple added a method that would allow a WatchKit Extension to communicate back and forth with its host app. The new method, -openParentApplication:reply:
, allows the WatchKit app to wake its parent app and send it an NSDictionary.
The host app handles this request by implementing a new method in the app delegate, -application:handleWatchKitExtensionRequest:reply:
. Here, you have the option of sending a response NSDictionary
back to the WatchKit Extension.
This request-reply mechanism solves the problems we discussed earlier by allowing for simple communication between the WatchKit Extension and the hosting application.
Let’s take a look at a simple example of the power and benefits of these new methods. Here, we have an Apple Watch app that allows the user to select one of three words which rhyme with “at”: cat, hat and my coworker, Mat. The selected word will appear as an image in a WKInterfaceImage
(the WatchKit equivalent of a UIImageView
). You can download this sample project here.
Of course, if we are adding this WatchKit Extension to a fully fledged iOS app that already has image fetching methods, why rewrite those in our WatchKit Extension? What we can do is use our handy new -openParentApplication:reply:
method and pass in our desired image title in the NSDictionary
. Each of our buttons will pass its title as a string into our method below:
func getDataFromParentApp(image: String) {
let dictionary = ["Desired Word":image]
WKInterfaceController.openParentApplication(dictionary) {
(replyInfo, error) -> Void in
...
}
openParentApplication
, as with any other communication between the Apple Watch and iPhone, will occur over bluetooth magic, without requiring you to do anything. Over in our AppDelegate of our iOS target, we will need to implement the other side of our method:
func application(application: UIApplication!,
handleWatchKitExtensionRequest userInfo: [NSObject : AnyObject]!,
reply: (([NSObject : AnyObject]!) -> Void)!) {
getImageForWordThatRhymesWithDat(userInfo, reply)
}
We already have a method in our iOS application called getImageForWordThatRhymesWithDat
, which expects an NSDictionary
with the key “Desired Word” and a value containing the name of the image we desire. The method returns an NSDictionary
with the key “Returned NSData” and the NSData of our image.
We will leave out the details of our getImageForWordThatRhymesWithDat
method and let you imagine it is a method you have already built in one of your current iOS applications. Maybe you want to pass back a different set of data based on what your application already implements. Just make sure the data can be held in NSDictionary
and transfers correctly through our two methods.
Now that our NSData is getting sent back to the WatchKit Extension, let’s look back at the completion block of our earlier openParentApplication method.
(replyInfo, error) -> Void in
switch (replyInfo?["Returned NSData"] as? NSData, error) {
case let (data, nil) where data != nil:
let image = UIImage(data: data!)
self.imageView.setImage(image)
case let (_, .Some(error)):
println("got an error: (error)") // take corrective action here
default:
println("no error but didn't get data either...") // unexpected situation
}
We have now received our image NSData (or possibly an error), and we can act accordingly and set our WKInterfaceImage
.
Our new openParentApplication method solves several problems we discussed earlier:
-openParentApplication:reply:
allows us to briefly access our parent app when it is asleep.-handleWatchKitExtensionRequest:userInfo:reply:
can send data from our parent application back to our WatchKit Extension, lessening the need for code duplication or Frameworks.Thanks for the new method, Apple! We are glad that they realized the issue early on and listened to developer demand. We hope this explanation helps with your early WatchKit wisdom.
Our introductory guide to Swift Regex. Learn regular expressions in Swift including RegexBuilder examples and strongly-typed captures.
The Combine framework in Swift is a powerful declarative API for the asynchronous processing of values over time. It takes full advantage of Swift...
SwiftUI has changed a great many things about how developers create applications for iOS, and not just in the way we lay out our...