try! Swift NYC 2017 Recap

Tyler Milner
Atlas
Published in
12 min readSep 25, 2017

In case you’ve never heard of it, try! Swift is one of the newest iOS conferences on the block. First starting in Japan in March of 2016, try! Swift has quickly become an international conference, recently adding Bangalore as its third and final stop for this year. The conference is organized by Natasha Murashev (@NatashaTheRobot) who also runs the This Week in Swift iOS newsletter (which I highly recommend signing up for). Earlier this month, I had the opportunity to attend my first try! Swift conference in New York City.

About the Conference

The single track conference spanned three days — one pre-conference workshop + two main conference days — and had some awesome presentations by over 20 speakers. I really enjoyed the format of the conference, with each talk lasting roughly 20–30 min and direct access to the speakers during “office hours.” There was a dedicated space outside of the main theater where each speaker would post up for questions immediately after his or her talk.

In addition to all of the wonderful speakers, there were what I consider some “big names” in the iOS community in attendance as well. There was support from server-side swift leaders like Jonathan Guthrie (Swift Perfect), who ran the server-side Swift workshop; and Tanner Nelson (Vapor), who did a presentation on server-side Swift and Vapor in general. RxSwift founder, Krunoslav Zaher, did a talk on a new RxSwift architecture called RxFeedback. There were also well-established bloggers like Soroush Khanlou (khanlou.com), who wasn’t a schedule speaker, but filled in for a presenter who got sick. Other blogging veterans include Matt Gallagher (cocoawithlove.com), who did a great view-state driven application presentation; and Ash Furrow (ashfurrow.com), who ran the RxSwift workshop.

Favorite Talks

These are my notes from some of my favorite talks of the conference. While all of the talks were awesome, these presentations stood out as being most relevant to my current proficiency and interests within iOS development. I’ve included links to code and/or presenter notes, if possible. I will do my best to keep the page updated as I find more speaker materials are released. It’s also worth noting that all talks were recorded by Realm, and the videos/transcripts will be available soon!

Update 9/26/2017: Realm has started posting the videos from try! Swift NYC 2017. Check them out on the conference page of Realm Academy!

Map and FlatMap Magic

Neem Serra

Video: https://academy.realm.io/posts/try-swift-nyc-2017-neem-serra-map-and-flatmap-in-swift/

Slides: slideshare.net/NeemSerra/map-and-flat-map-magic

This talk contained many cool and new (to me) map and flatMap techniques. Neem went over the basics of map and flatMap using example collections of simple Cupcake structs to make it easier to understand what was going on.

photo credit to Neem Serra

I really enjoyed how Neem gave several before and after examples where she showed the “old way” of doing something before unveiling the “new way” of accomplishing the same task using functional techniques.

The “old way” typically involves a lot of for loops that modify mutable state. This is one of the shorter examples:

The “old way” — mutable state — photo credit to Neem Serra

The new, functional way of doing things involves what Neem described as “visually explicit chaining” to create a clear, sequential code path:

The “new way” —functional/“visually explicit chaining” — photo credit to Neem Serra

Despite the somewhat introductory sounding title, there was so much good information in this presentation that I will be doing a separate blog post later to highlight the tips and tricks I felt will help me the most!

Driving view state through data for fun and/or debugging

Matt Gallagher

Video: https://academy.realm.io/posts/try-swift-nyc-2017-matt-gallagher-driving-view-state-through-data/

Code: github.com/mattgallagher/Clocks

In this talk, Matt showcased an alternative implementation of the Redux/ReSwift Time Travel feature. What impressed me the most was the ability to drive the data/document state and presentation state separately. This could theoretically allow you to easily put the app into a state that’s otherwise very hard to enter.

Matt defined view-state as anything mutable in a view that isn’t written to the main “model.” For instance, each character of text typed into a search field is a piece of view-state, but doesn’t need to be saved to the main app-state each time the user enters a character.

