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

XcodeGen

Ste Prescott
December 02, 2018

 XcodeGen

XcodeGen is a tool that generates your Xcode project file and helps manage your projects settings & configuration. This deck shows how you could use it in your own projects.

Ste Prescott

December 02, 2018
Tweet

Other Decks in Programming

Transcript

  1. // !$*UTF8*$! { archiveVersion = 1; classes = { };

    objectVersion = 50; objects = { /* Begin PBXBuildFile section */ 8B53914821B4057D00E124A0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B53914721B4057D00E124A0 /* AppDelegate.swift */; }; 8B53914A21B4057D00E124A0 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B53914921B4057D00E124A0 /* ViewController.swift */; }; 8B53914D21B4057D00E124A0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8B53914B21B4057D00E124A0 /* Main.storyboard */; }; 8B53914F21B4057F00E124A0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8B53914E21B4057F00E124A0 /* Assets.xcassets */; }; 8B53915221B4057F00E124A0 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8B53915021B4057F00E124A0 /* LaunchScreen.storyboard */; }; 8B53915D21B4057F00E124A0 /* XcodeGenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B53915C21B4057F00E124A0 /* XcodeGenTests.swift */; }; 8B53916821B4057F00E124A0 /* XcodeGenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B53916721B4057F00E124A0 /* XcodeGenUITests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ 8B53915921B4057F00E124A0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 8B53913C21B4057D00E124A0 /* Project object */; proxyType = 1; remoteGlobalIDString = 8B53914321B4057D00E124A0; remoteInfo = XcodeGen; }; 8B53916421B4057F00E124A0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 8B53913C21B4057D00E124A0 /* Project object */; proxyType = 1; remoteGlobalIDString = 8B53914321B4057D00E124A0; remoteInfo = XcodeGen; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ 8B53914421B4057D00E124A0 /* XcodeGen.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = XcodeGen.app; sourceTree = BUILT_PRODUCTS_DIR; }; 8B53914721B4057D00E124A0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; 8B53914921B4057D00E124A0 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; }; 8B53914C21B4057D00E124A0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; 8B53914E21B4057F00E124A0 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 8B53915121B4057F00E124A0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 8B53915321B4057F00E124A0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 8B53915821B4057F00E124A0 /* XcodeGenTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XcodeGenTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 8B53915C21B4057F00E124A0 /* XcodeGenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XcodeGenTests.swift; sourceTree = "<group>"; }; 8B53915E21B4057F00E124A0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 8B53916321B4057F00E124A0 /* XcodeGenUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XcodeGenUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 8B53916721B4057F00E124A0 /* XcodeGenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XcodeGenUITests.swift; sourceTree = "<group>"; }; 8B53916921B4057F00E124A0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 8B53915521B4057F00E124A0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ ... 586 lines
  2. .xcodeproj files » Ugly to read » Big reason of

    merge conflicts » If corrupt good luck » Difficult to code review & diff » A lot of noise
  3. General project checklist » Code / Resources » Tests »

    Additional targets (App Extensions, Static Libraries, ...) » Dependencies » Environments
  4. Quick check What do we have? » A project »

    Unit & UI test testing » A linked dependency » Configuration based on environments
  5. Add unit test target ... XcodeGenTests: platform: iOS type: bundle.unit-test

    sources: - XcodeGenTests dependencies: - target: XcodeGen ...
  6. Add UI test target ... XcodeGenUITests: platform: iOS type: bundle.ui-testing

    sources: - XcodeGenUITests dependencies: - target: XcodeGen
  7. name: XcodeGen options: bundleIdPrefix: me.steprescott targets: XcodeGen: platform: iOS type:

    application sources: - XcodeGen XcodeGenTests: platform: iOS type: bundle.unit-test sources: - XcodeGenTests dependencies: - target: XcodeGen XcodeGenUITests: platform: iOS type: bundle.ui-testing sources: - XcodeGenUITests dependencies: - target: XcodeGen
  8. Quick tip! You can split the project configuration over multiple

    smaller .yml files. . !"" Project # !"" Targets # # !"" XcodeGen.yml # # !"" XcodeGenTests.yml # # $"" XcodeGenUITests.yml # $"" targets.yml $"" project.yml
  9. Add a new .yml file . !"" Project # !""

    Targets + # # !"" NotificationServiceExtension.yml # # !"" XcodeGen.yml # # !"" XcodeGenTests.yml # # $"" XcodeGenUITests.yml # $"" targets.yml $"" project.yml
  10. . !"" Project # !"" Configs + # # !""

    Development.xcconfig + # # $"" Production.xcconfig # !"" Schemes + # # !"" Development.yml + # # $"" Production.yml # !"" Targets # # !"" NotificationServiceExtension.yml # # !"" XcodeGen.yml # # !"" XcodeGenTests.yml # # $"" XcodeGenUITests.yml + # !"" configs.yml + # !"" schemes.yml # $"" targets.yml $"" project.yml
  11. schemes: Development: build: parallelizeBuild: true targets: XcodeGen: all XcodeGenTests: testing

    XcodeGenUITests: testing run: config: Development test: config: Development targets: - XcodeGenTests - XcodeGenUITests profile: config: Development analyze: config: Development archive: config: Development
  12. schemes: Production: build: parallelizeBuild: true targets: XcodeGen: all XcodeGenTests: testing

    XcodeGenUITests: testing run: config: Production test: config: Production targets: - XcodeGenTests - XcodeGenUITests profile: config: Production analyze: config: Production archive: config: Production
  13. Quick check Do we have the same as before? »

    A project » Unit & UI test testing » A linked dependency » Configuration based on environments
  14. Comparisons Before After Line count 1,915 575 Merge risk High

    None Code review Noisy Focused » 30% the size of the original project » Settings / configurations more visible
  15. Generating the .xcodeproj Install XcodeGen with Homebrew Run xcodegen via

    CLI or add Git hooks Post-checkout & Post-merge #!/bin/bash export PATH=/usr/local/bin:$PATH set -e echo " ! Running hook" xcodegen