Protocol Extensions are a new feature of Swift 2. They allow you to add new functions (complete with implementations) to any class that implements a protocol. The functionality is best explained with a simple example. Let’s say you wanted to add a way to shuffle arrays.
In Swift 1.2 and earlier, you’d probably add a shuffle function using something like this:
As you can see here, we're also able to use Swift’s fantastic pattern-matching support to limit our extension to only mutable collections that use an Int as their index.
SFSafariViewController is another new addition in iOS 9, and it’s a great one.
Get ready to throw out all that custom in-app browser or third-party library code you’ve been using.
Unlike other solutions, SFSafariViewController embeds all of the power of Safari on iOS (including Autofill, shared cookies, etc.) directly into your app.
Replacing your existing solutions should be trivial for most people, here’s how:
iOS has had support for hardware keyboard shortcuts for a while now. New in iOS 9, Apple has made some great improvements to how apps can take advantage of them. Your app can now register keyboard shortcuts per view controller, and all currently valid shortcuts will be neatly
summarized when the user brings up the new keyboard shortcuts view.
Wiring up a new keyboard shortcut in this system couldn't be easier. Just define a new function, create a new UIKeyCommand and then call addKeyCommand on your view controller:
// inside some UIViewController subclass:overridefuncviewDidLoad(){super.viewDidLoad()letshortcut=UIKeyCommand(input:"n",modifierFlags:UIKeyModifierFlags.Command,action:"createNewFile:")addKeyCommand(shortcut)}funccreateNewFile(command:UIKeyCommand){// do the thing}
UIStackView changes everything. New in iOS 9, you can think of UIStackView as an abstraction layer on top of Auto Layout. It arranges it's subviews and manages their constraints for you.
One way to think about UIStackView is as the UIKit-born cousin to WKInterfaceGroup, the main layout component for building Apple Watch apps with WatchKit.
UIStackViews layout their arranged subviews horizontally or vertically, and they provide options for how arranged subviews should be aligned and distributed.
You can of course nest many UIStackViews inside each other to easily and quickly create complex layouts. Let's test it out by creating something super common like a UITableViewCell to display a comment. We'll use 2 horizontal and 1 vertical UIStackView:
UIStackView Pro Tips
🌀 Set views to hidden for easy conditional layout
🏃 Hide views in animation blocks to animate the re-layout
🎳 Use size-classes to easily alter layout for different environments
FontBlaster is probably one of the simplest things we'll cover in these bites.
Don't be fooled though, it is one of the most useful little utilities and has quickly made its way into my "standard set" of third-party I use in all my new projects.
Adding a custom font to an iOS app is normally just a little cumbersome:
😁 First drag the font file(s) into Xcode
😐 Open up your Info.plist
😒 Add a new key for "Fonts provided by application"
😲 Find the exact names of each font that iOS’s font system wants to hear, adding items in the .plist for each
😭 Watch as loading them all slows down your app’s initial launch
With FontBlaster, all you have to do is make sure your custom font files are added to your app's main bundle then call this method anywhere in your app:
Hey everyone, first off the response to little bites has been absolutely incredible. I'd like to thank every single one of you for reading, responding, retweeting, requesting, etc. as I get things off the ground here.
Second, I'd like to let everyone know that there will be no bites published next week as I'll be busy attending Apple's Worldwide Developer Conference learning what is sure to be tons of exciting new things that I’ll get to cover here in the coming months.
If you're going to be at the conference as well, reach out on Twitter, I'd love to meet and talk to as many of you all as I can! 👍
Bites will resume their regular schedule starting Monday June, 15th.
DZNEmptyDataSet is a library that makes it extremely easy to add custom "empty" data sets, for when a screen in your app either currently has no data, or the user hasn’t created any data yet.
You can configure it by implementing a bunch of different optional methods in the DZNEmptyDataSet protocol. A pretty simple setup is shown here, but the there are lots of more advanced options including custom views and even easily adding a button below the text.
extensionPhotosViewController:DZNEmptyDataSetSource{functitleForEmptyDataSet(scrollView:UIScrollView!)->NSAttributedString!{returnNSAttributedString(string:"No Photos")}funcdescriptionForEmptyDataSet(scrollView:UIScrollView!)->NSAttributedString!{lettext="Photos you take will appear here"returnNSAttributedString(string:text,attributes:[NSForegroundColorAttributeName:UIColor.grayColor()])}funcimageForEmptyDataSet(scrollView:UIScrollView!)->UIImage!{returnUIImage(named:"cracked-egg")}}
Detect interaction by implementing one of the methods in the DZNEmptyDataSetDelegate protocol.
extensionPhotosViewController:DZNEmptyDataSetDelegate{funcemptyDataSetDidTapButton(scrollView:UIScrollView!){println("tapped button on the empty view!")}}
Here's some example empty screens DZNEmptyDataSet can help you create:
PromiseKit is a library that adds Promises support to Objective-C and Swift. Promises (sometimes referred to as "Futures") can help clean up some of the spaghetti-callback-ridden code that we've all written then never talked about again.
The main thing you should take away from this bite is that PromiseKit lets you turn repulsive, close to gibberesh code like this:
...into much more readable, and composable code like this:
firstly{SynapseAPI.loadVideos()}.then{videosin// `join` waits for all the requests to finish, then continuesjoin(videos.map{PiedPiperAPI.loadVideo($0)})}.catch{errorin// called if any error happens anywhere in the chain}.finally{// done, much nicer}
The power of Promises doesn't stop at network calls! PromiseKit comes with extensions Promise-ifying many of the traditionally disperate parts of Cocoa and Cocoa Touch like CLLocationManager, UIAlertView, and even sending a user off to another UIViewController, letting them choose something, then continuing on.
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!
Carthage is a new way to integrate third-party libraries in your apps. One way to think of it is as a simpler alternative to CocoaPods. It’s a dependency manager distilled down to just about it’s simplest possible form.
One of the notable differences between Carthage and CocoaPods is that Carthage doesn’t require an Xcode Workspace to be created or "automagically" managed. It can be installed via a downloadable installer or with a simple brew install carthage.
Create a Cartfile, which is just a plain text file filled with lines like the ones below. Each of these tell Carthage about a library you’d like to use in your app.
Then, simply run carthage update. At which point Carthage will go out and download and build all the libraries you asked for.
Note: Similar to CocoaPods’pod install, you’ll also need to run carthage update anytime you change or update your Cartfile.
Where things begin to feel different from CocoaPods is that the next step is to manually drag and drop the frameworks Carthage built when you ran carthage update into the Linked Frameworks and Libraries of your Xcode target’s General settings panel.
Action Extensions are incredibly powerful. Not only can they accept many different forms of input data, but they can return data back to the original application as well. Let's build an Action Extension to help us sound smart while writing. It will accept a word, let us choose a more intelligent sounding word, then return our selection to the original app.
First we'll add the extension:
File > New > Target... then use the Action extension template.
We grab the input word, then load replacement words:
Finally, we'll return our chosen replacement word back to the original app:
funccompleteWithWord(word:String){varc=self.extensionContext!vartypeID=kUTTypeTextasStringvarprovider=NSItemProvider(item:word,typeIdentifier:typeID)varitem=NSExtensionItem()item.attachments=[provider]c.completeRequestReturningItems([item],completionHandler:nil)}// then inside didSelectRowAtIndexPath:completeWithWord(words[indexPath.row])