IBOutlet Local Reasoning: What, why, and how

Did you watch Protocol and Value Oriented Programming in UIKit Apps from WWDC 2016 yet? I did and it’s one of my favorite sessions yet. It was essentially a part 2 from the WWDC 2015 session, Protocol-Oriented Programming in Swift. It even included a cameo of Crusty. I really liked the session because it gives some plain talk explanation towards improving your Swift code through basic functional programming techniques, and it was specifically attractive to me because of this year’s session’s focus on UI code. UIKit code is filled with object-oriented techniques and patterns like MVC and subclassing that it’s hard for a chiseled object-oriented veteran to learn new tricks like functional programming.

State is Bad

Relying on instance variables in your objects leads to buggy code. Furthermore, it leads to code that’s not just buggy, but also simply hard to debug. You should strongly consider any case where you introduce an instance variable that will be used for state management. Consider the following view controller:

class ViewController: UIViewController {

  var total = 0

  override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    if (total > 0) {
      print("total bigger than 0")
    }
  }

  func incrementTotal() {
    total = total + 1
  }
}

This code has an outrageous example of relying on an instance variable to determine state of the object. total is an Int. The major problem I have with code like this is the conditional if-statement in viewDidAppear(_:). This is a simple example, so it may not seem problematic to you. Imagine if the view controller had significantly more code, where total was referenced all over the code. Imagine there were numerous places where total was getting assigned to. Imagine there were numerous places where total was being used for conditional checks. Imagine that even external classes were reading and modifying total. Imagine all the places you would have to check and be aware of to ensure that total behaved correctly such that the view controller properly functioned. It quickly grows out of control. Code like this has been the source of more bugs than I can count in my UIKit programming. It’s why functional programming is so attractive to me, despite how hard it is for my head to wrap around some of the concepts.

Local Reasoning

One of the absolute most attractive things about functional programming in my mind is the lack of “side effects” of your code. Essentially, you strive to write code that does not have side effects, where there is a single “source of truth.” This is one of the cores of value oriented programming. When working towards this, you begin to write code that is much easier to debug and much less buggy to begin with. It’s much easier to understand code just by looking at it. One of the biggest anti-patterns of object oriented code is managing state of an object through a instance variable.

In the WWDC 2016 session Protocol and Value Oriented Programming in UIKit Apps the concept of “Local Reasoning” is introduced. It’s a semi-official computer science term that describes code which contains little to no side effects. Local reasoning is that “when you look at the code right in front of you, you don’t have to look at the rest of the code or project to know how it behaves.” This is really attractive because when you look at a piece of code, you can quickly have confidence that you understand what it does because you don’t need to look in many places. Instance variables that control object state are the enemy of local reasoning. For example, looking at the code above, any reference to total contains the caveat that there could be any number of things modifying total throughout program execution. You can never rely on the value of total to actually make a decision about the state of the program.

IBOutlet Local Reasoning

Of course you can’t actually remote all instance variables from your code. You’ll inevitably find certain scenarios where some state must be stored. One common such example are IBOutlets. IBOutlets are special snowflakes in the software design world. Pretty much any rule about software design may not apply when using IBOutlets. When using a Interface Builder file or a Storyboard, you’ll need to subclass UIView or UIViewController and link user interface elements from Interface Builder to the code through IBOutlets. The thing is, IBOutlets take the form of instance variables in code.

class ViewController: UIViewController {
  @IBOutlet weak var toggleSwitch: UISwitch!
}

So how can you apply IBOutlet local reasoning to improve your code? My coworker Mike Stanziano had a really useful idea on how to do this: use a property observer on the IBOutlet.

Let’s say that you want to create a UISwitch in your storyboard. The state of this switch will correspond to a boolean value in a persistence layer, the example will use UserDefaults. Initializing the value usually would happen in viewDidLoad() like:

override func viewDidLoad() {
  super.viewDidLoad()
  let keep = UserDefaults.standard().bool(forKey: "ToggleValue") ?? false
  toggleSwitch!.setOn(keep, animated: false)
}

Maybe you could use the Extract Method refactoring to move those two lines to their own method, but my point is that this code immediately violates local reasoning and starts you off on the wrong foot in using your IBOutlet. I’d consider this code part of initialization of the UISwitch, so it doesn’t make sense to put it in viewDidLoad() aside from the semi-artificial rule put in place by UIKit in that views should be setup in viewDidLoad().

Inspired by Protocol and Value Oriented Programming in UIKit Apps, my colleague Mike came up with something better:

@IBOutlet weak var toggleSwitch: UISwitch! {
  didSet {
    let keep = UserDefaults.standard().bool(forKey: "ToggleValue") ?? false
    toggleSwitch!.setOn(keep, animated: false)
  }
}