While standard Cocoa apps treat view-state as a side-effect of presentation, Matt showed how inverting the paradigm to treat presentation as a consequence of view-state could allow these time travel features to be easily built.

The primary example Matt showed involves the common task of transitioning to a detail screen in an app. In the standard presentation-driven approach, a view controller would typically call performSegue(withIdentifier:) to initiate the transition and subclass prepare(for segue:sender:) to catch and set data on the view controller during the transition. In a data-driven approach, an update to the view-state is made and then the presentation is performed in response to the updated view-state.

Example code is shown below (sorry for the subpar photo quality):

Inverted presentation logic — photo credit to Matt Gallagher

What impressed me the most was certainly the demo that Matt showed. I’ve created a quick video showcasing the standard time travel feature and then turning on the second slider to enable driving the main app-state and view-state independently of each other.

Demo of driving view-state independently from app-state in github.com/mattgallagher/Clocks

Creating Rich Custom UI Notifications

Craig Clayton

Video: https://academy.realm.io/posts/try-swift-nyc-2017-craig-clayton-creating-rich-custom-ui-notifications/

Slides: slideshare.net/thedevme/creating-rich-custom-ui-notifications

Code: bit.ly/tryswiftcc

In Craig’s talk, he gave a great overview of what it takes to implement the custom notifications UI that was introduced in iOS 10. I’ve personally not implemented this feature yet, so it was awesome to get a “crash course” in their implementation.

Setup is as simple as implementing three methods:

  • AppDelegate application(_:didRegisterForRemoteNotificationsWithDeviceToken:) — check if we’ve got permissions
  • UNUserNotificationCenterDelegate userNotificationCenter(_:willPresent:withCompletionHandler:) — called when the app receives a push while in the foreground
  • UNUserNotificationCenterDelegate userNotificationCenter(_:didReceive:withCompletionHandler:) — called when the app receives a push while in the background

To enable your custom notifications to run, the value for themutable-content key on the aps push notification payload must be set to 1 (an Int).

{
"aps": {
"alert": "New Message",
"mutable-content": 1
}
}

New in iOS 11 is the ability to turn off the notification preview text, which means the user would see the text “Notification” instead of the alert message that you set on the push payload.

You can turn off notification preview text in Settings -> Notifications.
Turning off notification previews will cause push messages to display “Notification” by default.

In order to customize this text, your app can include a strings.dict plist that will pluralize the message. This would allow the message to read something like “3 new tweets” instead of just “Notification.” Check out Apple’s Localizing Your App documentation for more information.

Also new in iOS 11 is the thread-id key on the aps push notification payload. This allows iOS to automatically merge related messages. For example, subsequent game updates could be combined into one message that contained the latest score.

{
"aps": {
"alert": "New Message",
"mutable-content": 1,
"thread-id": "123"
}
}

Server-side Swift Using Vapor

Tanner Nelson

Video: https://academy.realm.io/posts/try-swift-nyc-tanner-nelson-server-side-swift-using-vapor/

Tanner started his talk with a general overview of the benefits to developing a server using server-side Swift technologies. He outlined the main downsides with the three most common solutions for backend development:

  • CloudKit — built-in and easy to use, but not cross platform
  • MBaaS (Firebase, Realm, etc.) — hard to be DRY across platforms since backend database update logic must be built-in to each client
  • Existing solutions (Express.js, Ruby on Rails, etc.) — are well established and supported, but will likely require you to learn a new language and tooling

Compare this to server-side Swift, where you are working with a familiar language in your normal dev environment. Sharing models and business logic between the frontend and backend also helps you remain more DRY, and the compiler can help you type-check these interactions.

I toyed with Vapor about a year ago, but it was good to get a refresher on the main components of a Vapor server-side Swift application:

  • Routing — sending HTTP request (and associated info) to your business logic handler
  • Object-relational mapping (ORM) — Fluent, the ORM in Vapor, allows you to easily fetch and persist data in a database as well as create and migrate schema
  • Leaf — templating language to render data to HTML (for creating web apps or sending emails)

