In addition to feature development and bug fixes, iOS developers have to keep tabs on what’s announced yearly at WWDC. Amidst the notable new SDKs announced, there are some changes that iOS devs will need to roll out to keep their apps platform-compliant.
With Swift having evolved to version 4, along with improvements and changes coming to the iOS SDK itself, developers need to sift through the changes and devise a strategy for updating their code bases. All without breaking any of their existing features and functionalities! It all comes down to prioritization for your project: what is the minimum you need to do in order to make your app iOS 11 compliant? What is the easiest case you can make to your project stakeholder or project manager?
Vital features come first, and next come the nice-to-have but not required improvements that iOS 11 brings, from optimizing your application to the visual aesthetics that will further enrich the interaction and functionality of your app. With that in mind, this tutorial will guide you through the steps to take to upgrade your app, taking a pragmatic approach to required and optional improvements.
Objectives of This Tutorial
This article will provide you with an overview of the changes that will be required in order to update your app for iOS 11, from architectural to visual changes as well as App Store publishing changes. Moreover, this tutorial will organize the sections starting from the required changes needed and the scope and effort required, to the nice but not necessary features that will enhance your app as a result of iOS 11.
In this tutorial we will be covering the following:
- preparing your app (and yourself) for iOS 11
- architectural changes
- App Store publishing changes
- UI changes
Assumed Knowledge
This tutorial assumes an intermediate knowledge of Swift or Objective-C and Xcode, as well as familiarity with core iOS SDKs (e.g. UIKit and Core Foundation).
Architectural Changes
As with every iteration of iOS, the most important changes usually are the architectural ones. With iOS 11, this involves migrating to Swift 4, so updating the build settings for Xcode 9 will be the first task we’ll look at.
Incremental Migrating to Swift 4
Important | Required
For those who had to migrate from Swift 2 to 3 last year, that process was extremely painful, and a lot of the changes broke the existing codebase. Thankfully, this isn’t the case moving from Swift 3.2 to 4, as most of the chances are considered additive, rather than deprecating, and as a result the Xcode 9 migration tool performs an admirable job of transitioning your code to the latest Swift.
Moreover, unlike in previous versions, you are not going to be forced to do the upgrade to 4 in one go. That is, Xcode projects simultaneously support both Swift 4 and Swift 3.2, which means that you can have one target in your project compile under Swift 3.2 and another compile in Swift 4. The migration tool will let you know which classes and functions it successfully migrated, and which ones will require your manual intervention to resolve, in the form of errors or warnings.
The errors mean you will need to fix something that isn’t backward-compatible, whereas many of the warnings will indicate that there is a new way in Swift 4 of doing something, such as new API changes. Fix the errors, and prioritize the aforementioned warnings as a separate task.
To access the migration tool, go to Edit > Convert > To Current Swift Syntax in Xcode, and follow the prompts, selecting the target(s) you wish to migrate at this stage.
The migration tool will let you know the minimum work that you will need to do in order to recompile your app, and therefore it should come as no surprise that the recommended best practice is to work on migrating your app from 3 to 4 incrementally, especially in large projects, testing and converting target by target. You won’t have to migrate everything at once, and you can plan your migration path in stages, where and when needed.
We will next take a quick look at what the changes are in Swift 4 that are not mandatory to implement, but good to know.
32-Bit Architectural Deprecation
Important | Required
Another major change in iOS 11 is that all apps in the App Store now have to be 64-bit, as 32-bit apps are no longer supported, and as a matter of fact don’t even work on devices running iOS 11. This shouldn’t come as a surprise as Apple have been warning developers for quite a while, but in case your app has still not made its transition, you can follow Apple’s guidelines on Converting Your App to a 64-bit Binary.
What’s New in Swift 4
Not Important | Optional
Beyond the mandatory work needed in order to get your target to become Swift 4 compliant, you have the option of refactoring your existing code to leverage the new Swift API changes, which are broken down according to the following API-level improvements:
Strings
String has received a lot of attention in Swift 4, with the most notable change being a reversion back to Swift 1.0 where Strings are once again defined as collections, so you can iterate over a String object character by character (SE-0163) using a for loop. Other notable changes to the Strings class include:
- SE-0168 Multi-Line String Literals
- SE-0178 Add
unicodeScalars
property toCharacter
- SE-0180 String Index Overhaul
- SE-0182 String Newline Escaping
- SE-0183 Substring performance affordances
Collections
Dictionaries and sets, as part of collections, have also been revamped in Swift 4, starting with the filtering of dictionaries, which until now returned an array of tuples consisting of key/value pairs. To access a specific element, you would use the following subscript, as in an array:
listOfCars[4].value
In Swift 4, you get back a dictionary instead, providing a more consistent syntax, and subsequently, you access the returned dictionary as you would a normal dictionary. The same now occurs for the map()
function, where you also get back a dictionary. New to dictionary-access subscripts, you can provide a default value in case the key doesn’t exist, making your code safer.
let tomTheCat = animal[“name", default: “id”]
The rest of the changes for collections include:
- SE-0148 Generic Subscripts
- SE-0154 Provide Custom Collections for Dictionary Keys and Values
- SE-0165 Dictionary & Set Enhancements
- SE-0172 One-sided Ranges
- SE-0173 Add
MutableCollection.swapAt(_:_:)
Other Notable Changes
Finally, there are some miscellaneous changes worth noting as part of this release pertaining to the language:
- SE-0104 Protocol-oriented integers
- SE-0142 Permit where clauses to constrain associated types
- SE-0156 Class and Subtype existentials
- SE-0160 Limiting @objc inference
- SE-0164 Remove final support in protocol extensions
- SE-0169 Improve Interaction Between private Declarations and Extensions
You can find the exhaustive list of changes and original proposals at Swift.org.
App Store Publishing Changes
iOS 11 users of the App Store would have already noticed that it is sporting a completely new design with whole new sections, providing developers with new ways in which they can promote their apps and communicate with their users.
We will start off by taking a look at the new marketing icon that you will now be required to upload with your app updates.
Marketing Icon
Mandatory | Higher Priority
As of iOS 11, for any new submissions, whether your app is new or an existing one, you will need to include an icon-1024.png—a 1024×1024 sized marketing icon. Conveniently enough, you won’t need to submit the icon via iTunes Connect, but through Xcode, by going to Images.xcassets and adding the appropriately sized image, the same way you manage your other icons:
The marketing icon is used as part of the new App Store design process, to show a larger image icon representing your app in the Today section, or other sections where the app graphic is enlarged.
Promoting In-App Purchases
Optional | Lower Priority
Apple has made the process of in-app purchases more prominent and transparent, allowing users to view all the in-app purchasing options directly via the same level as the app product display, and in fact, even initiate an in-app purchase for the app whilst downloading the actual app. Think of a subscription app where users who download your app may already want to purchase their subscription. iOS 11 makes this quicker and more convenient.
As of iOS 11, developers are able to promote up to 20 in-app purchases such as subscriptions on their app’s product page. These purchase options will also appear in search results.
Promoting in-app purchases can also encourage downloads of your app. When a user doesn’t have your app installed but wants to buy a promoted in-app purchase, they’ll receive a prompt to download the app first. Once the app is downloaded, the transaction will continue in the app. (Apple)
To enable greater in-app purchase promotion visibility, in iTunes Connect you will need to include the following metadata:
- Image: This is the unique promotional image representing your in-app purchase, appearing on your App Store product page, Today, Games, and Apps tabs, as well as other prominent areas. This should not consist of a screenshot or represent your app’s icon, but rather represent what the in-app purchase does. The image should also be in PNG format, and high quality with dimensions of 1024 x 1024.
- Name: The display name of the in-app purchase, consisting of a maximum of 30 characters. This should be specific, befitting the function of that specific in-app purchase. If it is a subscription, say so, and ensure the duration of the subscription is included in the title, such as “One Month All-Access Subscription”.
- Description: 45 characters long, descriptions provide context for the users to understand and appreciate the benefits of your specific in-app offering.
For more information on promoting your in-app purchase, refer to Apple’s official guidelines as well as Apple’s Product Page guidelines.
Communicating With Your Customers
Optional | Lower Priority
Something that is definitely long overdue, and Android developers have enjoyed for quite some time, is the ability to respond directly to user comments. As of iOS 11, developers can now also directly respond to their users’ reviews and comments. While this doesn’t require any technical changes and participation is optional, developers through iTunes Connect (App > Activity > Ratings) can respond to praise as well as criticism.
Individualized developer responses can be leveraged in order to build stronger and more intimate relationships, fostering deeper engagement, by showing that their feedback is being reviewed and responded to, and issues they raised are actively being listened to. To respond to comments, simply go to iTunes Connect where you can view the feedback and respond individually.
Besides the new developer comments feature, Apple have also provided a new formalized SDK to prompt users to rate and review apps. The new SKStoreReviewController
should be used instead of any third party or manual prompting of users for reviews, because Apple wants the operating system to be able to control the frequency of the prompts as well as their visual appearance. Apple will thus constrain prompts to no more than three times in a 365-day period.
To implement SKStoreReviewController
, simply import StoreKit and call requestReview()
as shown below:
... import StoreKit ... SKStoreReviewController.requestReview() ...
While Apple hasn’t outright banned the other methods of prompting users for feedback, expect this to change in the near future, so it’s best that you start thinking of implementing Apple’s prompt-to-review engine over the next year.
Refer to Apple’s Ratings, Reviews and Responses guidelines for more information.
Incremental Rollouts
Optional | Lower Priority
Another very useful feature iOS 11 brings to developers is the ability to release their apps to users incrementally. Apple calls this phased releasing, and it’s intended to reduce the risk of overloading the production environment all at once, instead rolling out the release updates over a seven-day period.
Under Version Release in iTunes Connect, there is a new section called Phased Release for Automatic Updates, which gives you the option of either releasing immediately or over the seven-day period. Developers are also able to halt the phased roll-out for up to 30 days, which would normally happen if a major issue is discovered and reported.
The phased roll-out doesn’t prevent users from getting the update manually from the App Store, but rather is targeted at users who use the iOS automatic download setting in the App Store.
Next, let’s take a look at the visual changes that were introduced as part of iOS 11, as we go through the important as well as the less important topics.
UI Changes
After looking at the architectural as well as the app store publishing changes for iOS 11, we are now ready to dissect the visual changes and help you prioritize what UI changes should be tackled first.
Importantly, while we certainly could build our iOS apps without implementing any of the changes in this section, addressing only the architectural and App Store changes, you may first want to ensure that your app visually supports the new iPhone X. This means changes to the navigation bars to address the new physical ‘notch’ at the top.
With that in mind, we will look at updating your UI for the iPhone X first up, followed by some other quick changes that will ensure your app appears modern and up-to-date.
Updating Your UI for iPhone X
Mandatory | Higher Priority
One of the most important tasks in updating your iOS app is ensuring is ensuring your app looks good and works nicely on the newer devices, whilst not breaking your previous device support. That’s why Apple has worked very hard to provide developers with tools such as Auto Layout to design for screen-agnostic layouts, be it the iPhone 4, 5C, or the 6 and 6 Plus. As of this year, we now have a phone that not only has new dimensions, but also has a physical notch at the top.
Notice that we don’t have a rectangle viewport anymore, and with the new notch at the top for the physical sensors, how does Apple recommend you deal with that? For one thing, Apple don’t want you to place black bars at the top to hide the notch! Instead, they are advocating for developers to embrace it.
Don’t mask or call special attention to key display features. Don’t attempt to hide the device’s rounded corners, sensor housing, or indicator for accessing the Home screen by placing black bars at the top and bottom of the screen. Don’t use visual adornments like brackets, bezels, shapes, or instructional text to call special attention to these areas either. (iOS Human Interface Guidelines)
You will need to design for the full-screen experience, leveraging the new device’s bezel-less design while not obscuring parts of your UI with either the device’s rounded corners or sensor housing (notch).
The good news is, Apple’s system-provided UI elements from UIKit such as the UINavigationBar
already conform and adapt to the new design requirements out of the box. However for any custom UI elements, you will need to do the conformance work yourself.
Looking at the images of the iPhone 4.7 compared to the new iPhone X above, you will notice how the status bar is now implemented differently, starting with its height, which has grown from the historical 20 pt to 44 pt on the iPhone X.
Apple suggests that app developers who have been hiding their status bars should reconsider that decision in light of the iPhone X and only hide it in landscape mode, not portrait mode.
Finally, make use of the Safe Area Layout Guides by leveraging Auto Layouts as your primary measure to ensure your app fits within its appropriate margins, guaranteeing no visual obstructions, such as underlapping the status bar or navigation bar.
Two excellent resources to help get you started with designing for the iPhone X are the following WWDC videos:
- Designing for iPhone X – Fall 2017 – Videos – Apple Developer
- Building Apps for iPhone X – Fall 2017 – Videos – Apple Developer
Implementing Drag & Drop
Optional | Lower Priority
One of the most talked about new SDKs at this year’s WWDC is drag & drop. This is something desktop users have been accustomed to for a very long time, but its absence in the iOS platform meant the iPad and iPhone have never truly embraced multi-tasking. In iOS 11, this has changed, as the new iOS will support UI elements being dragged not only within the same screen, but from one application to another.
Leveraging iOS’s multi-touch engine, users can effortlessly move content in a natural way between apps on the iPad (or just within the same screen on the iPhone) by tapping and holding on an image, file, text, or specific UI element to drag it. This is already integrated system-wide in iOS, allowing users for instance to drag text from Safari into the dock’s Reminders app to create a new reminder item.
This hasn’t been flagged as mandatory for implementation, but because it will rapidly become an expected behavior due to its prevalence system-wide, it is suggested that you try and prioritize this sooner rather than later, so that you can make your app’s UX conform to the new standard system UX behavior.
UIKit comes with some level of drag & drop support built-in, for components such as UITables
and UICollectionViews
, but you will need to bridge and adapt the elements with code so that other components can receive the dragged component. This can be somewhat involved, and it’s outside the scope of this article, but I’ll cover drag & drop support more fully in a follow-up post next week.
For now, briefly, you would add and support drag & drop in your ViewController
’s viewDidLoad()
method, by implementing the two delegates shown below:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UITableViewDropDelegate, UITableViewDragDelegate { ... func viewDidLoad(){ ... firstTableView.dragDelegate = self // You associate the drag delegate to this table secondTableView.dropDelegate = self // You associate the drop delegate to this table firstTableView.dropDelegate = self secondTableView.dragDelegate = self firstTableView.dragInteractionEnabled = true secondTableView.dragInteractionEnabled = true ... } ... func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] { //(1) Drag is being initiated } func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) { //(2) Drop is being initiated }
Stay tuned for our upcoming article on how to add Drag and Drop support to your iOS 11 app.
Other UIKit & Auto Layout Changes
Optional | Lower Priority
Finally, let’s take a look at the remaining UIKit changes new to iOS 11, starting with the UINavigationBar
, which has some notable improvements, including the integration of SearchViewController
and large titles. We then take a look at the improvements to UITableView
, from the new and improved swipe actions to table view cells automatically self-sizing.
Navigation
We already touched on navigation bars earlier on when discussing the iPhone X and how it aligns with the new status bar dimensions. Besides that, the new contemporary design style advocated for in iOS includes new larger titles in navigation bars, first seen in the Apple Music App in iOS 10 and since then an established design pattern across all of the other system apps in iOS.
The larger title text provides greater emphasis on the context of the screen in a navigation bar, and helps orient users as to the active tab while navigating through the various tabs. The size of the title text is not static but rather shrinks as the user scrolls down, reverting to the pre-iOS 11 style. Inversely, when you pull down in a scroll view, the title text will increase slightly.
Use a large title when you need to provide extra emphasis on context. In some apps, the big, bold text of a large title can help orient people as they browse and search. In a tabbed layout, for example, large titles can help clarify the active tab and inform the user when they’ve scrolled to the top. Phone uses this approach, while Music uses large titles to differentiate content areas like albums, artists, playlists, and radio. A large title transitions to a standard title as the user begins scrolling content. Large titles don’t make sense in all apps and should never compete with content. Although the Clock app has a tabbed layout, large titles are unnecessary because each tab has a distinct, recognizable layout. (iOS Human Interface Guidelines))
As a developer, it’s up to you to decide if and when to implement the large text style, based on Apple’s Human Interface Guidelines, and Apple recommends you specifically use the large text titles only for top-level navigation screens rather than across all levels. To enable large text, simply add the following property to your UINavigationController
:
navigationController?.navigationBar.prefersLargeTitles = true
Hierarchically, both the master and detail view controllers under the navigation bar will have the large text mode enabled by default due to parent inheritance, and as just mentioned, it is advisable to only have the top-level navigation screens implement the large text mode. To suppress the large text inheritance in your detail screen, go to your view controller and add the following to its initializer (it has to be set at initialization time):
required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) navigationItem.largeTitleDisplayMode = .never }
The largeTitleDisplayMode
above is being set to .never
. Without that line, the default is .automatic
, which is where the detail view controller inherits the properties of its parent view controller.
Search View Controllers
Search can now be integrated directly into navigation bars without needing to associate the UISearchViewController
instance with the subject view controller (and its table header view) separately. As of iOS 11, you can elegantly embed the search bar in the navigation bar:
navigationItem.searchController = UISearchController(searchResultsController: nil)
You will also need to conform to UISearchResultsUpdating
to react to search terms, of course. While iOS automatically hides the search bar based on the number of rows in your table view, you can force the search bar to be visible at all times by toggling:
navigationItem.hidesSearchBarWhenScrolling = false
UITableViews
Finally, we take a look at two new and distinguished features introduced to UITableViews
as of iOS 11: self-sizing and improved swipe actions. Self-sizing was introduced way back in iOS 8 to alleviate the burden of developers having to manually size table view cells, with the ability to dynamically size the cells to fit the contents of the row using Auto Layout. Until now, you had to explicitly request auto-sizing using:
tableView.rowHeight = UITableViewAutomaticDimension tableView.estimatedRowHeight = 100
As of iOS 11, it is on and set by default with no extra code, but you still have the ability to specify your own row height explicitly, as needed. iOS 11 has also brought about new leading and trailing swipe actions, prevalent in many system apps such as Apple’s very own Mail app.
In addition to being able to being able to swipe either left or right, you can also attach images to associate with these actions. You implement two delegate methods as part of the UIContextualAction
, for leading and trailing swipe actions:
override func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { let trash = UIContextualAction(style: .normal, title: "Delete") { action, view, completionHandler in print("Delete") completionHandler(true) } delete.backgroundColor = UIColor.red delete.image = UIImage(named: "delete") let actionGroup = UISwipeActionsConfiguration(actions: [delete]) actionGroup.performsFirstActionWithFullSwipe = false return actionGroup } .. override func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { let archive = UIContextualAction(style: .normal, title: "Archive") { action, view, completionHandler in print("Read") completionHandler(true) } archive.backgroundColor = blue archive.image = UIImage(named: "archive") let move = UIContextualAction(style: .normal, title: "Move") { action, view, completionHandler in print("Move") completionHandler(true) } move.backgroundColor = purple move.image = UIImage(named: "move") let actionGroup = UISwipeActionsConfiguration(actions: [archive,move]) actionGroup.performsFirstActionWithFullSwipe = false return actionGroup }
Using the code above, you can create more than one contextual action and add it to the UISwipeActionsConfiguration
grouping instance, for more than one action. This is a simple yet engaging improvement to bring greater elasticity to your table views, with minimal code changes, and while not mandatory, it’s worth allocating a few hours to it in your sprint planning board.
Conclusion
In this post, I’ve given you an overview of the changes across the architecture, App Store, and visual components of iOS 11, providing you with an idea of what you will need to action immediately, and what can be deferred until a later time. Migration to iOS 11 and Swift 4 will be a lot easier than it was in the previous years’ updates.
Beyond the imminent changes that need to be made, we’ve also gone through the Swift 4 changes that improve strings and collections, as well as the visual improvements to UITableView
and Search Controller. This should make it easier for you to plan your work to make updates to your app!
Stay tuned for my upcoming post on implementing drag & drop for your iOS 11 apps, and in the meantime, check out some of our other posts on new changes to iOS and Swift!
-
XcodeWhat’s New in Xcode 9?
-
iOS SDKFaster Logins With Password AutoFill in iOS 11
-
SwiftWhat’s New in Swift 4
Powered by WPeMatico