The guard statement was added to Swift in its 2.0 release. It can dramatically increase the readability and clarity of the conditional checks in our code.
We can think of the guardstatement like a sort of inverted ifstatement. We essentially say: "this thing must be true otherwise we're bailing out!". Here's a fairly full-featured example:
Here we're ensuring that we have a fuelCell using optional unwrapping, then using pattern matching to make sure that our (now unwrapped optional) fuel cell has enough fuel in it for us to launch. Right away we can start to see how much clarity this adds.
If either part of our condition fails, we use the else block to run some code then return from the function.
Also as a bonus, the variables we unwrapped in the guardstatement are now available, unwrapped, and in-scope for the rest of our function (anything below the guardstatement). Neat!
This allows the rest of our function to focus on the actual work being done, rather than checking for validity throughout. We can stack these up too, it's quite common to see multiple guardstatements at the top of a functions in Swift.
It's important to note that we aren't required to return at the end of a guard's else block. Imagine using guard in loops to continue, or in a function that throws to throw an error. Guard helps keep our code clean and readable. Happy guarding!
Today we'll continue looking at initialization in Swift with Designated Initializers. Let's get started.
Swift's initialization system is made up of what are essentially a set of rules. We'll step through them here. Let's start with a class.
The first rule of Designated Initializers is that we need one. All classes must define (or inherit) at least one.
Ok, we've added one designated and one convenience initializer. Not too shabby. Now, let's use this base class.
Uh oh, what's going on here? Turns out it's the next rule. We're writing the designated initializer for Peakachew. Designated initializers must call a designated initializer from their immediate superclass, not a convenience one like we tried to do here.
Well, we've fixed our first problem but we've hit the next rule. Designated initializers have to initialize all stored properties on their class before calling super.
Lastly, designated initializers must call their parent class's initializer before assigning a value to any properties they've inherited from it.
With that, we're done. We're now following all the rules:
Often when working with data from an API or third-party we'll need to manipulate or analyze it in a very specific way. In these cases, many of us simply search Google for "how to do the thing to a String in Swift". This usually works out fine, but what a bummer.
Today we'll check out a library from Andrew Mayne called SwiftString, which can help us here.
SwiftString is essentially a collection of a ton of String manipulation and analysis utilities. It has functions like this:
Following up on Bite #201 about reporting bugs to Apple, today we'll take a look at a tool that makes reporting bugs even easier called QuickRadar. It's great and will give us a chance to discuss one more piece of this puzzle, OpenRadar.
QuickRadar is a open-source menu bar app for OS X that simplifies and improves upon the "traditional" bug reporting process we looked at in Bite #201. We can download it for free from quickradar.com. We'll move it over to /Applications, then start it up.
We can head over to QuickRadar's preferences to fill in our Apple ID credentials.
Next, we'll select New Radar... to see the app's main interface. Here we can describe our bug, drag in a sample project, etc.
We'll see another option at the bottom: "Send to Open Radar". Open Radar is a site run by the community that catalogs and allows us to search/compare bugs with each other.
Usually we have to post them there manually, but with QuickRadar, we'll just add our credentials in preferences, then check the box. Finally, to ease confusion, links like rdar://12345only work for Apple employees.
We've all been there. We hit a bug, and after a bit of debugging we determine the cause actually lives in one of Apple's frameworks. 😱Perhaps even worse, we find a crashing bug in Xcode itself 😨. When we hit these types of issues, our first step to getting it fixed should be reporting the bug to Apple. Today we'll check out how to do it. Let's begin.
We'll start by going to bugreport.apple.com and logging in with our developer account Apple ID.
Once inside, we'll see a delightful iOS 6-ish interface. Yeah... Anyways, we'll click the New button to get started.
Next, we'll select the platform/product we're reporting for.
Finally, we'll be shown the main New Problem form. Most of the fields are self explanatory, but don't feel too boxed in by the format. Just be direct, describe the exact problem as we'd want to hear it described ourselves (imagine if we were the ones tasked to fix it!)
Here's a quick example:
Apple's internal “Radar” system for tracking these reports has gotten a bad rep. In truth though, it's our only way to get these types of issues in front of the eyes of the engineers who need to know about them. Now go forth, and report all the things!
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!
Way back in Bite #1 (zomg!) we talked about initializing View Controllers in Swift. Swift'sinitfunctions are still a source of confusion for many newcomers. Today we'll look at a couple cases where Swiftsynthesizesinits for us.
Structs
Swift offers free "memberwise"initializers for Structs. This means that if we define a Struct, and opt not to define any initializers, one will be synthesized for us, under the hood, using the properties we've given to the Struct. If we add our own though, we lose the synthesized init, and become responsible for defining 100% for the Struct'sinits.
Classes can synthesize a default initfunction for us. Only one that accepts 0 parameters, though. We'll get this if we define a class, while assigning default values to all its properties:
classSpaceship{vartopSpeed=1000varcurrentSpeed=0}
letship=Spaceship()
There's plenty to cover about init'ing things in Swift. We'll take a look in future Bites. Oh, and happy 200thBite !
iOS gives us a ton of great capabilities to build upon. Being able to use the user's current geographic location in our apps really has changed the world.
We always need to ask for the user's permission first though, so we might as well do it in style! Today we'll check out a simple yet beautiful library from Sven Tiigi called STLocationRequest that uses Flyover to provide a great looking "location access prompt" view controller.
We'll begin by importing STLocationRequest, and configuring and showing a location request controller.
Except iOS 😭, which doesn't support them out of the box. Today we'll try a library from Michael Choe called SwiftSVG which provides great support for parsing and rendering SVG files. Let's take a look.
SwiftSVG supports a ton of different ways of getting SVGs into our app.
SwiftSVG also provides a custom UIViewsubclass we can use in Interface Builder that supports IBInspectable/IBDesignable.
More broadly, it's important to think about the reasons why we might want to use SVGs in our app. SVGs are essentially XML files (Open one up in a text editor, you'll see.)
They are instructions on how to draw a set of paths. The files are incredibly small.
It happenstothebest of us. We're going along, composing some UIViews in our app. We're styling them, configuring them, we can't wait to try them out. That's when we see it. A big, empty, unescapable void of nothingness right where our views should be! 😱
Today we'll look at some tips to solve a case of missingUIViews.
First, we should arm ourselves with tools to help inspect what's going on. Xcode's own View Debugger is a great place to start, and Reveal.app is a fantastic third-party solution.
Whether it's one of these tools, or simply writing some in-depth logging functions, our first step should be to look at both our view hierarchy and its layout for anything funky.
We can use private functions like recursiveDescription to print out a handy tree-view of our views to Xcode'sConsole.
Most of these debugging sessions stop here, as the problem often involves a view not being in the correct place in the hierarchy, or Auto Layout has gone and done something wacky with our views' locations.
If we're still stuck though, here are some sanity checks we can perform:
Are any viewshidden?
How about transparent? (0 alpha)
Is it masked via a maskLayer?
Does it have a CGRectZeroframe?
Is the key UIWindow a weird size or in a weird place?
Try making each view a specificuglycolor (the static .XColor() functions on UIColor work wonders here).
Is another view covering it up?
Is .clipsToBounds enabled and a strange frame/bounds is causing the view to be clipped?
If all else fails, comment out everything, and add it back one bit at a time until something fails.