This code moves the initialization of the UISwitch‘s state out of viewDidLoad() to a place that I argue is much more appropriate, where the IBOutlet is defined. Since IBOutlets don’t get init’d in code, their definition is the closest thing we have towards an actual instantiation. Now, when you look at the definition of the IBOutlet, you immediately know how it’s initial state is configured. This is right in line with the local reasoning – “when you look at the code right in front of you, you don’t have to look at the rest of the code to know how it behaves.”

And of course, writing a unit test for this code is extremely straightforward.

func testSwitch_DisplaysStoredSwitchState_WhenToggled() {
  // Start the switch on
  UserDefaults.standard().set(true, forKey:"ToggleValue")
  UserDefaults.standard().synchronize()

  let toTest = ViewController()
  let testSwitch = UISwitch()
  toTest.toggleSwitch = testSwitch

  XCTAssertTrue(toTest.toggleSwitch.isOn)
}

No need to call viewDidLoad() from your test. Simply set the desired value on the UISwitch and verify the behavior.

Clean Code is Clear Code

I love the principle of local reasoning in your code. I’m all about writing clean code, I even named this blog after it. Give IBOutlet local reasoning a try and I think you’ll like it. Clean code is enabled by clear code, and local reasoning leads you to clearer code. Give it a try. Here’s a project on GitHub with this code all wired up using Swift 3 and Xcode 8.

Happy cleaning.

VIDEO: Extract Method Refactoring

In “Refactoring, Improving the Design of Existing Code” by Martin Fowler, he presents the Extract Method refactoring. It is one of the best refactorings out there. It’s one of the most common ones that I use.

Here’s a video walkthrough of the Extract Method refactoring and its benefits:

Video Transcription

Hey, what’s up everybody, it’s Andy from cleanswifter.com, and I’m back this week to actually continue our series on reading “Refactoring, Improving the Design of Existing Code” by Martin Fowler. This week for the first time, we’re going to look at an actual refactoring in code. The refactoring we’re going to look at is called “Extract Method.” Extract Method is actually a really easy refactoring, it’s often supported by IDEs and the benefit of it is that it increases the opportunity for code reuse, you’ll have less duplication of your code, it enables smaller units of code, so it helps you get rid of those really long methods. And it also reduces the semantic distance between the method name and method purpose. I really like that wording that Fowler actually used in the book. That means your method names will be very clear and close to what the method actually does. As a result, for that to happen, your method needs to be succinct and cohesive. Extract method refactoring enables this. Let’s take a look at it.

Here’s a class, AccountViewController that subclasses UIViewController. Right here in viewDidLoad() is some simple code that creates two UILabels. Three properties are set on each label: the text color, the text alignment, and the number of lines. There are actually two different labels on which these properties are being set. But what’s in common between these two pieces of code, is that, the three properties are being set on the label are exactly the same. This is a prime opportunity to leverage the Extract Method refactoring. For Extract Method, all we’re going to do is create a new method called setUpLabel. In there, I’ll add a parameter that is the label to be set, and on that label, I’ll take this code, remove it from viewDidLoad() and add it to this new method that we’re extracting, and then down in viewDidLoad(), call the new method by providing the label. Down where the second label is setup, I can also then delete this code and call that same method with the addressLabel. Now you can see we’ve removed the redundant code that is setting up the label, and now we have a dedicated method that is named very clearly for what it does: sets up a label. The redundant code for addressLabel has also been consolidated.

Let’s make the example a little more complicated. In this example we see the similar three lines of code setting up the label that configure the text color, the text alignment, and the number of lines. To make it a little more complicated, we’re actually going to set the text on the two labels as well. nameLabel will be set to “Andy” and addressLabel will be set to “Philadelphia.” Now we want to perform a refactoring that removes redundancy while also preserving the ability to set the test on the labels. We’ll start off in the same way as before, creating the new method setUpLabel. Move forward with the refactoring to get to the same point we were at in the last example. Now that a baseline for setUpLabel is extracted, we need to update it to be able to accept a String such that the text on the label may be set, and the redundant use of temporary variables in viewDidLoad() can be removed. Add a parameter to setUpLabel of type String called text. Set the text on the UILabel‘s text. Update the method call to setUpLabel in viewDidLoad to actually pass in the text to be set. Do the same thing for addressLabel. At this point, we’ve removed redundancy and consolidated the code which includes setting the label’s text based on a provided parameter. There’s one more level of complication that we can add while leveraging the Extract Method refactoring.

Increasing the complexity of the example towards something even more real-life is to add properties on the view controller for each label so the values that are created are stored. After setUpLabel is called, we’re now storing the label in the property on the class. To further reduce the redundant code, I’m going to extract the label creation into setUpLabel. That will cause me to return the created label so that it can be set on the property. The goal of what I want to do here, is delete the creation of the UILabel in viewDidLoad() and move it to setUpLabel(). I will no longer need to pass the created label in to setUpLabel(). Instead, I will create a new UILabel each time setUpLabel is called. Then using that new label, set it’s properties, and return it. Now you can see the final result of the refactoring where all the redundant code has been consolidated into one place, a method dedicated to setting up labels. viewDidLoad() now reads very clearly.

