NSURLSession is the heart of networking in Foundation. Let's take a look at a few ways to use it.
The basic idea is we'll create a new NSURLSession, and then use it to create NSURLSessionTasks that will make the actual HTTP requests. We'll start by creating a new session:
We'll can use a data task like above, then use this function to grab the downloaded data. This will be called multiple times, so we'll need to keep an NSMutableData reference around to append to.
Imagine an app that downloads and plays movies. If a user begins downloading a movie, it'd be great if the file could continue downloading even if the user presses the home button and sends the app to the background. NSURLSessionDownloadTask can help. Let's take a look.
First we create a new background configuration and session. Then we use that session to create a new download task:
We can grab the downloaded data pretty easily, by implementing this function from NSURLSessionDownloadDelegate:
funcURLSession(session:NSURLSession,downloadTask:NSURLSessionDownloadTask,didFinishDownloadingToURLlocation:NSURL){print("Movie data written to \(location)")}
Last but not least, we'll need to implement a function from NSURLSessionTaskDelegate. In it we'll call finishTasksAndInvalidate on the session. This ensures everything is cleaned up and the session lets go of us (self) as its delegate.
Don't worry, NSTimeZone has our backs. It can help us easily translate NSDate objects from one time zone to another. Let's dive deeper with a concrete example.
Here's a common scenario:
We're working on an app that downloads some data from an API, then displays it to the user. In our case, we know the API is returning timestamp information in the GMTtime zone.
Translating the API's values to the user's local time zone would go something like this:
letinput="2015-08-24T09:42:00"// came from HTTP APIletGMTTZ=NSTimeZone(forSecondsFromGMT:0)letlocalTZ=NSTimeZone.localTimeZone()letformatter=NSDateFormatter()formatter.dateFormat="yyyy-MM-dd'T'HH:mm:ss"formatter.timeZone=GMTTZifletdate=formatter.dateFromString(input){formatter.timeZone=localTZformatter.dateFormat="MMMM d, H:mm a"timestampLabel.text=formatter.stringFromDate(date)// "August 24, 2:42 AM"}
After we parse the date, we change our formatter'stime zone to the local one, then render our date back to a string to show the user.
The NSTimeZone.localTimeZone() function (as well as any NSTimeZone object) is our gateway to a few more useful values:
NSFileManager is one of the primary ways you interact with the file system on iOS and OS X. Today we’ll look at both how to use it, as well as how to put some of the new Swift 2 features we’ve been learning about to real world use.
guardletdocumentsPath=NSSearchPathForDirectoriesInDomains(.DocumentDirectory,.UserDomainMask,true).firstelse{return}letlogPath=documentsPath+"spaceship.log"guardletlogExists=fm.fileExistsAtPath(logPath)else{return}do{letattributes=tryfm.attributesOfItemAtPath(logPath)letcreatedAt=attributes[NSFileCreationDate]// > 5 minutes (in seconds) ago?ifletcreated=createdAtwherefabs(created.timeIntervalSinceNow)>300{tryfm.removeItemAtPath(logPath)"[BEGIN SPACESHIP LOG]".writeToFile(logPath,atomically:false,encoding:NSUTF8StringEncoding,error:nil)}}catchleterrorasNSError{print("Error: \(error.localizedDescription)")}
Here we use NSFileManager to wipe out a log file if it's more than 5 minutes old:
First we use guard to make sure our documents directory is available.
Then, we create a path for our log file, and check that it exists.
Many of NSFileManager's functions are marked as throws, so we need a set of do/catch blocks.
Next we check when the log file was created.
We use another new Swift 2 feature, pattern matching, to do our age check on the optional inside the if statement.
Finally we try to remove the file, and replace it with a fresh, blank log.
We then use the catch statement to capture and print any errors that have been thrown.
Handoff is part of Apple's Continuity system. It allows users to begin a task or activity on one device, then continue it on another one. It's actually extremely simple to implement, all you do is tell the system what the user is currently doing in your app, and the system handles the rest. Here it is in code:
Now, if the user picks up another device the activity your app's icon will appear in the bottom left of the user's lock screen on iOS, or in the dock on OS X, and the user can continue where they left off. To wrap things up, we just need to implement two additional UIApplicationDelegate methods:
funcapplication(application:UIApplication,willContinueUserActivityWithTypeuserActivityType:String)->Bool{returntrue}funcapplication(application:UIApplication,continueUserActivityuserActivity:NSUserActivity,restorationHandler:([AnyObject]?)->Void)->Bool{// use the userActivity object to restore the state// needed for the user to continue what they were doingreturntrue}
NSLinguisticTagger is one of the hidden gems of Foundation.
It can be used to process natural-language text (i.e. words written by a human and suitable for consumption by other humans).
It’s an incredibly powerful API and we’re only going to scratch the surface of what’s possible with it here.
Let’s use NSLinguisticTagger to extract all the proper nouns from a UITextView.
Then we’ll use those nouns to perform searches in the Wolfram Alpha API to provide instant feedback about the important things the user has written in the text view.
The result will be a bare-bones context-aware writing app that can understand what you're writing about!