Safer Swift Code with Value Types I (AltConf 2015)

Safer Swift Code with Value Types I (AltConf 2015)

New language, new programming paradigms. Since the release of Swift the Cocoa developer community is increasingly experimenting with functional programming. How can we adopt FP principles in real world applications? This talk will discuss how apps can make use of immutable value types to avoid common code smells and bugs. I will also discuss other benefits of a functional approach, such as modularity through function composition. Throughout the talk I will illustrate the architecture of a non-trivial iOS app that relies strongly on immutable value types. The main goal of this talk is to show pragmatic approaches for applying functional programming principles to common problems in Cocoa development.

De23af005c790b22f8ce4d201e6ca027?s=128

Benjamin Encz

June 11, 2015
Tweet

Transcript

  1. 1.

    Safer Swift Code with Value Types Safer Swift Code with

    Value Types | @benjaminencz | AltConf, June 2015 1
  2. 2.

    What do I mean by safety? Safer Swift Code with

    Value Types | @benjaminencz | AltConf, June 2015 2
  3. 3.

    Agenda 1. What are Value Types vs. Reference Types 2.

    Why is this topic relevant now? 3. How: A Practical Example of a Value Oriented Architecture Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 3
  4. 4.

    Values vs. References Safer Swift Code with Value Types |

    @benjaminencz | AltConf, June 2015 4
  5. 5.

    Reference Types class PersonRefType { let name:String var age:Int //

    .. } // 1 let peter = PersonRefType(name: "Peter", age: 36) // 2 let peter2 = peter // 3 peter2.age = 25 // peter {"Peter", 25} // peter2 {"Peter", 25} Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 5
  6. 6.

    Value Types struct Person { let name:String var age:Int }

    // 1 let petra = Person(name:"Petra", age:25) // 2 var petra2 = petra // 3 petra2.age = 20 // petra {"Petra", 25} // petra2 {"Petra", 20} Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 6
  7. 8.

    Foundation / C Types Reference Types: - NSArray - NSSet

    - NSData Value Types: - NSInteger - Struct Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 8
  8. 9.

    Swift Standard Library Reference Types: - ManagedBuffer(?) - NonObjectiveCBase(??) Value

    Types: - Array - String - Optional Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 9
  9. 10.

    Enums and Structs in Swift are Powerful — Can have

    properties — Can have method — Can conform to protocols Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 10
  10. 11.

    So What Can't They Do? “Indeed, in contrast to structs,

    Swift classes support implementation inheritance, (limited) reflection, deinitializers, and multiple owners.” Andy Matushak1 1 http://www.objc.io/issue-16/swift-classes-vs-structs.html Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 11
  11. 12.

    We've Already Been Doing This! @property (copy) NSString *userName; Safer

    Swift Code with Value Types | @benjaminencz | AltConf, June 2015 12
  12. 13.

    Case Study A Twitter Client Built on Immutable Value Types

    Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 13
  13. 14.

    Twitter Client 1. Download the latest 200 tweets and display

    them 2. Allow to filter tweets (RT only, favorited tweets only, etc.) 3. Allow user to favorite tweets (should be synced with server) Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 14
  14. 16.

    How can we favorite Tweets? Safer Swift Code with Value

    Types | @benjaminencz | AltConf, June 2015 16
  15. 17.

    It Is Very Simple with OOP tweet.favorited = true Safer

    Swift Code with Value Types | @benjaminencz | AltConf, June 2015 17
  16. 18.

    It Is Simple with OOP let lockQueue = dispatch_queue_create("com.happylocking", nil)

    dispatch_sync(lockQueue) { tweet.favorited = true } Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 18
  17. 19.

    Is It Simple with OOP? let lockQueue = dispatch_queue_create("com.happylocking", nil)

    dispatch_sync(lockQueue) { tweet.favorited = true NSNotificationCenter.defaultCenter(). postNotificationName("Tweet Changed", object: tweet) } Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 19
  18. 20.

    Modeling Change is Hard! let lockQueue = dispatch_queue_create("com.happylocking", nil) dispatch_sync(lockQueue)

    { tweet.favorited = true NSNotificationCenter.defaultCenter(). postNotificationName("Tweet Changed", object: tweet) tweetAPIClient.markFavorited(tweet.identifier) } Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 20
  19. 21.

    Modeling Change is Hard! — Protect against unwanted updates —

    Distribute new value throughout application — Understand what the underlying identity of an object is and perform update accordingly Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 21
  20. 22.

    Modeling Change is Hard! — Protect against unwanted updates —

    Distribute new value throughout application — Understand what the underlying identity of an object is and perform update accordingly -> We need to this in all places where we mutate values! Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 22
  21. 23.

    Modelling Change is Hard! Safer Swift Code with Value Types

    | @benjaminencz | AltConf, June 2015 23
  22. 24.

    How Can We Model Change With Immutable Value Types? Safer

    Swift Code with Value Types | @benjaminencz | AltConf, June 2015 24
  23. 25.

    How Can We Model Change With Immutable Value Types? Model

    change to values as values! Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 25
  24. 26.

    How Can We Model Change With Immutable Value Types? Model

    change to values as values: — Create a new Tweet for every change — Save these changes in a Store — Store saves local changes and server state — Store provides a merged view on list of tweets — Store can trigger sync of local state to server Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 26
  25. 28.

    Favoriting a Tweet let currentTweet = tweetTableViewCell.tweet! let newTweet =

    Tweet( content: currentTweet.content, identifier: currentTweet.identifier, user: currentTweet.user, type: currentTweet.type, favoriteCount: currentTweet.favoriteCount, isFavorited: !currentTweet.isFavorited ) store.addTweetChangeToLocalState(newTweet) Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 28
  26. 29.

    Modelling Change in Stores class TweetStore { var tweets: [Tweet]?

    { get { // merge server list and local list } } func addTweetChangeToLocalState(tweet: Tweet) { // append tweet to local list } func loadTweets() -> Promise<[Tweet]> { // trigger API request, populate server list } Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 29
  27. 31.

    Syncing Change 1. Iterate over each local change 2. Generate

    API request that syncs that local change to server 3. Upon each API response: — If success: remove tweet from local change set — If failure: leave tweet in local change set Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 31
  28. 32.

    Syncing Change protocol StoreSync { typealias StoreType static func syncLocalState(merge:

    StateMerge<StoreType>) -> Promise<SyncResult<StoreType>> } struct StateMerge <T> { let serverState: [T] let localState: [T] } enum SyncResult <T> { case Success(StateMerge<T>) case Error(StateMerge<T>) } Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 32
  29. 34.

    Benefits of a Value Oriented Architecture — Confidence that no

    one will change our data under the covers — Change propagation needs to be handled explicitly — Modeling change as data opens opportunities: — Undo Functionality — Sophisticated conflict resolution Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 34
  30. 35.

    The Value Mindset Example project: https://github.com/Ben-G/TwitterSwift Related, great talks: -

    https://realm.io/news/andy-matuschak-controlling- complexity/ - http://www.infoq.com/presentations/Value-Values Safer Swift Code with Value Types | @benjaminencz | AltConf, June 2015 35