$30 off During Our Annual Pro Sale. View Details »

Creating a Swift Library

Jeff
March 03, 2016

Creating a Swift Library

Talk about all the infrastructure required to creating a cross-platform swift library.

Note: these slides may make more sense in the context of the presentation. Videos may be published in the next few weeks.

Supplementary Material:

- https://github.com/jeffh/Snorlax is the sample library that integrates with as many platforms that Swift currently supports.
- https://github.com/jeffh/SnorlaxSamples has some sample integrations of all the package managers.

Try! Swift 2016 Talk

Jeff

March 03, 2016
Tweet

More Decks by Jeff

Other Decks in Technology

Transcript

  1. View Slide

  2. Your Awesome Code
    Platforms
    Continuous Integration
    Releases
    Installation

    View Slide

  3. SWIFT LIBRARY
    CREATING A

    View Slide

  4. Example

    View Slide

  5. View Slide

  6. import Foundation
    /// Sleeps for a random time interval
    public func rest() {
    let interval = NSTimeInterval(random() % 2)
    NSThread.sleepForTimeInterval(interval)
    }

    View Slide

  7. import XCTest
    import Snorlax
    import Foundation
    class SnorlaxTests: XCTestCase {
    func testRest() {
    let expectation = expectationWithDescription("Resting")
    dispatch_async(dispatch_get_main_queue()) {
    rest()
    expectation.fulfill()
    }
    waitForExpectationsWithTimeout(5, handler: nil)
    }
    }

    View Slide

  8. View Slide

  9. View Slide

  10. App Extensions Allow app extension API only

    View Slide

  11. import Snorlax
    PRODUCT_MODULE_NAME

    View Slide

  12. View Slide

  13. View Slide

  14. Testing

    View Slide

  15. Xcode Betas
    Matrix Builds
    Managed CI
    Github Integration

    View Slide

  16. # .travis.yml
    osx_image: xcode7.2
    language: objective-c
    script: ./test

    View Slide

  17. #!/bin/bash
    # ./test script
    set -e # stop when a test fails
    xcodebuild test
    -scheme Snorlax-OSX
    -destination "platform=OS X"
    xcodebuild test
    -scheme Snorlax-iOS
    -destination "platform=iOS Simulator,name=iPhone 6,OS=9.2"
    xcodebuild test
    -scheme Snorlax-tvOS
    -destination "platform=tvOS Simulator,name=Apple TV 1080p,OS=9.1"

    View Slide

  18. View Slide

  19. View Slide

  20. View Slide

  21. pod spec create Snorlax

    View Slide

  22. View Slide

  23. carthage build —no-skip-current

    View Slide

  24. View Slide

  25. // Package.swift
    import PackageDescription
    let package = Package(
    name: "Snorlax"
    )

    View Slide

  26. Snorlax/
    |- Package.swift
    |- Sources/
    | |- Snorlax/
    | | |- Snorlax.swift

    View Slide

  27. Snorlax/
    |- Package.swift
    |- Sources/
    |- Tests/
    | |- Snorlax/
    | | |- SnorlaxTest.swift

    View Slide

  28. Snorlax/
    |- Package.swift
    |- Sources/
    |- Tests/
    | |- LinuxMain.swift
    | |- Snorlax/

    View Slide

  29. LinuxMain.swift

    View Slide

  30. // LinuxMain.swift
    import XCTest
    @testable import Snorlaxtest
    // This is the entry point for tests on Linux
    XCTMain([
    SnorlaxTests(),
    ])

    View Slide

  31. // ... SnorlaxTests.swift ...
    class SnorlaxTests: XCTestCase, XCTestCaseProvider {
    var allTests: [(String, () throws -> Void)] {
    return [("testRest", testRest)]
    }
    func testRest() {
    let start = NSDate()
    rest()
    let end = NSDate()
    let duration = end.timeIntervalSinceDate(start)
    XCTAssertGreaterThanOrEqual(duration, 0)
    XCTAssertLessThan(duration, 2)
    }
    }

    View Slide

  32. // ... SnorlaxTests.swift ...
    class SnorlaxTests: XCTestCase, XCTestCaseProvider {
    var allTests: [(String, () throws -> Void)] {
    return [("testRest", testRest)]
    }
    func testRest() {
    let start = NSDate()
    rest()
    let end = NSDate()
    let duration = end.timeIntervalSinceDate(start)
    XCTAssertGreaterThanOrEqual(duration, 0)
    XCTAssertLessThan(duration, 2)
    }
    }

    View Slide

  33. #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
    public protocol XCTestCaseProvider {
    var allTests: [(String, () throws -> Void)] { get }
    }
    #endif
    class SnorlaxTests: XCTestCase, XCTestCaseProvider {
    ...
    }

    View Slide

  34. swift build
    swift test

    View Slide

  35. DEVELOPMENT-SNAPSHOT-2016-03-01-a
    DEVELOPMENT-SNAPSHOT-2016-02-25-a
    DEVELOPMENT-SNAPSHOT-2016-02-08-a
    DEVELOPMENT-SNAPSHOT-2016-02-03-a

    View Slide

  36. SwiftEnv
    github.com/kylef/swiftenv

    View Slide

  37. swiftenv install DEVELOPMENT-SNAPSHOT-2016-03-01-a
    swiftenv local DEVELOPMENT-SNAPSHOT-2016-03-01-a

    View Slide

  38. # .travis.yml
    osx_image: xcode7.2
    language: generic
    matrix:
    include:
    - os: osx
    env: TYPE=xcode
    - os: osx
    env: TYPE=spm
    - os: linux
    dist: trusty
    sudo: required
    env: TYPE=spm
    # Install SwiftEnv
    install: if [[ "$TYPE" == "spm" ]]; then eval "$(curl -sL https://…)"; fi
    script: ./test $TYPE

    View Slide

  39. View Slide

  40. Creating a Release

    View Slide

  41. 1.2.3
    Major Minor Patch
    semver.org

    View Slide

  42. TEXT
    CUTTING A RELEASE
    ▸ Update version in Podspec (commit and push it)
    ▸ Tag new version: git tag v0.1.2
    ▸ Push tag: git push origin v0.1.2
    ▸ Push podspec: pod trunk push Snorlax.podspec
    ▸ Create a release from a tag in Github
    ▸ Announce!

    View Slide

  43. github.com/jeffh/Snorlax
    github.com/jeffh/SnorlaxSamples

    View Slide

  44. JEFFHUI.NET
    @JEFFHUI
    THANKS!

    View Slide