Slide 1

Slide 1 text

CocoaPods ! iOSDevCampDC, September 2015 Boris Bügling - @NeoNacho

Slide 2

Slide 2 text

CocoaPods

Slide 3

Slide 3 text

Contentful

Slide 4

Slide 4 text

Agenda • What's new and upcoming • CocoaPods plugins • How does CocoaPods even • Troubleshooting and Tips

Slide 5

Slide 5 text

What's new and upcoming

Slide 6

Slide 6 text

CocoaPods 0.38

Slide 7

Slide 7 text

support for watchOS Pod::Spec.new do |s| # … s.watchos.deployment_target = '2.0' end

Slide 8

Slide 8 text

Target Deduplication Happens by default, exceptions: • They are used on different platforms. • They are used with differents sets of subspecs. • They have any dependency which needs to be duplicated.

Slide 9

Slide 9 text

Breaking Change to the Hooks- API post_install do |installer_or_rep| # @note: Remove after CocoaPods 0.38+ is completely rolled out # and rename block argument to `installer`. installer = installer_or_rep.respond_to?(:installer) ? installer_or_rep.installer : installer_or_rep # You can use the installer from now on. end

Slide 10

Slide 10 text

Split of xcconfig • pod_target_xcconfig • user_target_xcconfig

Slide 11

Slide 11 text

Other changes • Removal of the Enviroment Header • Deterministic UUIDs by Xcodeproj • Resolver takes the Deployment Target into account

Slide 12

Slide 12 text

Make sure you check out blog.cocoapods.org and the CHANGELOG for major releases

Slide 13

Slide 13 text

CocoaPods 0.39 • currently beta 4 • Vendored dynamic frameworks ! • --private option for linting (ignore warnings only suitable for trunk) • HEADER_SEARCH_PATHS is no longer constructed recursively

Slide 14

Slide 14 text

Road to 1.0

Slide 15

Slide 15 text

Major Changes Customizable Installation

Slide 16

Slide 16 text

Customizable Installation • --no-integrate • Same default • Pass options to the installer

Slide 17

Slide 17 text

Major Changes Target Inheritance

Slide 18

Slide 18 text

Target Inheritance • :exclusive => true • New options • Complete • Search paths • None

Slide 19

Slide 19 text

Target Inheritance • Allows test targets to work • Allows for more 'logical' Podfiles

Slide 20

Slide 20 text

Coming this fall Hopefully

Slide 21

Slide 21 text

CocoaPods plugins

Slide 22

Slide 22 text

CocoaPods plugins • Add subcommands to pod, the tool • post_install hook • Each plugin is a Gem

Slide 23

Slide 23 text

Do whatever you want, because Ruby !

Slide 24

Slide 24 text

Useful plugins

Slide 25

Slide 25 text

$ pod plugins list

Slide 26

Slide 26 text

$ pod keys set AccessToken 0xFFFFFFFF

Slide 27

Slide 27 text

$ pod package ContentfulDeliveryAPI.podspec

Slide 28

Slide 28 text

$ pod lib coverage

Slide 29

Slide 29 text

$ pod roulette

Slide 30

Slide 30 text

How to build your own plugin

Slide 31

Slide 31 text

$ pod plugins create cocoapods-awesome-plugin

Slide 32

Slide 32 text

$ tree . ├── Gemfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── cocoapods_awesome_plugin.gemspec └── lib ├── cocoapods_awesome_plugin.rb ├── cocoapods_plugin.rb └── pod └── command └── plugin.rb 3 directories, 8 files

Slide 33

Slide 33 text

module Pod class Command class Plugin < Command self.summary = "Short description." self.arguments = [CLAide::Argument.new('NAME', true)] def initialize(argv) @name = argv.shift_argument super end def validate! super help! "A Pod name is required." unless @name end def run UI.puts "Add your implementation here" end

Slide 34

Slide 34 text

Hooks

Slide 35

Slide 35 text

Pod::HooksManager.register(:post_install) do |options| require 'installer' UI.puts "This gets executed after installation" end

Slide 36

Slide 36 text

How does CocoaPods even

Slide 37

Slide 37 text

use_frameworks!

Slide 38

Slide 38 text

Build Phases

Slide 39

Slide 39 text

Check Pods Manifest.lock diff "${PODS_ROOT}/../Podfile.lock" "${PODS_ROOT}/Manifest.lock" > /dev/null if [[ $? != 0 ]] ; then cat << EOM error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation. EOM exit 1 fi

Slide 40

Slide 40 text

Link Binary With Libraries • Links the aggregate framework • Gets build via implicit dependencies

Slide 41

Slide 41 text

Radar 22392501 Actual Results: It doesn't. You receive this error when archiving: [...] So, because they have the same product name, they're overriding each other. How are we supposed to use our own frameworks from our different target types?

Slide 42

Slide 42 text

Embed Pods Frameworks • Copies the frameworks to the application bundle

Slide 43

Slide 43 text

Copy Pods Resources • Copies resources to the application bundle

Slide 44

Slide 44 text

Troubleshooting

Slide 45

Slide 45 text

Mixing Objective-C and Swift in a Pod • Frameworks can't have a separate bridging header • Objective-C headers can be included in the umbrella header

Slide 46

Slide 46 text

First solution: module imports import ObjectiveCPod => You get the full public API

Slide 47

Slide 47 text

Second solution: publiclize all the things • Create a header • Import all the Objective-C headers you need • Add that header to public_header_files => Exposes the dependency in the public API

Slide 48

Slide 48 text

Third solution: custom module map • Module maps can have private submodules framework module ResearchKit { umbrella header "ResearchKit.h" module Private { umbrella header "ResearchKit_Private.h" export * } export * module * { export * } } • Can be declared in the podspec with module_map

Slide 49

Slide 49 text

Reset your integration $ gem install cocoapods-deintegrate $ pod deintegrate $ pod install

Slide 50

Slide 50 text

rm -rf $HOME/ Library/Developer/ Xcode/DerivedData

Slide 51

Slide 51 text

Filing issues • Read our contribution guidelines • Try if your problem reproduces in a separate project • Give us that project! => Help us help you

Slide 52

Slide 52 text

It gets really old creating countless projects every day :)

Slide 53

Slide 53 text

Tips

Slide 54

Slide 54 text

Use bundler to pin your used CocoaPods version $ cat Gemfile source 'https://rubygems.org' gem 'cocoapods', '= 0.36.0.beta.1' $ bundle install $ bundle exec pod install # from now on

Slide 55

Slide 55 text

Make sure your dependencies don't go away • Commit the Pods directory • Mirror your Pods (https://github.com/xing/ XNGPodsSynchronizer)

Slide 56

Slide 56 text

You can keep the Pods history separate • Create an orphaned branch on your repo • Check it out as a submodule to Pods • History is now completely separate

Slide 57

Slide 57 text

Automate your workflow • Use plugins • Use a Rakefile or Makefile for common tasks • Use pre_install or post_install hooks in the Podfile

Slide 58

Slide 58 text

Thank you!

Slide 59

Slide 59 text

@NeoNacho [email protected] http://buegling.com/talks