You just saw an example of the Extract Method refactoring. Just to recap it’s benefits: it increases the opportunity for code reuse by reducing duplication, it enables smaller pieces of code (as you saw viewDidLoad and setUpLabel become small). And finally, decreases the semantic distance between the method name and method purpose – which means you can create a nice small method with a nice clear name that reflects what the method does.

I hope you liked this screencast on the Extract Method refactoring from “Refactoring, Improving the Design of Existing Code” by Martin Fowler.

Weekend Reading, June 24, 2016

Weekend Reading for June 24, 2016, click here

Happy Friday fellow Clean Swifters. It’s been a crazy week of watching and writing about WWDC videos and new technology for me. Xcode 8 beta has been fairly stable for me, and it’s really fun digging into some of the new frameworks.

I’d love to hear from you, what topics are you interested in hearing about on cleanswifter.com? Just reply to this email and let me know.

Get “Weekend Reading” delivered in your email, as well as every other cleanswifter.com post, and receive a free screencast on iOS automated testing by signing up here. “Weekend Reading” is created through AWeber’s app, Curate, which I helped create and is entirely written in Swift.

Happy cleaning

iOS 10 UICollectionView Highlights

Did you get a chance to watch the WWDC 2016 session, “What’s New in UICollectionView in iOS10″ yet? I watched it today. There is some good stuff in the session, and I want to recap it for you in this post. The session is broken into three segments that capture everything that’s new for an iOS 10 UICollectionView :

Improvements to:

  • Smooth Scrolling
  • Self-Sizing Cells
  • Interactive Reordering

There is a special bonus fourth segment as well, but I’ll save that for later.

Smooth Scrolling Enhancements

In iOS 10, there are several enhancements that will improve the performance of your UICollectionViews – some of which you will manually need to leverage, and some you will get for free. Before dropping into the new features of iOS 10 UICollectionView, the presenter gives a nice overview of what it means to “drop frames” and what it’s bad.

Don’t Drop Frames

In order for your app to have “buttery smooth” performance, a hallmark of iOS apps, you must strive for app animation that performs at 60 frames per second. This means that a given frame of the user interface must be displayed in less than 16.67ms in order for the animation to appear “smooth.” Otherwise, when the frame rate drops lower than that, it’s apparent to the user in the form of a choppy animation. The easiest way to make the frame rate drop, is to do things like add blocking, long running method calls on the main thread in the middle of your animation. Here’s an in-depth article from Facebook on how they measure and ensure a highly performant news feed in their app.

Less Aggressive Loading and Unloading Cells

In a UICollectionView, the lifecycle of a cell is as follows:

  1. prepareForReuse
  2. cellForItemAtIndexPath – The heavy lifting of populating your cell’s data from your model happens here.
  3. willDisplayCell – Lightweight preparation for when you cell is about to go onscreen.
  4. Cell comes on screen, and as scrolling continues starts to move offscreen.
  5. didEndDisplayingCell

In general, this flow is unchanged between iOS 9 and iOS 10. The different is when these methods are called. Apple has optimized when willDisplayCell is called. In iOS 10, it’s now called at the very last minute before the cell goes on screen. This helps to balance out the CPU performance in drawing cells, but not executing that code too early. Additionally, another enhancement Apple has made in iOS 10 UICollectionView is that cells are not put on the reuse queue as aggressively as in the past. Instead, after a cell leaves the screen, it is kept around a little longer in case the user decides to swipe the cell back on screen.

Cell Pre-fetching

Apple also enhanced UICollectionView such that by default, cells are pre-fetched. This means that you can get even earlier awareness of when data for a cell is needed such that you can retrieve it. For example, if you are building a UICollectionView full of remote images. Leveraging the UICollectionViewDataSourcePrefetching, UIKit will call:

collectionView(_:prefetchItemsAt:)

to allow for you to start downloading the images with Grand Central Dispatch of an NSOperationQueue such that when the cells containing the images comes on screen, the images will be downloaded and ready to go.

If you need to, you can opt out of this behavior by setting isPrefetchingEnabled to false, but why would you?

As part of pre-fetching, realizing that cellForItemAtIndexPath may be called for cells that never end up coming on screen – because the user stopped scrolling before they were shown. Also, it’s really important that you keep the work in willDisplayCell and didEndDisplayingCell really light. All the heavy lifting goes in cellForItemAtIndexPath. Apple described pre-fetching as an “adaptive technology” which I assume to mean that it’s level of “predictiveness” varies by use case for a given application.

And as bonus, this exact same pre-fetching API is also available on UITableView via UITableViewDataSourcePrefetching.

Self Sizing Enhancements

Prior to iOS 10, estimatedItemSize has existed on UICollectionViewFlowLayout in order for you to provide an estimate size for the items in your collection view. Sometimes it’s hard to predict the size of items in your UICollectionView. Realizing this, Apple has introduced automatic item sizing for your UICollectionViewFlowLayout. Simple set the item size to the constant UICollectionViewFlowLayoutAutomaticSize and UIKit will make smart guesses based on past measurements of your items in order to automatically predict item sizes for future items.

According to Apple:

It will keep a running tally of all the cells it’s already sized, and use that to influence its future sizing estimates…making the sizing much more accurate…leading to better performance and a more accurate layout.

Interactive Reordering Enhancements

Reordering a iOS 10 UICollectionView has also undergone some improvements as well. Prior to iOS 10, if you didn’t already know (and I only learned recently), it’s really easy to enable reordering on your UICollectionView – in your UICollectionViewDelegate, simply implement:

func collectionView(_ collectionView: UICollectionView, targetIndexPathForMoveFromItemAt originalIndexPath: IndexPath, toProposedIndexPath proposedIndexPath: IndexPath) -> IndexPath

There are some additional methods on UICollectionView that you should take a peak at too that enable you to add more advanced animation and update your data model if appropriate.

New in iOS 10 UICollectionView is the ability to reorder with paging!

collectionView.isPagingEnabled = true

That’s it! The presenter describes it as an interaction that feels just like moving icons between pages on your home screen.

The Bonus

Finally, the big reveal happens. It’s as if this is such exciting news worthy of a WWDC reveal, but there is no other session appropriate for it. The presenters reveal that pull to refresh will be supported on:

  • UIScrollView
  • UITableView
  • UICollectionView

If it wasn’t awesome enough that UIScrollView and UICollectionView got the control, but you are also no longer constrained to needing a UITableViewController if you want an out of the box pull to refresh control (which was a pretty annoying prior limitation in my opinion).

Final Thoughts

I have plans to do an in-depth example of how to use pre-fetching with Grand Central Dispatch in order load remote images in a UITableView sometime in the future. I recently ran into a problem in one of my apps that this exact thing would have solved. Essentially I had cells in a UITableView that were of varied height based on a remote UIImage being loaded. I ended up needing to set a static height on the cells to achieve a high frame rate and scaling the images, instead of properly sizing the cells according to the natural height of the image. It wasn’t the end of the world, but there was some extra white space in the cells that wasn’t needed. How do you plan on using these new changes to iOS 10 UICollectionView?

Happy cleaning.

iOS 10 UNUserNotificationCenterDelegate Overview

I just finished watching “Introduction to Notifications” from WWDC 2016 and there are some really cool new features for iOS 10 local notifications. Notifications are core to the mobile experience, regardless of what platform you’re using – Android, iOS, or something else. Apple really raised the bar with their iOS 10 local notifications through creation of a new framework, the User Notifications framework. The brand new iOS 10 UNUserNotificationCenterDelegate in the User Notifications Framework is one thing that jumped out at me.

Why Create A New Framework?

Push notifications have been available in iOS for years. Just like any framework, over time, as use cases and technology evolves, frameworks need to be reconsidered and improved. It is that time for push notifications on iOS. New in iOS 10, Apple created the User Notifications Framework. When implementing notifications, you have the choice to implement a local or remote notification. A local notification does not require a server to alert the user, where a remote notification does require a remote server to send information to the user. In past iOS versions, depending on the type of notification you are handling, there are two different methods in UIApplicationDelegate to implement to handle either notification type – remote or local. As such, this can lead to a lot of duplicate code since it’s likely that there is common handling of notifications regardless of whether they are local or remote.

One Notification Handler To Rule Them All

The User Notification Framework in iOS 10 fixes this as there is now a single method for handling both types of notifications. The new iOS 10 UNUserNotificationCenterDelegate now has a single set of methods for handling both remote and local notifications.

Deprecated

The old methods on UIApplicationDelegate are deprecated, including:

  • application(_:didReceive:) – Sent to the delegate when a running app receives a local notification.
  • application(_:didReceiveRemoteNotification:) – Called when your app has received a remote notification
  • application(_:handleActionWithIdentifier:forRemoteNotification:completionHandler:) – Tells the app delegate to perform the custom action specified by a remote notification.
  • application(_:handleActionWithIdentifier:for:withResponseInfo:completionHandler:) – Called when your app has been activated by the user selecting an action from a local notification.
  • application(_:handleActionWithIdentifier:forRemoteNotification:withResponseInfo:completionHandler:) – Called when your app has been activated by the user selecting an action from a remote notification.

New

Instead, these are all consolidated into a TWO METHODS in the new iOS 10 UNUserNotificationCenterDelegate protocol:

  • userNotificationCenter(_:didReceive:withCompletionHandler:) – Called to let your app know which action was selected by the user for a given notification.
  • userNotificationCenter(_:willPresent:withCompletionHandler:) – Delivers a notification to an app running in the foreground.

That’s right, two methods. And what’s better, is that now that they are moved into their own protocol, the iOS 10 UNUserNotificationCenterDelegate so this will help clean up your existing UIApplicationDelegate by being able to refactor all that old notification handling code into a shiny, new, cohesive protocol of it’s own.

Here’s an example:

extension NotificationManager: UNUserNotificationCenterDelegate {

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {

        switch response.actionIdentifier {

        // NotificationActions is a custom String enum I've defined
        case NotificationActions.HighFive.rawValue:
            print("High Five Delivered!")
        default: break
        }
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {

        // Delivers a notification to an app running in the foreground.
    }
}

That’s literally it for handling notifications.

Bonus: Creating Local Notifications

Similar, creating local notifications has also been simplified. In order to verify the behavior of the new iOS 10 UNUserNotificationCenterDelegate protocol, I wrote some sample iOS 10 User Notifications Framework code to generate a local notification:

// 1
let highFiveAction = UNNotificationAction(identifier: NotificationActions.HighFive.rawValue, title: "High Five", options: [])
let category = UNNotificationCategory(identifier: "wassup", actions: [highFiveAction], minimalActions: [highFiveAction], intentIdentifiers: [], options: [.customDismissAction])
UNUserNotificationCenter.current().setNotificationCategories([category])

// 2
let highFiveContent = UNMutableNotificationContent()
highFiveContent.title = "Wassup?"
highFiveContent.body = "Can I get a high five?"

// 3
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)

// 4
let highFiveRequestIdentifier = "sampleRequest"
let highFiveRequest = UNNotificationRequest(identifier: highFiveRequestIdentifier, content: highFiveContent, trigger: trigger)
UNUserNotificationCenter.current().add(highFiveRequest) { (error) in
  // handle the error if needed
  print(error)
}

Here’s an overview of that code block:

  1. Create the custom “High Five” action for responding to the local notification, and set it as a category for the notification in addition to a system provided category for simply “dismissing” the notification.
  2. Create the content for the local notification.
  3. Create the trigger for the notification, for it to pop 5 seconds in the future.
  4. Add the notification to the notification system.

This code highlights two new features of local notifications in iOS 10, custom actions and time based triggers.

Custom actions now let you specify any number of actions for which the end user may respond to the notification.

iOS 10 UNUserNotificationCenterDelegate

Time based triggers allow you to delay the local notification by a time interval, designate it as repeating or not, and even schedule it based on an actual date.

I didn’t hear it confirmed in the WWDC presentation, but I’m pretty sure that the custom notification actions require 3D Touch. I could not figure out how to interact with them on my iPhone 5s device that is running iOS 10.

I’ve even bundled all this code up into an Xcode project for you on GitHub, here.

Notify Me

Notifications, remote and local, enable some of my favorite features on iOS so as an end user, I’m happy to see all these enhancements. As a developer, I can’t wait to try them out in my own app. This only scratches the surface of the new stuff Apple added. Do you use notifications in your app? What are you looking forward to most about the new iOS 10 User Notifications Framework? What about the iOS 10 UNUserNotificationCenterDelegate?

Happy cleaning.

UIPasteboard iOS 10 Example

I just finished watching What’s New in Cocoa Touch today from WWDC 2016, it was an awesome session. My coworker called it “the index for the rest of WWDC.” Olivier Gutknect basically goes on rapid fire for an hour citing change after change in UIKit for iOS 10. For each thing he mentions, he covers varied levels of detail, and usually references a different WWDC session where the framework or topic will be covered in more detail. The UIPasteboard iOS 10 API made an appearance in this session, just like the keynote. When I heard about the Universal Clipboard changes for iOS 10 and macOS Sierra, I was so excited to actually be able to use this new feature as an end user. It’s so cool, leveraging Handoff and continuity, iOS and macOS will intelligently share your clipboard across devices. This means I can copy something on my laptop, and then pickup my iPhone and have that most recent thing copied available for pasting.

As a developer, I was also curious to see what new changes were in store in the UIPasteboard iOS 10 API.

In order to take advantage of the new Universal Clipboard in your apps, you don’t need to do anything differently than you’ve been doing, just use the UIPasteboard API. That being said, in order to provide the best user experience, there’s two changes to the UIPasteboard iOS 10 API that are related to the Universal Clipboard:

  1. Methods to help understand what is in the clipboard.
  2. Methods to designate the lifetime of the clipboard item.

Understanding the Clipboard Contents

Some of the changes to the UIPasteboard iOS 10 API enable you to inspect the contents of the clipboard to understand what type of contents are in the clipboard. Is it a color? Is it an image? Is it a string? Is it a URL? As a developer, you can intelligently take advantage of this. For example, say your app contains a color picker. You could provide a standard looking color picker, while also observing that the clipboard contains a color and show it as well.

Here’s an example:

// Setup, let's put some stuff in the UIPasteboard

let pasteboard = UIPasteboard.general()
pasteboard.string = "andy"
pasteboard.url = URL(string: "http://cleanswifter.com")
pasteboard.image = UIImage()
pasteboard.color = UIColor.red()

// Understanding the UIPasteboard contents

if pasteboard.hasStrings {
    print("The pasteboard has Strings!")
}
if pasteboard.hasURLs {
    print("The pasteboard has URLs!")
}
if pasteboard.hasImages {
    print("The pasteboard has images!")
}
if pasteboard.hasColors {
    print("The pasteboard has colors!")
}

Designating The Lifetime of Clipboard Contents

With the changes to the UIPasteboard iOS 10 API that introduce Universal Clipboard, it also opens a slight security vulnerability in that an end user could copy a sensitive piece of data and inadvertently make it available across all their devices. The UIPasteboard iOS 10 API provides a way to lock this down. As a developer, you can either:

  • Flag a piece of data as “local only” in which it will not appear in the Universal Clipboard across devices, and
  • Set an expiration date on a piece of data such that it isn’t available after that date.

Here’s an example of flagging a pasteboard item as “local only”:

// Add a string
let aLocalOnlyStringKey = "Local only string key"
let aLocalOnlyStringValue = "Local only string value"

// Set the string in the LOCAL pasteboard
pasteboard.setItems([[aLocalOnlyStringKey: aLocalOnlyStringValue]], options: [UIPasteboardOption.localOnly : true])

In one line, you set the item in the UIPasteboard with an option localOnly as true.

Here’s an example of adding something to the pasteboard with an expiration date:

let aExpiringStringKey = "Local only string key"
let aExpiringStringValue = "Local only string value"
// Create a date 24 hours from now
let expirationDateOfTomorrow = Date().addingTimeInterval(60*60*24)

// Add the string and mark it to expire 24 hours from now
pasteboard.setItems([[aExpiringStringKey: aExpiringStringValue]], options: [UIPasteboardOption.expirationDate: expirationDateOfTomorrow])

Again, in one line you get to pass an expiration date for when the UIPasteboard item should expire. You can also use these together.

Gonna Needa Pasteboard

James Dempsey is going to need to update the lyrics to his song “Gonna Needa Pasteboard” to account for the Universal Clipboard and these new UIPasteboard iOS 10 API features. In the meantime, I absolutely can’t wait to use the Universal Clipboard, and all the while knowing that if developers properly take advantage of these new UIPasteboard iOS 10 API features, my data will be safe and my applications will be snappy.

The code from this post is available in GitHub as a playground, here.

Don’t forget, this UIPasteboard iOS 10 API is still in beta and could change between now and the public release.

Happy cleaning.

Post-Weekend Reading, June 20, 1016

Post-Weekend Reading for June 20, 2016, click here

Happy Monday fellow Clean Swifters. How was your WWDC 2016 week? I wasn’t able to make the conference in-person so I’m furiously watching as many videos as possible.

Normally, I like to get this link round-up out on Fridays. Sorry, I’m a day late. My wife and I threw a huge party this past weekend and I got caught up with prep work and wasn’t able to get this out in time. The good news is that I was able to dig up a couple links I wouldn’t have found on Friday.

Get “Weekend Reading” delivered in your email, as well as every other cleanswifter.com post, and receive a free screencast on iOS automated testing by signing up here. “Weekend Reading” is created through AWeber’s app, Curate, which I helped create and is entirely written in Swift.

Happy cleaning.

“What’s New In Swift” WWDC Session Highlights

I just finished watching What’s New in Swift from WWDC 2016 and wanted to pass on the highlights for you. “What’s New in Swift” is great session that I highly recommend you also watch for yourself. There are a couple things that jump out at me that I feel are worth writing about.

Goals For Swift 3

Unless you’re hiding under a rock, you’ll know that the big news in Swift is the upcoming release of Swift 3. This presentation kicks off immediately covering the goals for Swift 3:

  • Develop an open community
  • Portability to new platforms
  • Get core fundamentals into shape
  • Optimize Swift for awesomeness

Granted some of these are a little “soft” and not well defined, I really like the first goal. On stage, Apple did not hold back in describing that Swift 3 will be the result of total community involvement with the languages evolution – which is exactly the desired intention. This totally hits home for me. Even though I haven’t been an active participant in the language’s evolution, I’m a firm believer that the open source software model leads to better software, and for something as critical as the language that I could be using for the foreseeable future, I’m happy that it’s being evolved in such an open model.

Swift Adoption at Apple

This might be one of the first times that I’ve seen or heard Apple formally recognize and describe major uses of Swift internally in their own development. It was surprisingly extensive, and refreshing to hear them actually admit to it. Swift has been out almost two years now, and for me, one of the signs I’ve been looking for to represent Swift’s maturity is precisely this: Apple’s adoption of the language in their own products, and they finally hit the nail on the head for me. Here are some highlights:

Apple Products With Lots Of Swift

  • New Music app for iOS
  • Console app in Sierra
  • Dock app
  • Picture in Picture in Sierra (actually 100% Swift)
  • New documentation viewer in Xcode (actually 100% Swift)
  • Swift Playgrounds for iOS (actually 100% Swift)