Another exciting aspect about Vapor’s evolution that Tanner mentioned was the improvements that Swift 4 brings with regard to reducing the amount of “stringly typed” code that you need to write and maintain.

Modern RxSwift Architectures

Krunoslav Zaher

Video: https://academy.realm.io/posts/try-swift-nyc-2017-krunoslav-zaher-modern-rxswift-architectures/

Code: github.com/kzaher/RxFeedback

While I must admit that I have only surface knowledge of reactive frameworks like RxSwift, I did enjoy Krunoslav’s talk on RxFeedback, even if I was a little lost at times. 😅

From what I understand, RxFeedback is a new architectural approach for reactive apps that use RxSwift. The main idea seems to be tying together an initial state, a reducer, and a “feedback loop” to help you build your app’s functionality in a standard, straightforward way.

RxFeedback — photo credit to RxFeedback

One of the main benefits to using this architecture seems to be getting everyone on the same page and making it easy for developers to answer the question, “where do I need to put this code?”

  • If it’s state/data → encode it into the main ‘state’ struct
  • If it’s a way to modify state → create an Event/Command
  • If it’s an effect → encode it into part of the state and then design a feedback loop

As an example, consider the following simple counter component:

A simple counter app — photo credit to RxFeedback

The state changes and UI binding can be succinctly described using RxFeedback:

Observable.system(
initialState: 0,
reduce: { (state, event) -> State in
switch event {
case .increment:
return state + 1
case .decrement:
return state - 1
}
},
scheduler: MainScheduler.instance,
feedback:
// UI is user feedback
UI.bind { state in
([
state.map(String.init).bind(to: label.rx.text)
], [
plus.rx.tap.map { Event.increment },
minus.rx.tap.map { Event.decrement }
])
}
)

This looks promising if code like above can scale for a fully-fledged application. I’m definitely adding RxSwift/RxFeedback to my todo list to explore further in the coming months!

Error handling made easy

Helen Papanikolopoulou & Kostas Kremizas

Video: https://academy.realm.io/posts/try-swift-nyc-2017-eleni-papanikolopoulou-kostas-kremizas-error-handling/

Code: github.com/workable/swift-error-handler

Helen and Kostas showcased some great techniques to make error handling easier to manage with codebase growth. They first outlined the major problems with taking an adhoc, on-the-fly approach to error handling:

  • Lots of boilerplate, repeated code (non-DRY)
  • No standardized way of handling errors across the codebase — different engineers will solve the problems in different ways
  • Complex code paths (e.g. multiple return statements) can lead to cognitive overload

I also really loved the list of bad error handling practices that you should try to avoid:

  • Skipping cases and/or using generic error messages — don’t be in a hurry/lazy (“I’ll fix it later”) or make the assumption that errors are edge cases.
  • Leaving duplicated/similar code everywhere
  • Handling errors directly in the networking layer

On the contrary, some good practices for error handling include:

  • Creating a set of default actions for common errors
  • Having an easy way to customize defaults

Helen and Kostas introduced their ErrorHandler library and showcased how it can help bring sanity to your error handling. The general idea is to encapsulate all of your common error handling code into a default handler. Things like responding to no internet connection, 401 Unauthorized errors, and generic errors will typically be handled in the same way across your app. You can also specify actions that should always run any time an error is encountered, like sending the error to your logging mechanism.

extension ErrorHandler {
class var defaultHandler: ErrorHandler {

return ErrorHandler()
.on(NSErrorMatcher(domain: NSURLErrorDomain, code: NSURLErrorNotConnectedToInternet) { (_) in
showErrorAlert("You are not connected to the Internet. Please check your connection and retry.")
return .continueMatching
}

// You can use the Alamofire extensions to easily handle responses with invalid http status
.onAFError(withStatus: 401, do: { (_) in
showLoginScreen()
return .continueMatching
})

// Handle unknown errors.
.onNoMatch(do: { (_) in
showErrorAlert("An error occurred! Please try again. ")
return .continueMatching
})

// Add actions - like logging - that you want to perform each time - whether the error was matched or not
.always(do: { (error) in
Logger.log(error)
return .continueMatching
})
}
}
}

