Slide 1

Slide 1 text

Θ͍Θ͍Swift Package Manager Θ͍Θ͍swiftc #5 @giginet

Slide 2

Slide 2 text

Agenda • SPM System library • Package Description V4.2 • How to develop

Slide 3

Slide 3 text

Motivation • App Store Connect APIΫϥΠΞϯτΛSwiftͰ࡞ͬͯͨ • ৄࡉ͸iOSDC Reject Conference Day1Ͱʂʂʂ • JSON Web TokenͷॲཧʹCͷϥΠϒϥϦΛ࢖͍͔ͨͬͨ

Slide 4

Slide 4 text

System Library • ΄͔ͷύοέʔδϚωʔδϟʔͰೖΕͨStatic LibraryΛSPMͰ ఏڙ͢Δ΍ͭ

Slide 5

Slide 5 text

OpenSSL • https://github.com/IBM-Swift/OpenSSL . !"" LICENSE.txt !"" Package.swift !"" [email protected] !"" README.md !"" module.modulemap #"" shim.h

Slide 6

Slide 6 text

module.modulemap • libssl, libcryptoʹlink module OpenSSL [system] { header "shim.h" link "ssl" link "crypto" }

Slide 7

Slide 7 text

shim.h #ifndef OpenSSLHelper_h #define OpenSSLHelper_h #include #include #include #include #include #include #include #include #include #include #include #include // (ry

Slide 8

Slide 8 text

Package.swift import PackageDescription let package = Package( name: "OpenSSL", providers: [ .apt(["openssl libssl-dev"]), .brew(["openssl"]), ], products: [ .library( name: "OpenSSL", targets: ["OpenSSL"] ) ], targets: [ .target(name: "OpenSSL") ] )

Slide 9

Slide 9 text

How to init modulemap $ swift package init --type modulemap

Slide 10

Slide 10 text

How to use • .packageͰଞͷύοέʔδͱಉ͡Α͏ʹ૊ΈࠐΊΔ • Swift͔Β؆୯ʹCͷAPIୟ͚Δ import PackageDescription let package = Package( name: "Wormhole", products: [ .library( name: "Wormhole", targets: ["Wormhole"]), ], dependencies: [ .package(url: "https://github.com/giginet/libjwt-swift.git", from: "1.0.0"), ], targets: [ .target( name: "Wormhole", dependencies: ["Result", "JWT"]), ] )

Slide 11

Slide 11 text

libjwt-swift • https://github.com/giginet/libjwt-swift • JWTΛѻ͏CϥΠϒϥϦΛSwift͔Β͔ͭ͑ΔΑ͏ʹౕͨ͠

Slide 12

Slide 12 text

