Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CocoaPods Frameworks with Marius Rackwitz

Orta
October 05, 2015

CocoaPods Frameworks with Marius Rackwitz

The history of CocoaPods frameworks.
Advice on how you can do it.

Orta

October 05, 2015
Tweet

More Decks by Orta

Other Decks in Programming

Transcript

  1. 5 Oct 2015
    @orta
    @mrackwitz
    Marius Rackwitz & Orta Therox
    CocoaPods Frameworks

    View Slide

  2. View Slide

  3. What is CocoaPods?

    View Slide

  4. 5 Oct 2015
    @orta
    @mrackwitz
    WHAT IS COCOAPODS?
    A dependency manager
    A community around mostly open source code
    5 years old

    View Slide

  5. TERMINOLOGY

    View Slide

  6. WORKSPACE

    View Slide

  7. TARGETS

    View Slide

  8. BUILD PHASE

    View Slide

  9. Integration History

    View Slide

  10. Static Libraries
    COMMON DENOMINATOR UNTIL IOS 7.0

    View Slide

  11. 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

    View Slide

  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

    View Slide

  13. 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

    View Slide

  14. 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);

    }


    View Slide

  15. COCOAPODS HAS TO BUNDLE RESOURCES

    View Slide

  16. Dynamic Frameworks
    REQUIRED FOR SWIFT

    View Slide

  17. 5 Oct 2015
    @orta
    @mrackwitz
    INSIDE A FRAMEWORK

    View Slide

  18. 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

    View Slide

  19. 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

    View Slide

  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

    View Slide

  21. 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

    View Slide

  22. 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
    }
    }

    View Slide

  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)
    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

    View Slide

  24. 5 Oct 2015
    @orta
    @mrackwitz
    DYNAMIC FRAMEWORKS NEED TO BE EMBEDDED

    View Slide

  25. 5 Oct 2015
    @orta
    @mrackwitz
    DYNAMIC FRAMEWORKS NEED TO BE EMBEDDED

    View Slide

  26. 5 Oct 2015
    @orta
    @mrackwitz
    DYNAMIC FRAMEWORKS NEED TO BE EMBEDDED
    CocoaPods allows different sets of dependencies
    per build configuration.


    pod 'Lookback', :configurations => ['Debug']

    View Slide

  27. 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

    View Slide

  28. 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

    View Slide

  29. 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

    View Slide

  30. Transitioning

    View Slide

  31. 5 Oct 2015
    @orta
    @mrackwitz
    TRANSITIONING FROM STATIC LIBRARIES TO FRAMEWORKS
    gem install cocoapods-deintegrate
    pod deintegrate

    View Slide

  32. TRANSITIONING FROM STATIC LIBRARIES TO FRAMEWORKS

    View Slide

  33. 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

    View Slide

  34. 5 Oct 2015
    @orta
    @mrackwitz
    TRANSITIONING FROM STATIC LIBRARIES TO FRAMEWORKS
    Add use_frameworks! to Podfile.
    Run pod install.
    Run tests.

    View Slide

  35. 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

    View Slide

  36. 1st App With CocoaPods Frameworks
    github.com/artsy/eidolon/pull/317

    View Slide

  37. Simple Transition, old app
    github.com/artsy/energy/pull/50

    View Slide

  38. Large codebase, ~60 pods
    github.com/artsy/eigen/pull/520

    View Slide

  39. 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

    View Slide

  40. App Launch Time Increased
    github.com/artsy/eigen/issues/586

    View Slide

  41. 5 Oct 2015
    @orta
    @mrackwitz
    Come help out
    @mrackwitz / @orta / @CocoaPods
    cocoapods.org/get-started

    View Slide