Swift, Frameworks & Modules, Learnings from CocoaPods

1fa9cb8c7997c8c4d3d251fb5e41f749?s=47 Realm
October 05, 2015

Swift, Frameworks & Modules, Learnings from CocoaPods

Presented by Marius Rackwitz & Orta Therox at GOTO Copenhagen 2015

1fa9cb8c7997c8c4d3d251fb5e41f749?s=128

Realm

October 05, 2015
Tweet

Transcript

  1. 3.
  2. 5.

    5 Oct 2015 @orta @mrackwitz WHAT IS COCOAPODS? A dependency

    manager A community around mostly open source code 5 years old
  3. 8.
  4. 12.

    5 Oct 2015 @orta @mrackwitz WHAT ARE STATIC LIBRARIES? ”A

    static library (aka static archive) is a collection of .o files with a table of contents that lists the global symbols in the .o files.
 
 ld will only pull .o files out of a static library if needed to resolve some symbol reference.
 man page of ld
  5. 13.

    5 Oct 2015 @orta @mrackwitz WHAT ARE STATIC LIBRARIES? ”A

    static library (aka static archive) is a collection of .o files with a table of contents that lists the global symbols in the .o files.
 
 ld will only pull .o files out of a static library if needed to resolve some symbol reference.
 man page of ld
  6. 14.

    5 Oct 2015 @orta @mrackwitz ar
 archive BUILDING A STATIC

    LIBRARY Source Code clang lipo fat binary ar
 archive ranlib o-files o-file o-files o-file table of contents
  7. 15.

    5 Oct 2015 @orta @mrackwitz INSIDE LD 1 2 3


    4 5 6 7 8 9 10 #BananaKit.h @import monkey; @interface BKBananaTree @property (copy) NSArray *fruits; @end 
 @interface BKBananaFruit @property (weak) MKMonkey *peeledByMonkey; - (void)peel:(MKMonkey *)m;
 @end 1 2 3
 4 5 6 7 8 9 #monkey.h typedef NS_ENUM(NSUInteger, MKSize) { MKSizeSmall, MKSizeBig }
 @interface MKMonkey @property (nonatomic, assign) MKSize size; - (id)init(MKSize)size; @end 1 2 3
 4 5 6
 7
 8
 9
 #main.m @import monkey; @import BananaKit; 
 void main() { id m = [[MKMonkey alloc]
 init:MKMonkeySmall]; id t = [BKBananaTree new]; t.fruits.first.peel(m);
 }

  8. 19.

    5 Oct 2015 @orta @mrackwitz COCOA TOUCH FRAMEWORKS Binary
 Dynamic

    linkable binary Modules Declaration
 Clang Module Map, Swift Module declarations Headers
 Stripped in app Resources
 Prepared like in the app Info.plist
 Meta-data like version, copyright etc. Dependencies
 Can contain further frameworks and dylibs }Necessary for
 import & linking
  9. 20.

    5 Oct 2015 @orta @mrackwitz WHAT ARE DYNAMIC LIBRARIES? ”A

    dynamic library (aka dylib or framework) is a final linked image. Putting a dynamic library on the command line causes two things:
 
 1) The generated final linked image will have encoded that it depends on that dynamic library.
 2) Exported symbols from the dynamic library are used to resolve references. 
 the man page of ld
  10. 21.

    5 Oct 2015 @orta @mrackwitz WHAT ARE DYNAMIC LIBRARIES? ”A

    dynamic library (aka dylib or framework) is a final linked image. Putting a dynamic library on the command line causes two things:
 
 1) The generated final linked image will have encoded that it depends on that dynamic library.
 2) Exported symbols from the dynamic library are used to resolve references. 
 the man page of ld
  11. 22.

    5 Oct 2015 @orta @mrackwitz libtool
 -dynam ic MachO BUILDING

    A DYNAMIC LIBRARY Source Code clang lipo fat binary MachO ld ld o-files o-file
  12. 23.

    5 Oct 2015 @orta @mrackwitz INSIDE LD 1 2 3


    4 5 6 #main.swift import monkey import BananaKit let m = MKMonkey(.Small) let t = BKBananaTree() t.fruits.first.peel(m) 1 2 3
 4 5 6 7 8 9 10 11 12 #BananaKit.swift import monkey public class BKBananaTree { var fruits: [BKBananaFruit] public struct BKBananaFruit { var peeledByMonkey: MKMonkey? public func peel(m: MKMonkey) { peeledByMonkey = m } } } 1 2 3
 4 5 6 7 8 9 10 #monkey.swift public enum MKSize { case Small case Big } public class MKMonkey { public let size: MKSize public init(_ size: MKSize) { self.size = size } }
  13. 24.

    5 Oct 2015 @orta @mrackwitz INSIDE LD 1 2 3


    4 5 6 #main.swift import monkey import BananaKit let m = MKMonkey(.Small) let t = BKBananaTree() t.fruits.first.peel(m) MKMonkey MKSize.Small BKBananaTree 1 2 3
 4 5 6 7 8 9 10 11 12 #BananaKit.swift import monkey public class BKBananaTree { var fruits: [BKBananaFruit] public struct BKBananaFruit { var peeledByMonkey: MKMonkey? public func peel(m: MKMonkey) { peeledByMonkey = m } } } BKBananaTree 1 2 3
 4 5 6 7 8 9 10 #monkey.swift public enum MKSize { case Small case Big } public class MKMonkey { public let size: MKSize public init(_ size: MKSize) { self.size = size } } BKBananaTree.peel MKMonkey MKSize MKMonkey.init MKSize.Big MKMonkey MKMonkey.size MKSize.Small BKBananaTree.peel Array Array.first
  14. 27.

    5 Oct 2015 @orta @mrackwitz DYNAMIC FRAMEWORKS NEED TO BE

    EMBEDDED CocoaPods allows different sets of dependencies per build configuration.
 
 pod 'Lookback', :configurations => ['Debug']
  15. 28.

    5 Oct 2015 @orta @mrackwitz WHAT HAPPENS ON COPY Header

    Stripping
 Headers are only needed to integrate the library for the compiler and shouldn’t be shipped Code Signing
 Frameworks are all signed individually and excluded from the whole app bundle signature
  16. 29.

    5 Oct 2015 @orta @mrackwitz FRAMEWORKS IN COMPARISON TO STATIC

    LIBS Advantages Easier to distribute & integrate if compiled Reduces file size if used for app & extensions Separate resources in distinct bundles Disadvantages Optimization is limited to LTO Limits dead-code stripping Increases load times
  17. 30.

    5 Oct 2015 @orta @mrackwitz WHAT MEANS THAT FOR COCOAPODS

    We need to support Clang Modules, too. DSL-extensions for Podfile and Podspec Bundle Resources into Frameworks Workaround issues with swift-stdlib-tool Code Signing
  18. 32.

    5 Oct 2015 @orta @mrackwitz TRANSITIONING FROM STATIC LIBRARIES TO

    FRAMEWORKS gem install cocoapods-deintegrate pod deintegrate
  19. 34.

    5 Oct 2015 @orta @mrackwitz TRANSITIONING FROM STATIC LIBRARIES TO

    FRAMEWORKS Deletes Pods/. Removes the CocoaPods Xcode group. Removes these three build phases: Copy Pods Resources Check Pods Manifest.lock Embed Pods Frameworks
  20. 35.

    5 Oct 2015 @orta @mrackwitz TRANSITIONING FROM STATIC LIBRARIES TO

    FRAMEWORKS Add use_frameworks! to Podfile. Run pod install. Run tests.
  21. 36.

    5 Oct 2015 @orta @mrackwitz COMMON ISSUES Pods depending on

    static libraries Libraries expecting resources in the main bundle UIFont pods Pods that change behaviour using #defines
  22. 40.

    App Launch Time Increased github.com/artsy/eigen/issues/586 3rd Party Frameworks have O(N^2)

    lookup time Could be in library launching Could be in library code sign verification Looking like solution is on app deployment to bundle all framework symbols into one
  23. 43.

    5 Oct 2015 @orta @mrackwitz Come help out @mrackwitz /

    @orta / @CocoaPods cocoapods.org/get-started