Then, in the caller (typically your view controller), you have much less boilerplate code to deal with. You can even override the error handling routines if you need custom behavior.

sendMessage(message) { (response, error) in

if let error = error {
ErrorHandler.defaultHandler
.on(ValidationError.invalidEmail, do: { (_) in
updateEmailTextFieldForValidationError()
return .continueMatching
})
.onAFError(withStatus: 404, do: { (_) in
doSomethingSpecificFor404()
return .stopMatching
})
.onNoMatch(do: { (_) in
// In the context of the current screen we can provide a better message.
showErrorAlert("An error occurred! The message has not been sent.")
// We want to override the default onNoMatch handling so we stop searching for other matches.
return .stopMatching
})
.handle(error)
}
}

Everyone is Your User

Julio Carrettoni

Slides: speakerdeck.com/dev_jac/accessibility-everyone-is-your-user

Code: github.com/Julioacarrettoni/tryswiftnycAccessibilityDemo

In the final talk of the conference, Julio did an exceptional job showcasing a poor voice-over experience and the steps needed to make it better. Julio then kicked things up a notch by putting himself in the shoes of an accessibility user and performing his demo while blindfolded!

“The only thing worse than doing a live demo is doing a live demo while blind.”

There were some great accessibility tips given during this presentation:

  • Use native elements when possible (don’t try to make a “look-alike” yourself).
  • Don’t rely on overlays to block interactivity. This doesn’t play well with the screen reader.
  • Don’t use “transparent” buttons on top of UI elements. This also doesn’t play well with the screen reader (although iOS 11 is a little more forgiving and will try to help).
  • Pay attention when using UIGestureRecognizers.
  • Watch out for the naming of image assets. If no accessibility description is given, the system will read the file name of the asset itself.
  • When in doubt, look to Apple’s apps for tips on how to adopt accessibility best-practices.

Other Cool Stuff at try! Swift

Machine Ethics and Emerging Technologies

Paul Fenwick

Video: https://academy.realm.io/posts/try-swift-nyc-2017-paul-fenwick-machine-ethics-emerging-technology/

While this talk wasn’t iOS or Swift related, it was one of my favorite talks of the conference! Paul provided great food for thought that we, as software engineers, need to keep in mind as the world continues to evolve with technological progress. Paul highlighted how ethics will become more important when designing autonomous systems like self-driving cars. At what point would it be okay for the self-driving car to sacrifice its occupant in order to save a pedestrian’s life? Would it ever be okay? Will we have two “types” of self-driving cars in the future — those that act with the “greater good” in mind and those that exclusively prioritize the safety of their occupants at all times?

Buddybuild demo

Dennis Pilarinos

Video: https://academy.realm.io/posts/try-swift-nyc-2017-dennis-pilarinos-buddybuild/

While I’ve heard of Buddybuild, I’ve never used it before. I generally prefer to have complete control over my signing and build process, but Buddybuild is definitely on to something with how easy they’ve made it setup a new project, onboard testers, and allow them to provide feedback! It only took about 10 minutes to get an app onto the Buddybuild platform and deploy it to a random audience member.

James Dempsey and the Breakpoints

James Dempsey

James, who presented on the first day of the conference, helped to close out the show by performing some of his iOS development anthems. Armed with his ukulele and some clever lyrics, James’ tunes were a great way to end the conference.

Thanks, try! Swift!

A quick thanks to NatashaTheRobot for organizing the conference and all of the volunteers for making it happen! Also thanks to all of the try! Swift NYC 2017 sponsors! I had a great time at the conference and was able to soak in a lot of great material. I hope to be able to attend next year and am excited to see this conference continue to grow over the coming years!

--

--