At one point or another, we've all heard some form of "Oh you make apps? I'm interested in that, but I'm having trouble just getting started". Today we'll take a look at the specific steps to create our first app and where to go from there. Let's dive in:
We'll need a Mac. We'll open the Mac App Store and search for "Xcode", then install it. (It's free).
Once it's installed, we'll open Xcode. We'll allow it to verify it's installation, and install any components it needs to.
Then we'll go to the File menu and choose File > New > Projectโฆ We'll leave the Master-Detail iOS Application selected and click Next. We'll give our new app a name: "Foodstagram". We'll enter "com.somename" as the organization identifier, select Swift as the language, and click Next. Finally, we'll choose where to save our new project, then click Create.
When our project opens, we'll hit the little โถ button in the top left corner. Xcode will build our new app and launch it in the Simulator.
Hey it's an app! Hit the +button to add some entries, then edit to delete them.
Congratulations, our new app-venture (sorry, had to) has begun! Next, we need to learn how to learn. When first starting out, much of our time will be spent Googling for things we don't know yet. This is completely normal. Let's start right now.
We'll look at going from idea to implementation. Our idea: "The top bar of the app should be green."
We'll Google for how to do it, using as specific a phrase as we can given what we know so far:
"ios swift change top bar background color".
We'll read the first result from stackoverflow. The first answer contains some possibly helpful code snippets, but we'll read a few more to be sure. It seems the rest of the answers all suggest a similar piece of code talking about "appearance". Sounds promising. One even mentions "color" and "green", so we'll copy it for pasting later:
We'll keep reading our search results until we find a coderwall post from Eranga Bandara that answers our question: "Add following code to didFinishLaunchingWithOptions function in AppDelegate.swift".
Perfect, we'll do just that and click the AppDelegate file in Xcode, then paste our copied code at the end of the specified function.
We can check if it worked by clicking the โถ button again. Success! Our top bar is now green!
We can't learn everything this way, so our next step is to try to find something to teach us the rest of the basics. There's plenty of great resources out there, including one that's just getting started. ๐๐ซ
Grand Central Dispatch is the name of Apple's collection of task concurrencyfunctions in libdispatch. GCD (as it's often called) is packed full of interesting features involving concurrency, queuing, timers, and more. Let's dive in and take a look at some simple and common use cases:
Common Usage
One of the most common ways to use GCD is to hop to a background queue to do some work, then hop back to the main queue to update the UI:
If we wanted to run some code in viewDidAppear: but only wanted it to run the first time, we could store some flag in a Bool property. Or just use GCD:
We can also easily wait a specified amount of time, then run some code. Here we'll use this technique to pop back to the previous view controller a quick "beat" after the user selects an an option in a table view controller. (As seen in many apps, including Settings.app):
Using a UISegmentedControl to switch view controllers is very common, even Apple does it:
Let's build this using UIPageViewController and UISegmentedControl.
We start with a blank storyboard, drag out a UIPageViewController and set it as the initial view controller. Then drag out two UIViewControllers to switch between. We'll select the page view controller and choose Editor > Embed In > Navigation Controller.
Then we drag out a UISegmentedControl and drop it into the title area of the navigation bar of our page view controller. Finally, we create an @IBAction function that will get called when the selected segment changes.
The code is pretty straightforward, note the use of R.swift to grab those two view controllers from our storyboard. (covered in Bite #52).
Let's say you have a table view with some cells showing a list of crew members. It'd be great if when the user taps a cell, it would โexpandโ to reveal some actions that can be performed on that crew member. Let's dive in.
Setup View Hierarchy
As you can see, we lean on UIStackView pretty heavily. The constraint shown here is the one we'll be animating.
Animate the Constraint
In our cell's setSelected(animated:) function, we animate the constraint just like we covered back in Bite #9. After the animation's done, we hide/show the toolbar. This triggers the top-level stack view to recalculate it's height.
Our view controller takes care of resizing our cells by updating the 'expanded' state of each crew member when the selection changes and a pair of calls to tableView.beginUpdates/endUpdates inside the tableView:didSelectRowAtIndexPath: and tableView:didDeselectRowAtIndexPath:.
Download the complete working project here: j.mp/bite050
letsomething=Product()switchsomething{caseisProduct:print("Found a product")caseletpersonasPerson:print("Found a person: \(person.name)")default:print("Found an unknown thing.")}
Where
letcontentOffset=(0,30.0)switchcontentOffset{caselet(_,y)wherey<0:print("Scrolled up")caselet(_,y)where(0...60)~=y:print("scrolling top area")default:println("just scrolling")}
Swift 2
New in Swift 2, you can now use any Swift pattern as the clause of an if statement:
letcomments=7ifcase1...10=commentCount{print("some comments")}elseifcase11..100=commentCount{print("lots of comments")}
And in Swift 2's new error handling:
do{trysend(message:"Hello")}catchSendError.Offline{print("user is offline")}catchSendError.RateLimited{print("stop spamming")}catchSendError.Blocked(letreason){print("user was blocked because \(reason)")}
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.
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.