Today we'll continueourlookat interesting Swift features. Let's begin.
Type Matching with ‘is’
Try as we might, sometimes still we end up with an AnyObject or Any reference in our Swift code. We can ask if it is a given type or subtype using Swift's powerful pattern matching:
This technique has a few different applications, but one good example is capturing a value from a switchstatement inline:
enumTheme{caseDay,Night,Dusk,Dawnfuncapply(){// ...letbackgroundColor:UIColor={switchself{caseDay:returnUIColor.whiteColor()caseNight:returnUIColor.darkGrayColor()}}()// ... set backgroundColor on all UI elements}}
Today we'll look at acouplemore tips for working in Swift. This time, we'll focus on Swift properties. Let's dive in.
Property Observers
In Objective-C, we'd likely use Key-Value Observing to "know" when the value of a property on one of our objects changes.
KVO still works great in Swift. In many cases, we might be able to get away with Swift's (much cleaner) property observers:
structSpaceship{letname:StringvarcurrentSpeed:Int=0{willSet{print("About to change speed to \(newValue)")}didSet{ifcurrentSpeed>oldValue{print("Increased speed to \(currentSpeed)")}elseifcurrentSpeed<oldValue{print("Decreased speed to \(currentSpeed)")}}}}
Lazy Properties
"Lazy" initialization is a great way to put off expensive work until some later time in our code. Back in Objective-C, if we wanted to "lazily" initialize a property, we might go override it's getter, and check if a private instance variable is nil or not, then populate it if it's not, then return it. Whew!
In Swift, we can forget all of this and accomplish the exact same with a simple new keyword:
lazyvarcouchPotatoes=[String]()
We can also use this technique to lazily init our UI elements, neat!
Localization can go a long way towards increasing the sales of our apps. Users are browsing the App Store all over the world, and when they come across a neat looking app that's not translated into their language, they're very likely to keep on scrolling. Today we’ll check out a library called Localize-Swift from Roy Marmelstein that makes this process much nicer.
The first helpful addition Localize-Swift brings us is a better way to localize our strings:
searchBar.placeholder="Hello World".localized()
Then we can easily test our translations at runtime using:
Localize-Swift also provides a custom genstrings.py script to easily fill our .strings files even though we're not using NSLocalizedString directly, neat!
Push Notifications were a fantastic addition to iOS in iOS 3. They can also sometimes be tricky to test and debug. We can save ourselves a ton of time and hassle with OS Xapp called Knuff. Today we'll check it out and see what it can do. Let's get started.
Before we begin, we'll install the free Knuff iOS app to make our lives a little easier in a few minutes.
We'll launch it on our iOS device (on the same Wifi network as our Mac). Knuff will display a new Devices button for us to choose our device, then it will in our push token for us.
We can use the Knuff iOS tab to try a push right away, neat!
Next, we'll switch to the Custom tab where we'll pick our app's certificate identity:
Knuff helps us by finding all the identities in our Keychain and letting us pick. (We can create a new push certificate/identity for our app with one command using fastlane's pem tool).
That's it! We can now use Knuff to configure our payload, and send pushes. Knuff even lets us save our configurations into files that we can open later for testing different notifications and scenarios.
More info about Knuff can be found at git.io/knuff
When a user first installs one of our apps, it'd be nice if we could hold their hand a bit, pointing out where the important bits are.
Today we'll look at Gecco, a library that can make creating these walkthroughs quite easy. Let's dive in.
Gecco is built using UIKit's custom transition protocols.
This means there's simply a view controller that we'll configure and present over our content that will display the "spotlight" effect.
In it's most basic form, we can use Gecco by creating a SpotlightViewController, then configuring it's spotlight property to be one of the supplied Oval, Rect, or RoundRectenum cases:
Then we simply present it like normal, neat! In simple cases this is all we need, next we'll look at customizing things further.
We can actually subclass Gecco'sSpotlightViewController and use it's spotlightViewproperty to animate the spotlight effect calling out different shapes, even morphing from one to another:
Note about hard-coding values: We've used exact values here to make it easy to understand how Gecco works. In a real world scenario, you would probably be grabbing these values from your views after they've been through a layout pass.
More info about Gecco can be found at git.io/gecco
A continued huge thanks to the folks at Hired.com for sponsoring this week's bites. Finding a good job can be a daunting task. Today we'll take a look at how we can use Hired.com to save our sanity, and find a great job in the process. Let's dive in.
We'll start by entering our email and answering some basic questions:
That's it. Hired will then work with over 3,000 pre-screened companies (both big and small) in 13 major metro areas (North America & Europe) to try find us a great job. Software engineers and designers on Hired can get 5+ job offers in a single week. Each offer will include salary and equity details upfront.
We can view interview requests and accept or reject them before talking to any company. If we get a job through Hired, they'll give us a $1,000 "thank you" bonus!
View offers and accept or reject them without talking to anyone.
Completely FREE + no obligations ever.
Hired is the real deal. They have solved some very real problems and fixed this historically messy process. Looking for a job? Don't waste time, sign up for Hired today so you can get back to work!
Today we'll continue our look at interesting Swift features. Let's begin.
Multiple/Chained Optional Unwrapping
This is great when we've got multiple optionals to unwrap. We can even use unwrapped references from earlier in the statement in later parts of the statement. Neat!
ifletURL=NSURL(string:someURL),letdata=NSData(contentsOfURL:URL),letship=Spaceship(data:data){// use 'ship'}
Multiple Initialization
We can initialize multiple references in one statement (and one line). This works for when using both let and var:
We can simplify Array (and Dictionary) initstatements like this:
letspaceships:[Spaceship]=[]
To this:
letspaceships=[Spaceship]()
Semicolons: Gone but not forgotten!
Removing the need for trailing semicolons was one of Swift's most welcome features. However, they actually are present in Swift, and can serve a useful purpose. They'll let us write multiple statements on one line. This works great (for example) in guardstatements:
iOS has some great built-in support for different keyboards for different types of data, but the built-in numeric-keypadkeyboard style does leave a few things to be desired (a "done" button, decimal point, a "hide" button, etc).
Today we'll look at a library called MMNumberKeyboard by Matías Martínez that does a great job of filling in these gaps. Let's try it out.
Setting up a text field to use the library's keyboard is extremely straightforward. First we'll create and configure the keyboard:
Optionals in Swift are a great way for us to represent either some value, or no value at all. Like many parts of Swift, they're actually built (mostly) in Swift itself. Today we'll pop the hood, and take a look at how they work. Let's get started.
We'll begin by heading over to the definition of the Optionalenum in the Swift headers. We can get here by pressing ⌘⇧O, then typing "Optional":
Right away we'll see that Optional types are merely an enum with an associated value. That associated value has a type, but it's a generic placeholder for whatever type we'll make Optional references to. The trailing-? syntax is merely syntactic sugar, for example:
String?
is simply a shorthand way of writing:
Optional<String>
Swiftenums really show their power here, we're able to represent a fairly high level concept, with this relatively simple construct. Next, let's look at initializing Optionals.
/// ...publicinit()publicinit(_some:Wrapped)
The first init statement handles Optionals with no value, the second handles the presence of some value. Additionally, Optional adopts NilLiteralConvertable, so all three of these statements mean the same thing: