Weekend Reading for July 10, 2016

Weekend Reading for July 10, 2016, click here

Happy Weekend fellow Clean Swifters. Here’s some suggested reading to keep you busy!

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

UIRefreshControl in iOS 10

Did you know that adding a UIRefreshControl in iOS 10 to a table view, a collection view, or a scroll view has never been easier? UIRefreshControl is now a first class citizen in all of these scrollable views and officially supported by the iOS SDK. Having fought through hacked solutions to use a UIRefreshControl in anything but the officially supported UITableViewController in the past, I’m really pumped to see this. This change for iOS 10 first caught my eye in the WWDC 2016 session, What’s New in UICollectionView in iOS 10 (which was a really good session by the way).

How It Works

The key to easily adding a UIRefreshControl to a UITableView, a UICollectionView, and a UIScrollView is the UIRefreshControlHosting protocol. Just like UIRefreshControl in iOS 10, this is also new in iOS 10. It’s a protocol adopted by UIScrollView. And coincidentally, UITableView and UICollectionView inherit from UIScrollView so they easily get this behavior.

Adding a UIRefreshControl in iOS 10

Here’s how simple it is to add a UIRefreshControl in iOS10:

let tableView = UITableView()
let rc = UIRefreshControl()
tableView.refreshControl = rc

Yep, it’s that dirt simple. Want to add a UIRefreshControl to a UIScrollView? It’s just as easy!

let scrollView = UIScrollView()
let rc = UIRefreshControl()
scrollView.refreshControl = rc

And want to add it to a UICollectionView? Well, you probably get the idea:

let collectionView = UICollectionView()
let rc = UIRefreshControl()
scrollView.refreshControl = rc

Now don’t forget to add a target to the UIRefreshControl so it has some behavior associated with it. Luckily, nothing has changed with that API, so it’s just as you remember it from pre iOS 10 days. Here’s a full example with a UITableView:

override func viewDidLoad() {
  super.viewDidLoad()
  let tableView = UITableView()
  let rc = UIRefreshControl()
  rc.addTarget(self, action: #selector(TableViewController.refresh(refreshControl:)), for: UIControlEvents.valueChanged)
  tableView.refreshControl = rc
  view.addSubview(tableView)
}

func refresh(refreshControl: UIRefreshControl) {
  tableView.reloadData()
  refreshControl.endRefreshing()
}

Refreshingly Simple

If you got this far, you probably aren’t rolling your eyes at how easy this is. If you’re questioning whether this is worth a blog post or not, fine. I believe it is. This is a subtle, yet awesome API change coming in iOS 10. I love to see that Apple continues to refine their API and adding niceties like this for developers. I look at this change and think, “Ya, this is how it always should have been.” Thank you, Apple. Has there been anything else on the edges that you’ve noticed and felt good about?

Happy cleaning.

Weekend Reading, July 1, 2016

Weekend Reading for July 1, 2016, click here

Happy Friday fellow Clean Swifters. We’re looking at a 3-day weekend here in the United States, I can’t wait. More time to catch up on WWDC sessions! Here’s some other suggested reading if you find yourself with free time this weekend.

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

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.

VIDEO: Building Tests

Chapter 4 of “Refactoring, Improving the Design of Existing Code by Martin Fowler, titled “Building Tests” provides an introduction to automated testing.

Here’s my perspective on the chapter:

Video Transcription:

Hey, what’s up everybody, it’s Andy from cleanswifter.com and I’m here to talk about the next chapter in Martin Fowler’s book, “Refactoring, Improving the Design of Existing Code.” You can buy that book in the Amazon Affiliate link in the description for this video. Last week we talked about chapter 3, Bad Smells in Code. In that chapter, Fowler presents some ideas of what to look for in your code to know it’s time to actually refactor it. This week, chapter 4, titled “Building Tests” Fowler actually talks about some techniques for introducing automated tests within your code. If you’ve been following any of my posts on cleanswifter.com, you’ll know I have a huge passion for automated testing of software. I was kind of excited for this chapter. When I finally got around to actually reading it, it fell short of what I was looking for. Fowler clarifies that this book is not about testing. And the reason I interpret he chose to include this chapter is to recognize the value of automated testing, especially in the time of refactoring. He doesn’t even mention test driven development in this chapter. Now, if you remember test driven development, one of the key steps to test driven development, is that final third step, to refactor everything you’ve done. Test driven development. You start off writing a failing test. Then you write the production code to make that test pass. And then you refactor. Now just bringing it back to Fowler’s book, he doesn’t actually talk about anything in detail with regard to test driven development. In fact I think he kind of just puts this chapter in here to recognize that when you go out to use this as a recipe book of refactoring, that you should keep in mind the value that can be adding tests throughout the process.

If you’re not familiar with automated testing, or haven’t been following any of my posts on <cleanswifter.com> is that remember, automated tests’ value is that it is code testing code. You can execute an entire test bed at the click of a button. Where your entire code base is tested in a matter of seconds. You do actually have to go through the effort of writing these tests, and that’s no small effort. Then you can make changes to the rest of your code base without risk of introducing new bugs. Additionally, when you find a bug, whether that’s reported through QA or an end user, you can first write a test to verify that bug, and then go fix the code to make sure the test passes, you can now have the confidence that that bug will never surface again in your code. For me, that’s really the value of adding tests, knowing that when I find a bug, I can write a test that verifies the bug does actually exist, then I can go fix that code, make the bug go away, make sure the test passes, then never again will that bug surface. This is especially relevant to the iOS development community because at a recent presentation I gave to the local CocoaHeads group here in Philly, there continues to be the majority of iOS development community that doesn’t write automated tests for their code. In that meeting we talked about some of the reasons this may be. For an independent or contract developer, that they don’t feel it is worth their time. Or hard to justify to their client, whether that is them for their own product, or someone else paying them for their time), that it is worth the time to write tests. It’s a 1:1 ratio, for every hour you spend writing production code, you’ll need to spend an hour writing test code. I think until you learn the lesson the hard way, and then see the value of automated tests correcting that, you’ll never be able to justify the cost. It’s like a catch-22, because if you never try it you’ll never be able to justify it to yourself. On the otherhand, if you’re going to wait to see the value before you try it, you’re never going to try it. I think one takeaway from this chapter, that even Fowler calls out, is that specifically, go try to write a couple tests. Don’t spend a lot of time writing an entire big test suite for your entire application, worrying about every edge case, and instead focus on just 1 or 2 tests that are going to add value, and I guarantee you that sometime down the road, you will have your butt saved by the fact that you had automated tests. You will write automated tests, and sometime down the road they will fail because some code change you made introduced an unexpected, but tested for bug. You’ll be happy since you caught the bug and not an end user.

Fowler clarifies the difference between unit and functional tests. Again, I have a ton of documentation on <cleanswifter.com> that helps differentiate and define each of these for iOS development. For unit testing, you’ll be using XCTest as provided by Apple. It’s code that tests other code at the smallest level. You’ll write a test method for each path of conditional code in another class. It requires intimate knowledge of the code you’re testing. Consider it white box testing. You can see the code, to know the conditional paths, and know how to test it. This is in contrast to functional testing. Functional testing is where you would call it black box testing. You don’t have intimate knowledge of the code. Instead, all you’re doing is testing the code from the outside in. This means that you are simulating an end user swiping, tapping, and navigating your app. There are a bunch of tools out there to do this. Apple’s provided tool is called Xcode UI Tests and I personally use a different tool, called KIF. It stands for Keep-It-Functional. It’s open source. Some of the benefits I like of KIF are that it is mature, been in the community for years, you can write your tests in either Objective-C or Swift. I haven’t spent enough time with Xcode UI Tests to know it’s pros and cons, but I did use its predecessor, UI Automation which was Javascript driven and a poorly documented API. It’s soured me on Apple’s provided functional testing tools, so that’s why I haven’t gone back yet. I’ll do that soon and write about it on <cleanswifter.com>.

Another important thing to keep in mind when you write your first test, regardless of whether you are doing TDD or not, and in fact if you are just starting out I don’t recommend jumping right into TDD. But one thing to keep in mind when writing your tests is that you want to see that test fail when you expect it to fail. For example, say you are writing a test for a method that adds numbers. You want to first verify that adding 1 and 2, never returns anything other than 3. Otherwise, you won’t have the confidence that when someting actually goes wrong, that test will actually fail. That gives you a baseline assurance that that test is actually providing that quality check you’re looking for. And trust me, I’ve seen plenty of cases where I’ve written a test and not done this, only to find out that it wasn’t actually verifying, what I thought it was verifying.

It was a pretty short chapter, chapter 4 in Martin Fowler’s book, “Refactoring” where he just introduces the concept of tests. If you’re watching this video and haven’t checked out anything I’ve posted on <cleanswifter.com> around automated tests. And if you’re not writing automated tests for your iOS apps, you should definitely go try that out.

Looking ahead, I’m really excited for the rest of this book. Chapter 4 is the end of the preamble before the actual list of refactoring recipes. Going forward, week by week, I’m going to make a screencast of that refactoring, showing it in action with Swift code, and post it on <cleanswifter.com>. It will demonstrate the transformation from smelly code to nice clean code. That will be done in a screencast where you can go back and watch. The first refactoring we’ll try in the book is Extract Method. It’s a really easy one, but also a really effective one. I’m looking forward to showing you that. Check back next week for that. In the meantime, be sure to checkout <cleanswifter.com>.

Happy cleaning.

WWDC 2016 Wish List

WWDC 2016 is less than one week away. I’ve only been to the actual conference once, and that was the 2014 instance. I had such a great time, met people that I continue to stay in contact with despite not having seen them since, and learned so much. That was the WWDC where Swift was unveiled to the world. With such a huge announcement as introducing a new programming language, I think it’s a WWDC that will stand the test of time. In a lot of ways, WWDC is like the one time of year that we developers get a new delivery of gifts from Apple. Gifts that we can use to create new business ventures, deliver new delightful features to our customers, and even gifts that will make our own lives easier- both as developers within Apple’s platform, as well as end users of many apps ourselves. I have no shortage of things that I’d like to see from Apple, both from a developer perspective, as well as an end user perspective. Here’s my WWDC 2016 wish list:

I tried to keep this list in the realm of possibility, and it is ordered by a mild amount of prioritization.

  1. Xcode Swift Support. Yes, you can build Swift apps in Xcode, and I do. And yes, there have been improvements in this area. There are just some fundamental things broken with building Swift apps in Xcode. For example, I hope I never have to see that “Xcode can only refactor C and Objective-C code.” dialog again.

Screen Shot 2016-06-06 at 12.19.29 PM

Frankly, I would be embarrassed if I had to put an error message in one of my apps to the tune of, “sorry, you tried to do something legitimate that we just don’t support.” And then to think that this message has been around for going on two years!?!?! Additionally, while less frequent as a year ago, I still get SourceKit crashes in Xcode. That’s when all of a sudden syntax highlighting of your source code stops, and there is no autocompletion. It’s usually paired with an error message. And often, there’s no suggested course to correct whatever you did to crash SourceKit. It’s usually the case that you typed in some non-compilable Swift that rather than getting a nice error message, your IDE stops working. Do you think a third-party IDE would survive with shortcomings like this? I don’t.

  1. Automated Test Support. Reflecting over the past five or so years of WWDC, it’s been amazing to watch the progress Apple has made in supporting automated testing of iOS apps. I remember when first joining the iOS dev community, being astounded by how little Apple made available for automated testing (compared to the Java world that I came from). Fast forward to today, and it’s a fairly comprehensive suite of tools for testing your apps. A couple gaps that I would like filled include:

    • Faster test execution – I heard that Visual Studio, the .NET IDE, actually will run your test bed anytime you save a source file in your project. That sounds AMAZING! In order for that to be possible, test execution must be fast. Right now, just to run a suite of a couple hundred XCTest unit tests, it’s about 20 seconds. That needs to be sped up.
    • Headless test runners – Right now, running tests (unit or otherwise), require a simulator or device to fire up your app, and run through the tests. This shouldn’t be needed. It would be so nice to run tests without the overhead of the iOS simulator or device.
  2. Continuous Integration Improvements – Xcode Server is a start, but so far from being something that would stand our as a continuous integration solution. I’d love to see Apple take strides to better supporting cloud-based continuous integration. This may even include some amount of supporting xcodebuild on non-OS X based systems (Linux?). Headless test runners would help here too. Right now, without the help of something like Buildasaur, I can’t even get the status of a Xcode Server integration on a pull request. That’s a huge hole in me adopting Xcode Server as the sole solution for continuous integration. Oh ya, and what about even automating some of the process of app deployment, like submission to iTunes Connect? Wouldn’t that be delicious!?

  3. WatchKit Performance. I’ll state right off the bat that I don’t actually have any WatchKit code in production apps at this point. I do have an Apple Watch that I wear everyday. I buy-in to the concept of wearables, especially for health and exercise tracking. The thing is, using the watch is so darn slow and unreliable. Whether I’m asking Siri to start a timer, or using the Strava watch app’s “Start Run” button, either the action simply won’t happen, it will take too long, or some random nasty side effect will happen (like my Strava workout will clobber the corresponding entry in HealthKit). Until WatchKit apps are speedy, and reliable, there’s no chance of success for the Apple Watch in the future. New hardware is not the answer here. It may be part of the solution, but the software stack needs a total revamp.

That’s my WWDC 2016 wish list. If I didn’t say it before, I’ll just reiterate how exciting this time of year is for me, and should be for you too. Even if you need to support older iOS versions, don’t worry, the new features that are announced are still fun to play with, and you’ll eventually get to use them in your production applications. What’s on your WWDC 2016 wish list? If you didn’t see, Apple will be live streaming sessions daily, and posting videos or all sessions throughout the week. Starting next week, I’ll be posting recaps and highlights of all the sessions I find interesting as I consume all this great content from the comfort of my couch.

Happy cleaning.

Swift Algorithm Club

I caught an article today on raywenderlich.com that pointed me to the Swift Algorithm Club. I had heard of the Swift Algorithm Club a couple times in the past, but never got the chance to take a peak. Today, I got that chance, and what I saw was really cool. Algorithms classes during my education were some of the most challenging, yet fulfilling classes that I took. Being able to dissect or create a complicated algorithm is a unique feeling. Something that I don’t think I’ve flexed enough since being out of school.

Big Oh

I really like how the Swift Algorithm Club has frequent references to Big-Oh notation, eg O(n). In particular, it’s so easy to get caught up in the high level APIs that we are often using when building our iOS apps, that it’s easy to lose focus on the basics of algorithm effectiveness and efficiency. Being able to spot an optimization to move from quadratic (O(n^2)) to linear (O(n) to even constant (O(1)) efficiency can have vast performance improvements in everything from network usage, to battery usage, to simple responsiveness of your app. One drawback, is that with the ease of learning how to “code iPhone apps” from the vast amount of tutorials out there, often these course cover nothing about algorithmic efficiency. So if all this is new to you, go do some Googling. Here’s a recorded course from MIT.

Go Contribute

I also appreciate how the article also puts an offer out recruiting contributors. I think for newcomers to the field, finding a project to be able to contribute to, or even just know how to contribute, can be daunting. It was nice that the article made some pointers on how to get started.

Wrap Up

Open source, and algorithms, how can you get any better? The Swift Algorithm Club is awesome. Take a look, and I’d love to know, do you consider Big-Oh efficiency when building your apps?

Happy cleaning.