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

Adding 3rd Party Code to Xcode Projects

Adding 3rd Party Code to Xcode Projects

My talk from iOSCon 2014. Covers adding code directly, managed by Git Submodules and CocoaPods.

The video for this talk is available at https://skillsmatter.com/skillscasts/5058-third-party-code

Abizer Nasir

May 15, 2014
Tweet

More Decks by Abizer Nasir

Other Decks in Programming

Transcript

  1. ADDING 3RD PARTY CODE TO YOUR PROJECT
    ABIZER NASIR | ABIZERN.ORG | @ABIZERN

    View Slide

  2. Adam Evans https://flic.kr/p/8qki95

    View Slide

  3. ADD THE FILES DIRECTLY

    View Slide

  4. ADD THE FILES DIRECTLY
    • Probably the easiest way.
    • Download the files, drag them to the project.
    • Behaves like any other part of the project.
    • Easy to change the code.

    View Slide

  5. DISADVANTAGES
    • ARC/MRR?
    • Code warnings, errors.
    • Changes to the original code can’t easily be folded in.
    • Lose history.

    View Slide

  6. ++ADD THE FILES DIRECTLY

    View Slide

  7. ++ADD THE FILES DIRECTLY
    • Use some kind of version control to download the source, or project.
    • Add the files directly as before
    • Behaves like any other part of the project.
    • Easy to change the code.

    View Slide

  8. DISADVANTAGES
    • ARC/MRR?
    • Code warnings, errors.
    • Changes to the original code can’t easily be folded in.
    • Lose history.

    View Slide

  9. SUMMARY
    • For small classes, or categories. This is an easy way to get external
    code into a project.
    • For anything larger, or which has dependencies, there is an
    alternative.

    View Slide

  10. STATIC LIBRARIES

    View Slide

  11. STATIC LIBRARIES
    • An archive of code that can be linked against, with headers for the
    public interface.
    • Not just code, but resources can be included in a bundle that the
    consuming application can copy into it’s own bundle.
    • May have their own dependencies.

    View Slide

  12. STATIC LIBRARIES
    • Some come as pre-built libs
    • OCMock
    • Some come with scripts that create the libs
    • Specta
    • Most come with decent instructions about integration
    • Some are just projects built for CocoaPods that don’t build libraries cleanly
    • Sad Panda

    View Slide

  13. WHY THEY ARE USEFUL
    • They build with their own ARC/MRR settings that don’t need to match
    the consuming application
    • They build with their own settings configuration, so errors/warnings,
    if any, are confined to the library build phase and not yours.
    • They build the correct architecture

    View Slide

  14. ADDING A LIBRARY TO YOUR PROJECT

    View Slide

  15. STEP 1
    DRAG THE LIBRARY INTO
    THE PROJECT

    View Slide

  16. STEP 2
    ADD THE LIBRARY
    TARGET AS A
    DEPENDENCY AND
    LINK AGAINST THE
    ARCHIVE

    View Slide

  17. STEP 3 WAVE THE RUBBER CHICKEN
    • Sometimes you’ll need to fix a few things:
    • Specify the public header path for the library so that you can use
    • #import
    • Specify the search path for archived builds so that you can
    distribute your application to testers
    • Add `-ObjC` `-force_load “some_path”` to the Other Linker Flags.

    View Slide

  18. CREATE A LIBRARY
    BEING A GOOD CITIZEN

    View Slide

  19. STEP 1
    USE THE CORRECT
    TEMPLATE

    View Slide

  20. STEP 2
    ADD A COPY HEADERS
    BUILD PHASE

    View Slide

  21. STEP 3 WAVE THE RUBBER CHICKEN
    • Make sure the public headers go into the correct place when building
    • Make sure the search paths are set up correctly
    • Set up valid architectures, warnings, errors.
    • Help is at hand…

    View Slide

  22. CONFIGURATION FILES
    • https://github.com/jspahrsummers/
    xcconfigs
    • Available when added to the project.
    • Sensible and opinionated configurations
    for different build targets.
    • Not just for libraries, use them for apps
    as well.
    • Set the top level to “why” and the
    secondary levels to “what”.

    View Slide

  23. View Slide

  24. DOCUMENTATION
    • Decide whether you need -ObjC (YES if you have categories on pre-
    existing classes) or -force_load linker flags (YES if your library only
    has categories and no classes), and document them.
    • Provide installation instructions, whether using CocoaPods or adding
    the project to a project or workspace

    View Slide

  25. COCOAPODS

    View Slide

  26. DEPENDENCY MANAGEMENT, AND MORE
    • If you’ve ever used a Ruby gem the idea of this will be familiar to you.
    • 3rd party source files and resources are fetched from a specified
    location, built into a static library which is added to an Xcode
    workspace that contains your original project.
    • From now on, you need to use the workspace not the project.

    View Slide

  27. PODFILE - SPECIFIES DEPENDENCIES
    • Uses a Ruby DSL.
    • Add pods to the targets in your app by
    name, or location.
    • Run `pod install`
    • CocoaPods will determine and install
    any other dependencies for those pods
    • The Pods folder contains the source,
    headers, project to build the library
    and more (acknowledgements,
    bundling scripts)

    View Slide

  28. PODS FOLDER
    • This is where almost all of the Pod output is sent to. It contains the
    sources, the config files, the static library project, the
    acknowledgements file.
    • Usually added to source control, even though it is generated. It’s not
    always guaranteed to be regenerated in the same state.
    • Useful to have a known state of the source when going back in
    history.

    View Slide

  29. PODFILE.LOCK
    • Should be checked into version control, specifies the version of pods
    to checkout on `pod install`
    • Resets when the Podfile dependency changes or `pod update` is run.
    • This is what tries to keep all repositories in sync.
    • Anybody else checking out the code just needs to run `pod install`
    and should get the same version.

    View Slide

  30. CREATING A COCOAPOD
    • You don’t need a working project (although it would be nice. Thanks)
    • Create a stub podspec file by running `pod spec create `
    • A large, well commented file is created which is easy to fill in.
    • run `pod lib lint` to validate the file
    • Alternatively, `pod lib create` to generate a folder structure. Write your source
    and then run `rake release` which takes care of tagging and versioning.
    • Submit a pull request to have it added to the repository.

    View Slide

  31. View Slide

  32. COCOAPODS? WE DON’T NEED NO STEENKIN’ COCOAPODS!
    Treasure of the Sierra Madre, Warner Bros 1948.

    View Slide

  33. GIT SUBMODULES

    View Slide

  34. GIT SUBMODULES
    • A Git repository that is added as a subdirectory of another Git
    repository.
    • The contents of the subdirectory are not tracked by the containing
    repository, the the commit hash.
    • It is checked out at a particular commit.
    • The submodule communicates with it’s own upstream repository
    independently of the containing repository.

    View Slide

  35. STORAGE
    • The .gitmodules file has a reference to the URL of the submodule and
    the directory which contains it. Shared with all repositories.
    • The .git/config file has a reference to the URL of the submodule and
    directory which contains it. Local to the current repository
    • The .git/modules folder has the actual git repositories for the
    submodule
    • The commit hash is stored in the repository.

    View Slide

  36. ADDING A SUBMODULE
    • `git submodule add `
    • You can go into the checked out folder and change checked out
    version.
    • Check the module into the repository. This only updates the commit
    hash, not the added code.
    • Tip: Always use your own fork of a repository as the main submodule.

    View Slide

  37. SHARING THE REPOSITORY - SHORT
    • short
    • `git clone —recursive `
    • shortish, if you have a bootstrap script
    • `git clone 

    ./script/bootstrap`

    View Slide

  38. SHARING THE REPOSITORY - LONGER
    • Clone the repo
    • `git clone `
    • Apply global repository settings to local repository
    • `git submodule init`
    • Actually setup the submodules
    • `git submodule update`

    View Slide

  39. CREATING A SUBMODULE
    • There is nothing to do. It’s just a library.
    • Specify the exact submodules and dependencies if required with a
    bootstrap script.
    • https://github.com/jspahrsummers/objc-build-scripts

    View Slide

  40. A RECURSIVE BOOTSTRAP
    https://github.com/jspahrsummers/objc-build-scripts

    View Slide

  41. HANDY TIPS
    • Check your submodules with `git submodule status`
    • Keep your submodules up to date - bootstrap or `git submodule
    update`
    • ALWAYS push changes to your submodule before committing to the
    enclosing repository
    • Use your own clone as submodules.

    View Slide

  42. WHICH SHOULD YOU USE?

    View Slide

  43. LOVERS
    CocoaPods Git Submodules
    Written by crazy, clever, passionate people
    There are some interesting edge cases that both can handle: Private repositories, fixed point checkouts. Try
    code before you buy.
    Most of the effort is in the setup, rolling out to others is easier after that.
    Builds libraries, doesn’t just dump code in the project, there is some audit trail of who did what.

    View Slide

  44. FIGHTERS
    CocoaPods Git Submodules
    Fast to set up Slower to set up. Integration is on you.
    Not tied to a VCS, doesn’t even need a VCS Needs Git repositories
    Dependency manager A dumb content tracker
    Quick to learn er…
    External code is just put into the project. No history, no
    logs directly accessible
    Full repository. See history, access all the code, run
    tests
    Encourages a consumption model
    Full project is available. Changes can be made, pushed
    to others while a pull request is pending
    Acknowledgements, external bundles subspecs. Shut up, I’m just a content tracker.
    Adds a dependency to manage dependencies You have Git already, you can manage the rest.

    View Slide

  45. SO, WHICH SHOULD YOU USE?
    • Pick the method that best suits the working environment
    • Which are you best able to support?
    • Do you see the value in the ancillary services that CocoaPods
    provides?
    • Almost anything you can do in one you can do in another.

    View Slide

  46. DOES IT MATTER?
    • Arguing about this is like arguing about the supremacy of Android/
    iOS (IMHO).
    • Choices like this are not always technical. They are related to the
    environment, product, the 3rd party code, even personality.
    • Compared to actually developing YOUR app, the time and
    complexity of using one or the other is minimal.
    • Pick one. Get really good at it. Be able to work with the other.

    View Slide

  47. THANK YOU FOR LISTENING!

    View Slide