! import Foundation import JWT struct JWTEncoder { func encode(issuerID: UUID, keyID: String) throws -> String { let object = UnsafeMutablePointer.allocate(capacity: MemoryLayout.size) jwt_new(object) defer { jwt_free(object.pointee) } let keyPointer = convertToCString(privateKey) defer { keyPointer.deallocate() } jwt_set_alg(object.pointee, JWT_ALG_ES256, keyPointer, Int32(privateKey.utf16.count + 1)) // https://github.com/benmcollins/libjwt/pull/71 jwt_add_header(object.pointee, "kid", keyID) jwt_add_grant(object.pointee, "iss", issuerID.uuidString.lowercased()) let expirationDate = Date().addingTimeInterval(expirationInterval) jwt_add_grant_int(object.pointee, "exp", Int(expirationDate.timeIntervalSince1970)) jwt_add_grant(object.pointee, "aud", "appstoreconnect-v1") guard let encodedCString = jwt_encode_str(object.pointee) else { throw Error.decodeError } return String(cString: encodedCString) } }

Slide 13

Slide 13 text

Deprecation • Xcode beta 6ͷToolchainͩͱ໰୊ͳ͘ಈ͘ • DEVELOPMENT SNAPSHOT(9/8ݱࡏ)ͩͱwarningग़Δ

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

ࠓ·Ͱͷ࿩͸4.2͔Βdeprecatedͳ ͷͰ๨Ε͍ͯͩ͘͞

Slide 16

Slide 16 text

System Library(>=4.2) • SPM Package Description v4.2͔ΒSystem Library͕αϙʔτ • System LibraryΛύοέʔδ͔Β௚઀ࢀরͰ͖ΔΑ͏ʹ • https://github.com/apple/swift-package-manager/blob/master/ Documentation/PackageDescriptionV4_2.md

Slide 17

Slide 17 text

How to Use • .systemLibraryͷଘࡏ͸υΩϡϝϯτʹॻ͍ͯ͋Δ • ࢖͍ํͷυΩϡϝϯτ͕ͳ͍ • ॻ͖͔͚ͷυΩϡϝϯτ͕Ϛʔδ͞Εͯͳ͍ঢ়ଶͰൃݟ͞Εͨ • https://github.com/apple/swift-package-manager/blob/ 40d319d7bb1a8cb42b187a4cbfa72515c61ebc44/ Documentation/Usage.md

Slide 18

Slide 18 text

Directories Sources !"" jwt #"" jwt.h !"" module.modulemap

Slide 19

Slide 19 text

// swift-tools-version:4.2 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "Wormhole", products: [ .library( name: "Wormhole", targets: ["Wormhole"]), ], targets: [ .systemLibrary(name: "JWT", path: "./Sources/jwt", providers: [.brew(["libjwt"]), .apt(["libjwt"])]), .target( name: "Wormhole", dependencies: ["Result", "JWT"]), ] )

Slide 20

Slide 20 text

Local Package • PD v4.2͔ΒϩʔΧϧύεͰͷdependencyʹରԠ import PackageDescription let package = Package( name: "MyPackage", dependencies: [ .package(path: "../example-package-playingcard"), ], targets: [ .target( name: "MyPackage", dependencies: ["PlayingCard"] ), ] )

Slide 21

Slide 21 text

Achievement • ~ͷల։͕όά͍ͬͯͨͷͰࡢ೔௚ͨ͠ • https://github.com/apple/swift-package-manager/pull/1779 $ swift build --disable-package-manifest-caching error: /Users/giginet/work/myexecutable/~/work/MyPackage has no manifest 'myexecutable' /Users/giginet/work/myexecutable: error: product dependency 'MyPackage' not found

Slide 22

Slide 22 text

Starting SPM development

Slide 23

Slide 23 text

SPM • SwiftͰ։ൃՄೳ • llbuild͸C++ • ͪΐͬͱPython(2) • Ϗϧυͷཱྀ͕ͳ͍ • ϏϧυࡁΈToolchainΛ࢖͑͹ྑ͍ • SPMͱswift-llbuild͚ͩඞཁ

Slide 24

Slide 24 text

Bootstrap • Documentation/Development.mdͱREADME.mdΛಡΉ • ͦΕͰ΋एׯϋϚΔ

Slide 25

Slide 25 text

Select Toolchain • /Library/Developer/Toolchains/swift-latest.xctoolchain/ Info.plistΛݟΔ • CFBundleVersionͷ஋Λ؀ڥม਺Ͱ౉͢ $ export TOOLCHAINS=org.swift.4220180908a

Slide 26

Slide 26 text

Build $ ./Utilities/bootstrap --verbose

Slide 27

Slide 27 text

Use development SPM #!/usr/bin/env bash /path/to/swift-source/swiftpm/.build/debug/spm "$@"

Slide 28

Slide 28 text

Xcode $ ./Utilities/bootstrap --generate-xcodeproj generated: ./SwiftPM.xcodeproj $ open SwiftPM.xcodeproj

Slide 29

Slide 29 text

LLDB • Xcode > Debug > Attach to Process by PID or Name...

Slide 30

Slide 30 text

Next • ManifestͷύʔαʔͰόάݟ͚ͭͨͷͰۙʑ௚͢༧ఆ • ։ൃ؀ڥͰDynamic FrameworkͷLinkʹࣦഊ͢Δ • swift-llbuild΋৮ͬͯΈΔ

Slide 31

Slide 31 text

Wormhole • ϥΠϒϥϦ࡞ͬͯexecutableͰ࢖͏ࢀߟྫ • https://github.com/giginet/Wormhole • iOS Reject Conference Day1Ͱ࿩͢༧ఆ • https://iosdc-reject-conference.connpass.com/event/93314/

Slide 32

Slide 32 text

͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