The presenter then went on to talk further about the Dock with some really revealing information. Internally, there’s actually a lot of stuff I consider general “OS functionality” that Apple actually classifies as the Dock app. Can you believe all this is included in the Dock codebase?

  • Dock bar at the bottom
  • Mission Control
  • Command-Tab Application Switcher
  • Stacks
  • LaunchPad
  • Spaces
  • Dashboard
  • Some of Notification System

What’s interesting about the Dock app is that a significant amount of Swift code was written for it in the El Capitan release, 10s of thousand lines of Swift code out of a total of 200k lines of code total. This is interesting because it represents a case study of a non-trivial amount of code that will be migrated from Swift 2.2 to Swift 3.0, and Apple did just this. The migration resulted with about 15% less actual code! Not to mention that the engineers like the safety features of Swift as well as the more articulate code.

How To Contribute To Swift

Have you seen swift.org yet? It’s the home of Swift on the web, besides the actual repositories on GitHub. There is a ton of information on the site about everything from migrating to Swift 3, to information on how to get started with contributing to the language. It’s a lot to digest. During this WWDC session, What’s New in Swift, an extremely simple outline was provided what contributing to the Swift language looks like:

  1. Socialize your idea idea on the mailing list.
  2. Once critical mass is achieved, the idea becomes a formal proposal on GitHub.
  3. Formal review of the proposal happens once the pull request for the proposal merges into the repository. Formal review happens on the mailing list, out in the open.
  4. Core team arbitrates a decision. The rationale for the decision is always documented, regardless of whether the proposal was accepted or rejected.

All proposals, past and present, can be found in the swift-evolution repository.

Swift 3 Source Compatibility

The #1 goal for Swift 3, according to Chris Lattner, is API compatibility. This is no small task though, because decisions now will affect developers for years to come since the API will become stable. As a result, naming guidelines are carefully considered and many tweaks are made as a result. Swift 3 APIs should:

  • Strive for clarity, not terseness or verbosity
  • Capture essential information
  • Omit redundant info/boilerplate

A direct result of this is the libdispatch renaming that I wrote about a couple weeks ago. Additionally, one of the weirdest and hardest things to get used to in Objective-C for me (a prior Java developer) was it’s incredible verbosity for the sake of verbosity. Chris Latter provides a bunch of examples on stage of this new clarity, and I’m loving it.

Here’s two such examples:

array.insert(1, atIndex: 0)

becomes

array.insert(1, at: 0)

and

if url.fileURL {}

becomes

if url.isFileURL {}

I can’t wait.

There is a lot more information in this session, “What’s New in Swift”, especially some in-depth discussion of improvements and cleaning-up of Swift 3 syntax, as well as some information on tool improvements when using Swift.

One of the closing statements of “What’s New in Swift” recognized that Swift 2.3 will be a total interim step towards Swift 3, most notably, Apple recommends getting Swift 3 migration into your project plans. And certain tools like the Swift Playgrounds iOS app and the Thread Sanitizer already require Swift 3. Luckily Xcode 8 comes with a nifty converter.

Did you watch this session, “What’s new in Swift”? If so, what are your impressions?

Happy cleaning.

Three New Xcode 8 Testing Features

I’m in the middle of watching the Platforms State of the Union from WWDC 2016, and there were three new Xcode 8 testing features announced for Xcode 8 that are so exciting for me. They are all related to automated testing. Did you catch them? They were:

  1. Test crash logs are captured.
  2. xcodebuild can now run with pre-built tests.
  3. Indexing tests is now 50x faster.

Capturing Crash Logs

Have you ever ran a test, unit or UI, that triggered an app crash? It just happened to me today. I bug when animating a UIPresentationController surfaced on iOS8. Unfortunately, Xcode 7 doesn’t capture crash logs when a test triggers a crash. Instead, you have to go back, re-run the test several times, set some breakpoints, and hone in on the code that caused the crash. Luckily, this is changing in Xcode 8 as crash logs will automatically be captured when a test crashes. This means you’ll instantly know the offending line of code that caused the crash, and will be able to fix it that much faster, and move on to building other pieces of your app.

Running with Pre-Built Tests

There’s no way in Xcode 7 to provide a pre-built bundle of compiled tests to be executed against a new instance of your app. This is changing in Xcode 8 with the new xcodebuild. You’ll be able to specify a pre-compiled bundle of tests to be run against a freshly-compiled instance of your app. This has the potential to vastly reduce your compile times. By default (at least in Xcode 7), all of your tests will go into the same target. Each time you need to run your tests, your entire app and all the tests will be recompiled. This isn’t always efficient, especially if there are pieces of your app that haven’t changed. With this new feature of Xcode 8, you’ll be able segregate these tests on their own, so that they can still be run, but they don’t have to be compiled. Awesome.

Faster Test Indexing

Xcode 8 testing features

