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.
TestFlight vs Enterprise Distribution
If you build apps more than likely you’ll need to send out test builds of your app to a group of users so they can review it and give you feedback before releasing it to the public. Depending on the scale and complexity of the app you’ll need to do this many times before your final release. Below are a couple of options when sharing with your team.
TestFlight Distribution
TestFlight is a free over-the-air platform used to distribute beta and internal iOS applications to team members. Developers can manage testing and receive feedback from their team with TestFlight’s Dashboard. The App Store approval process is not required. The general public cannot see a listing for your app, purchase or install it, only the people you invite to use it.
How Does it Work?
iOS Developers sign up at TestFlight, create a team, invite team members, add the team members’ devices to their application build (this still has to be done via Apple’s provisioning on the Developer Portal), upload to TestFlight and then distribute. Developers still have to build the app, however.
For a Developer
- Sign up with TestFlight and create your team.
- Invite and gather the UDIDs from the team members and add them to your Apple Developer Portal and provisioning profile for the app.
- Build the iPhone Application (.IPA) and upload to TestFlight.
- Distribute the build to team members and let the magic happen.
- Receive feedback, monitor tester’s activity and perform a full fledge beta test from the comfort of your chair. Developers on teams can also upload multiple apps for testing/internal distribution.
- Integrating the TestFlight SDK will further the data collected from your testing phase.
For a Tester
- As a tester using TestFlight, you can either be invited, recruited or just sign up.
- Once you sign up with TestFlight and login to the dashboard for the first time, you will be asked to connect your device, allowing developers to access the device’s Unique Device Identifier (UDID).
- Once you have successfully connected the device to your account and have been accepted to a team, the developer will have to add the UDID to the application, so that you can install it on your device. (Only 100 UDIDs allowed per account)
- Once the developer uploads a build you will receive an email through TestFlight, from the developer, with a link to install the build.
- Follow the instructions in the email, click on the link, download the build to your device, and you will be ready to begin using the app.
Note: If you are a registered developer with an enterprise account and are making apps for in-house distribution, TestFlight works with those too. TestFlight fully supports enterprise apps and it works much like ad hoc apps for distribution. Just upload an application signed with an enterprise provisioning profile and distribute to your team and only approved members of your team will have access to the application for installation.
Apple Buys TestFlight
In February of this year Apple announced it had bought TestFlight and as of March 21 TestFlight no longer supported Android builds. Since this time Apple has integrated the TestFlight platform into iTunes Connect so Apple developers can easily send out test builds of their app before submitting to Apple for review.
For instructions on how to prepare your beta app and set up a list of testers watch the TestFlight video tutorial below.
Enterprise Distribution
The iOS Enterprise Distribution program allows a company to distribute their own “in-house” apps directly. It is intended for employees of the licensee company only and that licensee must be a company or organization with a DUNS number. The cost is $299 per year for this license compared to $99 per year for the iOS Developer License. A given device can have apps installed from only one iOS Enterprise License at a time.
“Internal Use Applications developed under this Agreement may be deployed on Deployment Devices in two ways: (1) deployment for internal use by Employees, and (2) deployment for use by Customers either on Your physical premises or under the direct supervision and physical control of Your Employees in other locations, subject to Apple’s right to review and approve such deployment as set forth herein.” – Apple
Note: The Enterprise program does not enable you to deploy apps to the Public App Store. For that you need to be enrolled in the standard iOS Developer Program.
How Does it Work?
Note: You must have the Team Agent role in the iOS Provisioning Portal to create the artifacts needed for this build.
The process for building an Enterprise app is:
1. Create the Distribution Certificate.
2. Create an Enterprise Provisioning Profile. (Go to developer.apple.com and click Member Center.)
3. Build the app using the Enterprise Provisioning Profile.
Following sections explain these steps in further detail.
Create a Distribution Certificate
Distribution certificates are used to sign Enterprise apps.
The steps to receive a Distribution Certificate are:
1. Login to the iOS Provisioning Portal with the Agent role. Goto “iOS Dev Center” -> “Certificates, Identifiers & Profiles” -> “Certificates
2. In the Certificates section, go to the Production tab. Click on ‘+’ icon. Select the type as “In-House and Ad Hoc”.
3. Follow the steps to generate Certificate Signing Request (CSR). Use the Certificate Assistant (available in the Keychain Access application on Mac OS X).
4. Upload the CSR to the iOS Provisioning Portal and download the distribution certificate.
5. Save the certificate on the disk, and open this using Key Chain Access.
6. Xcode can now use this certificate to sign iOS apps.
7. To export this certificate to a different (build) machine, exported it in .p12 format:
a. In Key Chain Access, go to the My Certificates section
b. Right-click on the downloaded certificate and click “Export…”
c. Save the certificate in .p12 format, and provide a secure password while saving.
Create an Enterprise Provisioning Profile
The steps to create an Enterprise Provisioning Profile are:
1. Log in to the iOS Provisioning Portal with the Team Agent role. Goto “iOS Dev Center” -> “Certificates, Identifiers & Profiles” -> “Provisioning Profiles”
2. In the Provisioning section, go to the Distribution tab.
3. Click on New Profile. On the Create iOS Provisioning Profile page
a. Select the Distribution Method as In House
b. Select an appropriate distribution certificate
c. Select App ID
4. Download the provisioning profile.
5. This provisioning profile can be used to build the app for in-house deployment.
Building an App Using an Enterprise Provisioning Profile
The steps to build an app on a machine are:
1. Install the Distribution certificate (.p12 file)
2. Open Xcode. Go to the Organizer window
3. Import the Enterprise Provisioning Profile
4. Open the app’s project file in Xcode
5. Go to Build Settings, Code Signing section
6. Select the certification contained in the Enterprise Provisioning Profile
7. Build the project using Build For > Build for Archiving. This will create the app archive in .ipa file format
8. The .ipa file is ready for enterprise deployment
Distribute to Your Team
Once you have the *.ipa you can store that on an internal web server. Since iOS7, the web server needs to support SSL secure encryption.
Create a web page on your internal network that everyone can access within the company, i.e. http://apps.yourcompany.com. Then create an HTML with a link for each app that you would like to share.
The a href link for every app in your list should look similar to this and point to a manifest file:
itms-services://?action=download-manifest&url=https://
The App Name
Here is a sample manifest file (appName.plist):
items assets kind software-package url http://10.44.41.21/appName.ipa kind display-image needs-shine url http://10.44.41.21/appName.png kind full-size-image needs-shine url http://10.44.41.21/appName.png metadata bundle-identifier ent.company.appName bundle-version kind software title appName
Note: As of iOS8, ensure that the icon URLs are valid. If they are not the user will not be able to install the app on their device.
Conclusion
Personally I like to use the Enterprise Distribution method internally. It’s easy because you don’t have to provision individual devices, this is ideal for large companies with lots of stakeholders and testers. It’s also nice to have one URL that everyone can visit to download any of your test apps within the company. Also best to host that URL on the companies internal network, in order to follow Apple’s rules about “deployment for internal use by Employees” mentioned above. It’s well worth the $299 a year for the Enterprise license, and you can create as many apps as you need.
If I were to send out builds for a personal project or for a small startup company, TestFlight is a much better option since your distribution list of people you need to share the app with is much smaller and within the standard Ad Hoc distribution limitation of 100 devices allowed to provision for a developer account.
Tutorial: Submitting your App using the New iTunes Connect
Recently Apple updated their iTunes Connect portal (http://itunesconnect.apple.com) with a brand new look and feel. It was a very welcomed change since the portal has not been changed in years. You’ll notice that Apple has created icons for everything, it’s much easier to navigate around and it looks really nice when viewing on tablets or phones. At first I didn’t think any functionality changed, just a look and feel, until I went to submit my first update. The distribution process has changed quite a bit and now takes a lot longer.
Distribute Your App
Below is a step-by-step walkthrough on how to distribute your app using the new iTunes Connect portal. Much of it is the same, but the order has changed a little.
- Make sure that you have completed all the configuration the app needs. I.e. New Version and enter all your app details.
- Archive and upload your build using Xcode. Previously you needed to set everything up in iTunes Connect and set the status to “Waiting for Upload”, but now you can upload the binary anytime.
- At this time, you’ll see your build under the Prerelease tab. The status will be “Uploaded”. Now you have to wait for Apple to process your binary. This is where they check for non-public API usage and validate your binary. Note: This could take anywhere from 45 minutes to an hour or two.
- If your binary is rejected, you’ll receive an email from Apple just like before about the issues. If it passes, you’ll see a + plus icon beside the Build section under your new version.
- Click the plus sign to select a build. The plus sign appears only if you have not yet selected a build. If you have already selected a build, you can remove it and select a new one.
- A list pops up containing all of the uploaded builds. Select the one you want to set as the current build.
- After you click Done, it appears in the Build section of Versions along with its upload date and time.
- Click Save at the top of the page.
- Next, click the Submit for Review button in the top right part of the page.
- Answer questions about Export Compliance and Content Rights.
- Answer questions about the Advertising Identifier (IDFA). Indicate whether your app uses the Advertising Identifier, and if so, in what way. Read How to use Apple’s Identifier for Advertisers (IDFA) for more details about this step.
- Click Submit. iTunes Connect returns to Versions on the App Details page.
Tutorial: How to use Auto Layout in Xcode 6
Apple just introduced the new iPhone 6 (4.7in) and iPhone 6 Plus (5.5in). These are two additional sizes to the existing iPhone 4 (3.5in), iPhone 5 (4in), and iPad (9.4in). As iOS developers we have long enjoyed not having to develop for too many different screen sizes, unlike Android, until now. With this many screens available, your apps need to be flexible enough to work on all of them or Apple may reject it or even worse, users will complain it doesn’t work for them on their device.
Below is a simple tutorial to help you with adding constraints to your views using Storyboards, without having to write any code. This is helpful for handling auto rotation as well.
Designing an Interface using Constraints
- Make a new project based on the Single View Application template, and name it AutoLayout.
- Select Storyboard to edit the interface. One nice thing about using constraints is that they accomplish quite a lot using no code. All of the auto layout implementation can be done right here in the Storyboard.
- Add four labeled buttons. Drag four round rect buttons from the library over to your view. Use the dashed blue guidelines to help you line up each one near its respective corner. Double-click each button, and assign a title to each one so you can tell them apart later.
- Run It. Let’s see what happens now that we’ve specified that we support autorotation but haven’t set any autosize attributes. Build and run the app. Select Hardware Rotate Left, which will simulate turning the iPhone to landscape mode. Notice that all of the buttons except for the top left one is off the screen. We need to fix this.
- The image below shows an example of the Auto Layout Menu. You’ll find this in the bottom right of the Storyboard. First select which view you want to modify, then choose one of the buttons to modify it’s layout properties.
Align – Create alignment constraints, such as aligning the left edges of two views.
Pin – Create spacing constraints, such as defining the width of a UI control.
Issues – Resolve layout issues.
Resizing – Specify how resizing affects constraints.© Copyright 2014 AppCoda
- Let’s add our constraints. Click the upper-left button to select it. Choose the Pin button to change constraints for the button. Add 20px to the top and 0px to the left. Then press the “Add 2 Contraints” button to make the change.
- You’ll see that the constraints are now set by the blue lines now displayed when the button is selected. You may not see blue lines for the top left button since all constraints for that location are by default.
- Now do the same for the other three buttons.
- Run it and look at the results. Each button stuck tight to its nearest corner. The buttons on the right shifted out to the right to match the view’s new width, and the buttons on the bottom were pulled up to match the new height.
You can grab the full source code for this tutorial. Note: Built for XCode6-Beta7.
Additional Tips for using Auto Layout
Use Auto Layout to lay out your views relative to each other without fixed origins, widths, and heights, so that views reposition and resize appropriately when the language or locale changes. Auto Layout makes it possible to have one set of .storyboard and .xib files for all devices.
Remove fixed width constraints. Allow views that display text to resize. If you use fixed width constraints, text may appear cropped in some views.
Use intrinsic content sizes. The default behavior for text fields and labels is to resize automatically. If a view is not adjusting to the size of text, select the view and choose Editor > Size To Fit Content.
Use leading and trailing attributes. When adding constraints, use the attributes leading and trailing for horizontal constraints. The attributes leading and trailing are equivalent to left and right. The leading and trailing attributes are the default values for horizontal constraints.
Pin views to adjacent views. Pinning causes a domino effect. When one view resizes to fit text, other views do the same. Otherwise, views may overlap in some devices.
Constantly test your layout changes. Test your app using different device sizes, like iPhone 4, iPhone 5, iPhone 6, iPhone 6 Plus, and iPad.
Don’t set the minimum size or maximum size of a window. Let the window and its content view adjust to the size of the containing views.
Auto Layout is enabled by default when you create a new project. To enable Auto Layout for an older project, select the first view of the View Controller, then select the File Inspector (first one on the left) and make sure the “Use Auto Layout” check mark is selected.