Tutorials 45
Tutorial: Check for Internet Connection in Swift
There are many reasons you need to check if the user is connected to the internet within your app, most important is that your app needs to retrieve data from a feed or display a web view. As soon as your app is loaded and before you make any calls to get data from a feed you should check if the user is connected to the internet.
In the past in Objective-C the most common way to check for connectivity is using Reachability, but it hasn’t been converted to Swift as of yet. Below is a simple way to add this feature to your new Swift project.
- Create a new Swift file within your project, name it “Reachability.swift”.
- Cut & paste the following code into it to create your class.
import Foundation import SystemConfiguration public class Reachability { class func isConnectedToNetwork() -> Bool { var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0)) zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress)) zeroAddress.sin_family = sa_family_t(AF_INET) let defaultRouteReachability = withUnsafePointer(&zeroAddress) { SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, UnsafePointer($0)) } var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0) if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false { return false } let isReachable = flags == .Reachable let needsConnection = flags == .ConnectionRequired return isReachable && !needsConnection } }
- You can check internet connection anywhere in your project using this code:
if Reachability.isConnectedToNetwork() == true { println("Internet connection OK") } else { println("Internet connection FAILED") }
- If the user is not connected to the internet, you may want to show them an alert dialog to notify them.
if Reachability.isConnectedToNetwork() == true { println("Internet connection OK") } else { println("Internet connection FAILED") var alert = UIAlertView(title: "No Internet Connection", message: "Make sure your device is connected to the internet.", delegate: nil, cancelButtonTitle: "OK") alert.show() }
You can grab the full source code for this tutorial. Note: Built for Xcode 7.1.
Tutorial: Play Video in Swift
Recently I needed to add a video as a background in one of my apps. This is a really nice effect if it’s a looping video. On top of the video I had some other elements and buttons, it was cool to see motion happening behind. The code snippet below displays the video full screen with no controls and it repeats, but you could change the properties to suit your needs.
- First add the video to your project, just like any file, you can drag it into your Project Navigator or right click in the Project Navigator and select “Add Files”. Be sure to choose the targets that you need to add the file to, if you have more than one.
- In the Project Navigator select your Project Root > Your Target > Build Phases > Copy Bundle Resources. Check to see that you video is there, if not click the plus sign to add it.
- Add this import statement to the top of your View Controller.
import MediaPlayer
- Add this property to your class.
var moviePlayer : MPMoviePlayerController!
- Add the code below to create and play your video. This can be added to your ViewDidLoad() method or create your own function.
let path = NSBundle.mainBundle().pathForResource("Video", ofType:"mp4") let url = NSURL.fileURLWithPath(path!) self.moviePlayer = MPMoviePlayerController(contentURL: url) if let player = self.moviePlayer { player.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height) player.view.sizeToFit() player.scalingMode = MPMovieScalingMode.Fill player.fullscreen = true player.controlStyle = MPMovieControlStyle.None player.movieSourceType = MPMovieSourceType.File player.repeatMode = MPMovieRepeatMode.One player.play() self.view.addSubview(player.view) }
Get Started with Apple Watch and WatchKit
It’s finally here, we’ve been waiting a long time since we heard the rumours of an iWatch, and now with the release of Xcode 6.2 and the iOS 8.2 SDK Apple has included WatchKit so we can begin developing for it at last. What kind of watch app are you going to make?
Let’s look at the three kinds of watch interfaces you can include in your app.
WatchKit Apps
A Watch app is the basis for interacting with your content on Apple Watch. Watch apps are accessible from the home screen and usually provide only a portion of the functionality of their containing iOS app. The purpose of a Watch app is to give the user quick but more in-depth access to app-related data.
The Watch app works in tandem with a corresponding WatchKit extension running on the user’s iPhone. The Watch app contains no custom code and is used only to store the storyboards and resource files associated with your user interface. The WatchKit extension is the brains of the operation. It contains the business logic and code you use to manage your content, respond to user interactions, and update your user interface. And because it runs on the user’s iPhone, the WatchKit extension can easily coordinate with your iOS app to gather location updates or perform other long-running tasks.
Learn how to make a Watch App, Tutorial: Building an Apple Watch App
Glances
A glance is a focused interface for presenting important information that the user needs right now. Glances are aptly named because they are intended to be looked at quickly by the user. Glances do not scroll, so the entire glance interface must fit on a single screen. Glances are read-only and cannot contain buttons, switches, or other interactive controls. Tapping a glance launches your Watch app.
The code for managing a glance resides in your WatchKit extension. The classes you use to manage your glance interface are the same ones you use for your Watch app. Even though the classes and basic behaviour are the same, a glance is simpler to implement because it does not respond to user interactions.
Learn how to make a Glance, Tutorial: Building an Apple Watch Glance
Actionable Notifications
Apple Watch works with its paired iPhone to display local and remote notifications. Initially, Apple Watch uses a minimal interface to display incoming notifications. When the user’s movement indicates a desire to see more information, the minimal interface changes to a more detailed interface displaying the contents of the notification. Apps can provide their own customized version of this detailed interface and add custom graphics or arrange the notification data differently than the default interface provided by the system.
Apple Watch supports the interactive notifications that were introduced in iOS 8. Interactive notifications are a way to add buttons to a notification that reflect immediate actions the user can take. For example, an incoming calendar event might include buttons to accept or reject a meeting invitation. When your iOS app registers support for interactive notifications, Apple Watch automatically adds appropriate buttons to both the custom and default notification interfaces. All you need to do is handle the actions selected by the user in your WatchKit extension.
Learn how to make a Dynamic Notification, Tutorial: Building an Apple Watch Notification
Getting Started with WatchKit video
Apple has made a great video to help us understand the architecture, the APIs available and how the interface works.
Development Resources
- Apple Watch Human Interface Guidelines
- Xcode 6.2 beta, including iOS 8.2 SDK with WatchKit
- iOS 8.2 beta in iOS Dev Center
- WatchKit Programming Guide
- WatchKit Framework Reference
- WatchKit Catalog: Using WatchKit Interface Elements
- Lister: A Productivity App (Obj-C and Swift)
- WatchKit Catalog: Using WatchKit Interface Elements
Tutorial: Share on Twitter and Facebook in Swift
Apple has integrated Twitter login support since iOS 5, and Facebook since iOS 6. In the past, developers had to integrate the full Facebook and Twitter SDK to integrate sharing in their apps. Since it’s built in, it’s much easier to add these social features to your own app.
Note: If you would like to learn how to share with the native Facebook SDK, read this article: Tutorial: How To Share in Facebook SDK 4.0 for Swift
Using the Social Framework allows applications to interact with social networks from a single API without having to manage authentication. Users login to Facebook and Twitter at the OS level within the “Settings” app, so you don’t need to integrate the full Facebook or Twitter SDK and handle login yourself, it’s already done for you. It includes a system provided view controller for composing posts as well as an abstraction that allows consuming each social network’s API over HTTP.
The Social framework comes with a class named SLComposeViewController. The SLComposeViewController class presents a standard view controller for users to compose a tweet or Facebook post. It also allows developers to preset the initial text, attach images and add URL to the post. If you just want to implement simple sharing feature, this is the only class you need to know.
Below is what the SLComposeViewController looks like in your app.
For both, you’ll need to import the Social Framework.
import Social
Share on Twitter
- Go to the Storyboard and design the user interface. In the view, add the Facebook button.
- Create an action method below and name it as “twitterButtonPushed”. This method will be invoked when the button detects a Touch Up Inside event.
@IBAction func twitterButtonPushed(sender: UIButton) { if SLComposeViewController.isAvailableForServiceType(SLServiceTypeTwitter){ var twitterSheet:SLComposeViewController = SLComposeViewController(forServiceType: SLServiceTypeTwitter) twitterSheet.setInitialText("Share on Twitter") self.presentViewController(twitterSheet, animated: true, completion: nil) } else { var alert = UIAlertController(title: "Accounts", message: "Please login to a Twitter account to share.", preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil)) self.presentViewController(alert, animated: true, completion: nil) } }
- In the Storybaord, right click the Twitter button or switch to the Connections inspector in the right pane. Next drag a connection between “Touch Up Inside” and the View Controller on the left where the “twitterButtonPushed” method is defined.
- Test it out, run your app and when you press the Facebook button you should see the SLComposeViewController popup so the user can enter their text to share on their Twitter stream. Be sure to set the initial text value to whatever you like.
Share on Facebook
- Go to the Storyboard and design the user interface. In the view, add the Facebook button.
- Create an action method below and name it as “facebookButtonPushed”. This method will be invoked when the button detects a Touch Up Inside event.
@IBAction func facebookButtonPushed(sender: UIButton) { if SLComposeViewController.isAvailableForServiceType(SLServiceTypeFacebook){ var facebookSheet:SLComposeViewController = SLComposeViewController(forServiceType: SLServiceTypeFacebook) facebookSheet.setInitialText("Share on Facebook") self.presentViewController(facebookSheet, animated: true, completion: nil) } else { var alert = UIAlertController(title: "Accounts", message: "Please login to a Facebook account to share.", preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil)) self.presentViewController(alert, animated: true, completion: nil) } }
- In the Storybaord, right click the Facebook button or switch to the Connections inspector in the right pane. Next drag a connection between “Touch Up Inside” and the View Controller on the left where the “facebookButtonPushed” method is defined.
- Test it out, run your app and when you press the Facebook button you should see the SLComposeViewController popup so the user can enter their text to share on their Facebook page. Be sure to set the initial text value to whatever you like.
You can grab the full source code for this tutorial. Note: Built using Xcode 6.1.
Tutorial: Today Widget in Swift
App extensions in the Today view are called widgets. Widgets give users quick access to information that’s important right now. For example, users open the Today view to check current stock prices or weather conditions, see today’s schedule, or perform a quick task such as marking an item as done. Users tend to open the Today view frequently, and they expect the information they’re interested in to be instantly available.
The best widgets give users quick updates or enable very simple tasks. If you want to create an app extension that enables a multistep task or helps users perform a lengthy task, such as uploading or downloading content, the Today extension point is not the right choice.
Because user interaction with Today widgets is quick and limited, you should design a simple, streamlined UI that highlights the information users are interested in. In general, it’s a good idea to limit the number of interactive items in a widget. In particular, note that iOS widgets don’t support keyboard entry.
Below is a tutorial that implements a Time Widget to display clocks for a couple of time zones. This fits into the Apple requirement of making it a simple dynamic task that users may need frequently without wanting to open a full app.
Setup the Application Extension
- Select File > New > Project. Select the Single view application template, and call it TodayWidget.
- Add the Application Extension Target. Select File > New > Target…. Then in the left pane, select Application extension and under that choose Today Extension. Because our Today extension is going to show times, give it the name TimeWidget.
- A message will popup asking if you want to activate the “TimeWidget” scheme. Click Cancel. We will debug it using the normal Application scheme.
Create the Today Widget View
Today widgets are just like any other view within your application and built using a UIViewController. Next we’ll create our view for what will appear in the widget.
- In the project navigator, expand TimeWidget group and click on MainInterface.storyboard.
- Select the “Hello World” label already there and delete it.
- Click on the “View” and open the Size Inspector and change the height of the view to 60.
- Drag a eight UILabels into the view, the top four be the titles of the time zones and the bottom four will be clocks. See the image below.
- Define your IBOutlet label variables within the “TodayViewController.swift” and add in the perferredContentSize of the view so it will display the correct height in the Today View.
// // TodayViewController.swift // TimeWidget // // Created by Brian Coleman on 2014-10-16. // Copyright (c) 2014 Brian Coleman. All rights reserved. // import UIKit import NotificationCenter class TodayViewController: UIViewController, NCWidgetProviding { @IBOutlet var pacificLabel: UILabel! @IBOutlet var mountainLabel: UILabel! @IBOutlet var centralLabel: UILabel! @IBOutlet var easternLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view from its nib. self.preferredContentSize = CGSizeMake(320, 50); } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)!) { // Perform any setup necessary in order to update the view. // If an error is encountered, use NCUpdateResult.Failed // If there's no update required, use NCUpdateResult.NoData // If there's an update, use NCUpdateResult.NewData completionHandler(NCUpdateResult.NewData) } }
- Connect the IBOutlets to the new variables within the MainInterface.storyboard.
Test Your Today Widget
- When you run the app you’ll see a blank view since our app doesn’t do anything except create the Today Widget.
- Drag from the top of your view down to display the notification center. Next tap the “Edit” button.
- Tap the green plus button next to the TimeWidget. You’ll see it got added below the Calendar. Drag it to re-order it so it shows above the Calendar.
- Tap “Done” and you should see our TimeWidget displayed in the Today Widget view.
Add in Live Dynamic Data
We are almost done making our widget, let’s add in the clocks to finish it up.
import UIKit import NotificationCenter class TodayViewController: UIViewController, NCWidgetProviding { @IBOutlet var pacificLabel: UILabel! @IBOutlet var mountainLabel: UILabel! @IBOutlet var centralLabel: UILabel! @IBOutlet var easternLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view from its nib. self.preferredContentSize = CGSizeMake(320, 50); self.updateClocks() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)!) { // Perform any setup necessary in order to update the view. // If an error is encountered, use NCUpdateResult.Failed // If there's no update required, use NCUpdateResult.NoData // If there's an update, use NCUpdateResult.NewData completionHandler(NCUpdateResult.NewData) } func updateClocks() { var time: NSDate = NSDate() println("Time: \(time)") var timeString : NSString = "Time: \(time)" let formatter:NSDateFormatter = NSDateFormatter(); var timeZone = NSTimeZone(name: "UTC") formatter.timeZone = timeZone formatter.dateFormat = "HH:mm" println("UTC Time: \(formatter.stringFromDate(time))") timeZone = NSTimeZone(name: "US/Eastern") formatter.timeZone = timeZone formatter.dateFormat = "HH:mm" println("EST Time: \(formatter.stringFromDate(time))") easternLabel.text = formatter.stringFromDate(time) timeZone = NSTimeZone(name: "US/Pacific") formatter.timeZone = timeZone formatter.dateFormat = "HH:mm" println("PST Time: \(formatter.stringFromDate(time))") pacificLabel.text = formatter.stringFromDate(time) timeZone = NSTimeZone(name: "US/Mountain") formatter.timeZone = timeZone formatter.dateFormat = "HH:mm" println("MT Time: \(formatter.stringFromDate(time))") mountainLabel.text = formatter.stringFromDate(time) timeZone = NSTimeZone(name: "US/Central") formatter.timeZone = timeZone formatter.dateFormat = "HH:mm" centralLabel.text = formatter.stringFromDate(time) } }
You can grab the full source code for this tutorial. Note: Built for Xcode 6.0.