Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

What is CocoaPods?

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

TERMINOLOGY

Slide 6

Slide 6 text

WORKSPACE

Slide 7

Slide 7 text

TARGETS

Slide 8

Slide 8 text

BUILD PHASE

Slide 9

Slide 9 text

Integration History

Slide 10

Slide 10 text

Static Libraries COMMON DENOMINATOR UNTIL IOS 7.0

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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


Slide 15

Slide 15 text

COCOAPODS HAS TO BUNDLE RESOURCES

Slide 16

Slide 16 text

Dynamic Frameworks REQUIRED FOR SWIFT

Slide 17

Slide 17 text

5 Oct 2015 @orta @mrackwitz INSIDE A FRAMEWORK

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

5 Oct 2015 @orta @mrackwitz DYNAMIC FRAMEWORKS NEED TO BE EMBEDDED CocoaPods allows different sets of dependencies per build configuration.
 
 pod 'Lookback', :configurations => ['Debug']

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

Transitioning

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

TRANSITIONING FROM STATIC LIBRARIES TO FRAMEWORKS

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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