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

'Improving Xcode build time​' by Sameh Mabrouk

'Improving Xcode build time​' by Sameh Mabrouk

Sameh will describe few things:
- The problem of relatively high build times with CocoaPods
- How to deal with it
- How to handle it
- What Swift issues may arise while customizing your build process

This talk was made for CocoaHeads Kyiv #13 which took place Dec 16 2017.

CocoaHeads Ukraine

December 16, 2017
Tweet

More Decks by CocoaHeads Ukraine

Other Decks in Programming

Transcript

  1. IMPROVING
    XCODE BUILD TIME
    One Approach
    2017-Sameh Mabrouk, Mobiquity - @same7mabrouk

    View Slide

  2. INDEX
    Problem
    Solutions/Approaches
    Demo
    Result
    References

    View Slide

  3. INDEX
    Problem
    Solutions/Approaches
    Demo
    Result
    References

    View Slide

  4. Our App build time takes around
    7-10 minutes on local machine
    20-30 minuts on CI

    View Slide

  5. Hard to do TDD(good excuse)
    Slow the development process

    View Slide

  6. INDEX
    Problem
    Solutions/Approaches
    Demo
    Result
    References

    View Slide

  7. Optimisation on code level
    More class extensions increase build time
    Type inference, Swift takes more time to infers the types

    View Slide

  8. Dependency management
    Change debug information formate to “DWARF”
    post_install do |installer|
    puts("Update debug pod settings to speed up build time")
    Dir.glob(File.join("Pods", "**", "Pods*{debug}.xcconfig")).each do |file|
    File.open(file, 'a') { |f| f.puts "\nDEBUG_INFORMATION_FORMAT = dwarf" }
    end
    end

    View Slide

  9. Dependency management
    Change debug information formate to “DWARF”
    post_install do |installer|
    puts("Update debug pod settings to speed up build time")
    Dir.glob(File.join("Pods", "**", "Pods*{debug}.xcconfig")).each do |file|
    File.open(file, 'a') { |f| f.puts "\nDEBUG_INFORMATION_FORMAT = dwarf" }
    end
    end
    simply changing one option in Xcode reduced the waiting time in 25 seconds: nice!

    View Slide

  10. Dependency management
    (CocoaPods)

    View Slide

  11. Dependency management
    (CocoaPods)
    Using Binaries/Frameworks instead of source code of dependencies

    View Slide

  12. Demo

    View Slide

  13. How to use Framework with CocoaPods
    vendored_frameworks

    View Slide

  14. How to use Framework with CocoaPods
    Update pod spec
    Add binary/framework to your remote repo
    Pod install - to get the framework

    View Slide

  15. Example1: Podspec
    Pod::Spec.new do |s|
    s.name = 'ObjectMapper'
    s.version = '2.2.8'
    s.license = 'MIT'
    s.summary = 'JSON Object mapping written in Swift'
    s.homepage = 'https://github.com/Hearst-DD/ObjectMapper'
    s.authors = { 'Tristan Himmelman' => '[email protected]' }
    s.source = { :git => 'https://github.com/Hearst-DD/ObjectMapper.git', :tag => s.version.to_s }
    s.watchos.deployment_target = '2.0'
    s.ios.deployment_target = '8.0'
    s.osx.deployment_target = '10.9'
    s.tvos.deployment_target = '9.0'
    s.pod_target_xcconfig = {
    'SWIFT_VERSION' => '3.1',
    }
    s.requires_arc = true
    s.ios.vendored_frameworks = 'framework/ObjectMapper.framework'
    end

    View Slide

  16. Example2: subspecs
    Pod::Spec.new do |s|
    s.name = 'BananaLib'
    s.version = '1.0'
    s.author = 'Banana Corp'
    s.license = 'Proprietary'
    s.homepage = 'http://banana-corp.local/banana-lib.html'
    s.summary = 'Chunky bananas!'
    s.default_subspec = 'Source'
    s.subspec 'Source' do |source|
    source.source = {
    :git => 'http://banana-corp.local/banana-lib.git',
    :tag => 'v1.0'
    }
    source.source_files = '**/*.swift'
    end
    s.subspec 'Binary' do |binary|
    binary.source = {
    :http => 'http://banana-corp.local/banana-framework.zip'
    }
    binary.vendored_frameworks = 'BananaFramework.framework'
    end
    end

    View Slide

  17. Add framework to remote repo

    View Slide

  18. Add framework to remote repo

    View Slide

  19. Automation?

    View Slide

  20. Shell script!!!, i don’t know?

    View Slide

  21. Let’s give it a try…

    View Slide

  22. #!/bin/bash
    # clonning remote git repo
    function lazyclone {
    url=$1" "$2" "$3;
    echo $url
    reponame=$(echo $url | awk -F/ '{print $NF}' | sed -e 's/.git$//');
    echo $reponame
    git clone $url $reponame;
    cd $reponame;
    }
    lazyclone $1" "$2" "$3
    # using carthage to create dynamic framework from .xcodeproj
    carthage build --no-skip-current
    cd "Carthage/Build/iOS"
    # Go back to repo main directory
    cd ..
    cd ..
    cd ..
    # Create a directory called framework that hold the binary
    mkdir framework
    # Copy .framework from Carthage/Build/iOS directory to framwork directory
    cp -R ${PWD}/Carthage/Build/iOS/$reponame.framework ${PWD}/framework
    cp -R ${PWD}/Carthage/Build/iOS/$reponame.framework.dSYM ${PWD}/framework
    # Change .podspec so it should contain s.ios.vendored_frameworks
    sed -i '' '/source_files/c\
    s.source_files = '"'""'"'
    $'\n'' ./${reponame}.podspec
    sed -i '' '/end/i\
    s.ios.vendored_frameworks = '"'"framework/${reponame}.framework"'"'
    $'\n'' ./${reponame}.podspec
    # Remove Carthage directory
    rm -r Carthage
    # Commit and push .podspec and framework to remote repo
    function lazyPush() {
    git add .
    git commit -a -m "$1"
    git push
    }
    lazyPush "Change pod spec to support dynamic framework + add dynamic framework"
    echo "Done!"
    echo "Now you have a framework for this dependency, just do pod install in your project to use it"
    echo "Have a good day!"

    View Slide

  23. Result
    Our project build time decreased by 2 minutes.
    From 7 minutes to 5 minutes

    View Slide

  24. Conclusion
    Optimizing your building process truly pays off.

    View Slide

  25. Conclusion
    It only requires spending some time on it once in a while,
    ideally only costing a few hours every few months.

    View Slide

  26. Conclusion
    It saves a considerable amount of time and money.

    View Slide

  27. Conclusion
    But, most importantly, it will make developers happier.

    View Slide

  28. Conclusion
    Engineering work, so it’s fun to do.

    View Slide

  29. References
    https://medium.com/@RobertGummesson/regarding-swift-build-time-
    optimizations-fc92cdd91e31
    https://medium.com/@RobertGummesson/regarding-swift-build-time-
    optimizations-fc92cdd91e31
    https://github.com/RobertGummesson/BuildTimeAnalyzer-for-Xcode
    https://jobs.zalando.com/tech/blog/speeding-up-xcode-builds/?
    gh_src=4n3gxh1
    https://jobs.zalando.com/tech/blog/how-the-zalando-ios-app-abandoned-
    cocoapods-and-reduced-build-time/?gh_src=4n3gxh1

    View Slide