In Xcode 7, it’s really frustrating when I open a project in Xcode, and I have to wait several minutes for Xcode to finish “Indexing” my tests before I can run them. Have you experienced this? Seeing that I’m only working with a couple projects at a time, and the number of my tests creeps up slowly as I work on the projects, there really isn’t a huge cliff where performance all of a sudden drops off. Instead, one day, it will catch my eye that I noticed the indexing took longer than usual, or got in my way from actually performing a build. Then I wait. And eventually I can resume what I intended to do.

I was happy to hear that in Xcode 8, Apple has vastly improved the performance of this indexing process. In the Platforms State of the Union, it was stated that there is a 50x speed increase when tests are indexed. I can’t wait to experience this in my real projects during my day to day development.

It’s been great to watch how Apple’s support of automated testing has evolved over the years, and these three new Xcode 8 testing features continue that trend. You can measure tangible jumps in automated testing support with each WWDC since the iPhone’s original introduction. I can’t wait to see what else the rest of the week holds with regards to further enhancements to testing in Xcode 8.

Happy cleaning.

Xcode Extensions- Your Life Will Change

Did you get a chance to watch the WWDC 2016 Keynote or Platforms State of the Union today? Or were you lucky enough to be there in person? I wanted to bring to your attention what I believe will be one of the most impactful changes to your life as a developer, Xcode Extensions. In fact, Apple didn’t actually even mention it aloud during the keynote. You had to be closely watching the slides. Xcode Extensions appeared in the slide that Craig Federighi presented that was tag-cloud like in showing off all the new developer features available for iOS10. You can see it at minute mark 100:48. Xcode Extensions are also featured prominently on the What’s New page for Xcode 8:

xcode extensions

Later in the day, Xcode Extensions got a solid shoutout and description during the Platforms State of the Union, which you can see at minute mark 37:38.

Third Party Extensions Have Been Hard

Overall, during the keynote, I was a little surprised by the lack of new APIs available to iOS developers that were presented during this keynote. So when this slide appeared highlighting the new features available to iOS developers, I paused the video to scour each bullet. I’ve always loved customizing my development environment, and I’ve been a Alcatraz user for years. Alcatraz is a third-party extension (or plugin) manager for Xcode plugins. You can get anything from different source code highlighting templates, to extensions that significantly change the behavior of Xcode (usually in good ways). Unfortunately, creating Xcode extensions up until now has not been supported by Apple. I had the honor of working with Derek Selander on his monster 3-part raywenderlich.com tutorial on creating your own Xcode Plugin (I tech edited the article), and it revealed just how hard it is to create an Xcode extension, up until now. It’s a huge pain in the butt, and is really hard to do. You end up decompiling assembly code, running multiple instances of Xcode, and end up guessing a lot. And then, when new versions of Xcode are released, it’s possible that your plugin won’t work and will need to be updated.

Officially Supported Xcode Extensions Will Be Awesome

Other IDEs like Android Studio or Eclipse have APIs available for easily creating plugins. I’m assuming that Xcode Extensions are going to be just that, a way for developers to easily create Xcode extensions or plugins, through a Apple-supported API. Looking at the WWDC schedule, now that it’s been declassified, session 414 on Thursday is titled “Using and Extending the Xcode Source Editor.” It’s description contains the following:

We’ll also show you how to add commands to the source editor with new Xcode Extensions that you can distribute on the Mac App Store.

xcode extensions

During the Platforms State of the Union, the following were described as examples of Xcode extension functionality:

  • Content addition and deletion
  • Content transformation
  • Content selection
  • Pasteboard modification
  • In-file navigation

I was happy to see that Xcode extensions will be supported anywhere Xcode 8 runs – on both macOS Sierra and El Capitan. And furthermore, to be able to actually SELL THEM- something which isn’t possible with today’s backwards way of reverse engineering to create your own Xcode extension, will be awesome.

I think this will have a profound effect on our lives as developers. JetBrains and Reveal will no longer need to create standalone apps to help developers. Instead, they’ll be able to provide their awesome 3rd party functionality and features right within Xcode. I can’t wait for Xcode extensions.

Signed Libraries

Remember the hacked version of Xcode called XcodeGhost that was being distributed on third party download sites? Hackers had created a malicious version of Xcode that would inject malicious code into your iOS apps. Luckily, this only ever made it onto 3rd party download sites, which you shouldn’t use anyway, but people still do use because of slow overseas download speeds. The technique used to create Xcode extensions prior to Xcode 8 enabled this type of malicious hackery of Xcode. Luckily, with changes to Xcode 8, this doesn’t look like it will be possible any longer.

Xcode is now secured by System Integrity Protection, which means only trusted libraries and extensions can interact with the IDE and your code.

I interpret this to mean that the “old” way to hacking your own plugins into Xcode will no longer work, and you’ll instead have to play within the boundaries defined for official Xcode extensions.

WWDC week is so exciting. I’ll be going through videos each day and finding exciting and new APIs, features, and SDK changes to relay to you here, right on cleanswifter.com. What are you finding most exciting?

Happy cleaning.