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

如何打造一个让人愉快的框架

Wei Wang
January 10, 2016

 如何打造一个让人愉快的框架

For @swift, Beijing, 2016/01/10

Wei Wang

January 10, 2016
Tweet

More Decks by Wei Wang

Other Decks in Technology

Transcript

  1. onevcat ([email protected])

    View Slide

  2. onevcat ([email protected])

    View Slide

  3. ই֜಑᭜ӞӻᦏՈషளጱ
    ੜ਎

    View Slide

  4. ֕ᘍᡤکᬯฎӞེ୏ݎ
    ᘏտᦓ...

    View Slide

  5. ই֜಑᭜ӞӻᦏՈషளጱ
    ໛ຝ

    View Slide

  6. ӞӻඳԪ

    View Slide

  7. ྎኦށጱ“᫪ৼ”
    > ᗑᕶ᧗࿢
    > ཛྷࣳᥴຉ
    > ੕ᛯපຎ
    > ᥤࢶۖኮ
    ...

    View Slide

  8. View Slide

  9. զӤඳԪᕍંᡦ຅
    ইํᵮݶਫંૣݳ

    View Slide

  10. ֵአ໛ຝ

    View Slide

  11. ᬱݘ෸դ

    View Slide

  12. COCOA TOUCH LIBRARY
    ஫ӧԧ ᮎԶଙ
    ᤩಋۖ୚አ޾ .a ෈կ
    ಅඪᯈጱ௣థ

    View Slide

  13. Ջԍฎᶉாପ
    (STATIC LIBRARY)

    View Slide

  14. Ջԍฎᶉாପ
    (STATIC LIBRARY)
    .a + .h
    ፓຽ෈կ (Object files, .o) ጱ
    ᵞݳ
    ᯈݳᝑଗ१෈կ (.h) ֵአ
    ᱾ളک๋ᕣጱݢಗᤈ෈
    կӾ
    ࣁӞԶӤԧଙ१ጱᒫӣ
    ොପӾݢᚆᬮᚆᥠک

    View Slide

  15. ᔮᕹ໛ຝ
    .FRAMEWORK

    View Slide

  16. Ջԍฎۖா໛ຝ
    (DYNAMIC FRAMEWORK)
    ਂࣁԭᔮᕹٖ᮱
    ᬩᤈ෸᭗ᬦ dyld ۖா᱾

    ӧᵱᥝ᯿ෛے᫹
    ፗک iOS 8҅ݝํ Apple ګ֢
    ጱ໛ຝ಍ᚆֵአۖாොୗ

    View Slide

  17. UNIVERSAL FRAMEWORK
    զڹጱӞԶᒫӣො໛ຝԞ൉
    ׀ .framework ෈կ
    ਫᨶӤฎ಑۱ጱᶉாପ1 2
    2 https://github.com/jverkoey/iOS-Framework
    1 https://github.com/kstenerud/iOS-Universal-Framework

    View Slide

  18. LIBRARY V.S. FRAMEWORK

    View Slide

  19. View Slide

  20. COCOA TOUCH
    FRAMEWORK
    iOS 8 ୏তᚆڠୌۖா໛ຝ
    Swift ໛ຝጱࠔӞᭌೠ
    (ࢩԅ Runtime ᴴګ)

    View Slide

  21. ۱޾ׁᩢᓕቘ

    View Slide

  22. COCOAPODS3
    3 http://cocoapods.org

    View Slide

  23. զڹ
    workspace + libPod.a
    ୏ݎᘏ᭗ᬦ PodSpec ຽᦩᶱፓ
    አಁֵአ Podfile ೰ਧֵአጱ໛ຝ
    ץදᶱፓ෈կ̵Build Phase ޾ᚕ๜຅
    ୌᶉாପ
    “׍فୗ”ጱᵞ౮ොୗ

    View Slide

  24. ๋ᬪ
    From 0.36.0 - Swift ޾ۖா໛ຝඪ೮
    use_frameworks!

    View Slide

  25. ๋ᬪ
    From 0.36.0 - Swift ޾ۖா໛ຝඪ೮
    use_frameworks!
    ᬯӻᭌᶱտਖ਼ᶱፓׁᩢق᮱දԅ
    framework
    None or All

    View Slide

  26. ֵአ COCOAPODS
    # Podfile
    platform :ios, '8.0'
    use_frameworks!
    target 'MyApp' do
    pod 'AFNetworking', '~> 2.6'
    pod 'ORStackView', '~> 3.0'
    pod 'SwiftyJSON', '~> 2.3'
    end
    $ pod install

    View Slide

  27. CARTHAGE4
    4 https://github.com/Carthage/Carthage

    View Slide

  28. Րඪ೮ Framework
    ᶋ׍ف҅ӧදݒᶱፓ෈կ
    ݄Ӿஞ۸҅ፗള՗ git ՙପ឴ݐ

    View Slide

  29. ֵአ CARTHAGE
    # Cartfile
    github "ReactiveCocoa/ReactiveCocoa"
    github "onevcat/Kingfisher" ~> 1.8
    github "https://enterprise.local/hello/repo.git"
    $ carthage update

    View Slide

  30. View Slide

  31. View Slide

  32. SWIFT
    PACKAGE
    MANAGER5
    5 https://swift.org/package-manager/

    View Slide

  33. ڠୌ໛ຝ

    View Slide

  34. View Slide

  35. ӞԶᦣᑶ

    View Slide

  36. API ᦡᦇ
    ᘍᡤ൉׀ᕳ୏ݎᘏጱٖ਻

    View Slide

  37. API ᦡᦇ
    ᘍᡤ൉׀ᕳ୏ݎᘏጱٖ਻
    ੱݢᚆੜጱᦢᳯ๦ᴴ
    // Do this
    public func mustMethod() { ... }
    func onlyUsedInFramework() { ... }
    private func onlyUsedInFile() { ... }
    // Don't do this
    public func mustMethod() { ... }
    public func onlyUsedInFramework() { ... }
    public func onlyUsedInFile() { ... }

    View Slide

  38. API ᦡᦇ
    ޸ݷ҅ฎވႴศฃ౜ਠෆ

    View Slide

  39. API ᦡᦇ
    ޸ݷ҅ฎވႴศฃ౜ਠෆ
    ႴศกᏟጱ޸ݷ
    // Do this
    public mutating func removeAt(position: Index) -> Element
    // Don't do this
    public mutating func remove(i: Int) -> Element
    // <- index or element?

    View Slide

  40. API ᦡᦇ
    ޸ݷ҅ฎވႴศฃ౜ਠෆ
    ႴศกᏟጱ޸ݷ
    // Do this
    public func recursivelyFetch(urls: [(String, Range)]) throws -> [T]
    // Don't do this
    public func fetch(urls: [(String, Range)]) throws -> [T] // <- how?

    View Slide

  41. API ᦡᦇ
    ޸ݷ҅ฎވႴศฃ౜ਠෆ
    ႴศกᏟጱ޸ݷ
    public var displayName: String
    public var screenName: String // <- Better
    // Don't do this
    public func displayName() -> String
    // <- noun or verb? Why returning `String`?

    View Slide

  42. API ᦡᦇ
    ޸ݷ҅ฎވႴศฃ౜ਠෆ
    ੤ᦶԅ֦ጱොဩٟဳ᯽෈໩
    Ӟݙᦾ෫ဩᤒᬿႴ༩ᬯӻොဩٍ֛؉ԧՋԍ -> ᧗ᘍᡤ᯿຅
    ቘమᇫாғդᎱӧᵱᥝ෈໩੪ᚆᤩ፡౜

    View Slide

  43. API ᦡᦇ
    ޸ݷ҅ฎވႴศฃ౜ਠෆ
    SWIFT API DESIGN GUIDELINES
    HTTPS://SWIFT.ORG/DOCUMENTATION/API-DESIGN-GUIDELINES.HTML

    View Slide

  44. API ᦡᦇ
    սضၥᦶ҅ၥᦶḝۖ୏ݎ

    View Slide

  45. API ᦡᦇ
    սضၥᦶ҅ၥᦶḝۖ୏ݎ
    // In Test Target
    import XCTest
    @testable import YourFramework
    class FrameworkTypeTests: XCTestCase {
    // ...
    }

    View Slide

  46. ୏ݎ෸ጱᭌೠ
    ޸ݷ٫ᑱ
    // F1.framework
    extension UIImage {
    public method() { print("F1") }
    }
    // F2.framework
    extension UIImage {
    public method() { print("F2") }
    }

    View Slide

  47. ୏ݎ෸ጱᭌೠ
    ޸ݷ٫ᑱ - CASE 1
    // app
    import F1
    import F2
    UIImage().method()
    // Ambiguous use of 'method()'

    View Slide

  48. ୏ݎ෸ጱᭌೠ
    ޸ݷ٫ᑱ - CASE 2
    // app
    import F1
    UIImage().method()
    // ᬌڊ F2 ҁᕮຎӧᏟਧ҂

    View Slide

  49. ୏ݎ෸ጱᭌೠ
    ੒ԭ COCOA ᔄࣳጱ extension
    ஠ᶳႲےڹᖗ

    View Slide

  50. ୏ݎ෸ጱᭌೠ
    ޸ݷ٫ᑱ
    // Don't do this
    // F1.framework
    extension UIImage {
    public method() { print("F1") }
    }
    // F2.framework
    extension UIImage {
    public method() { print("F2") }
    }

    View Slide

  51. ୏ݎ෸ጱᭌೠ
    ޸ݷ٫ᑱ
    // Do this
    // F1.framework
    extension UIImage {
    public f1_method() { print("F1") }
    }
    // F2.framework
    extension UIImage {
    public f2_method() { print("F2") }
    }

    View Slide

  52. ୏ݎ෸ጱᭌೠ
    ᩒრ BUNDLE
    let bundle =
    NSBundle(forClass: ClassInFramework.self)
    let path =
    bundle.pathForResource("resource", ofType: "png")
    YourApp.app/Frameworks/YourFramework.framework/
    resource.png

    View Slide

  53. ݎ૲໛ຝ

    View Slide

  54. GITHUB

    View Slide

  55. COCOAPODS
    pod spec create MyFramework
    Pod::Spec.new do |s|
    s.name = "MyFramework"
    s.version = "1.0.2"
    s.summary = "My first framework"
    s.description = <<-DESC
    It's my first framework.
    DESC
    s.ios.deployment_target = "8.0"
    s.source = { :git => "https://github.com/onevcat/myframework.git",
    :tag => s.version }
    s.source_files = "Class/*.{h,swift}"
    s.public_header_files = ["MyFramework/MyFramework.h"]
    end

    View Slide

  56. COCOAPODS
    ൉Իک CocoaPods
    # ಑ tag
    git tag 1.0.2 && git push origin --tags
    # podspec ෈ဩ༄ັ
    pod spec lint MyFramework.podspec
    # ൉Իک CocoaPods Ӿஞՙପ
    pod trunk push MyFramework.podspec

    View Slide

  57. CARTHAGE

    View Slide

  58. SWIFT PM
    ਖ਼რ෈կනف Sources Ӿ
    // Package.swift
    import PackageDescription
    let package = Package(
    name: "MyKit",
    dependencies: [
    .Package(url: "https://github.com/onevcat/anotherPacakge.git",
    majorVersion: 1)
    ]
    )

    View Slide

  59. ᇇ๜ᓕቘ
    # Podfile
    pod 'AFNetworking', '~> 2.6.1'
    # 2.6.x ّ਻ (2.6.1, 2.6.2, 2.6.9 ᒵ҅ӧ۱ތ 2.7)
    # Podfile
    pod 'AFNetworking', '~> 2.6'
    # 2.x ّ਻ (2.6.1, 2.7, 2.8 ᒵ҅ӧ۱ތ 3.0)
    # Cartfile
    github "Mantle/Mantle" >= 1.1
    # य़ԭᒵԭ 1.1 (1.1҅1.1.4, 1.3, 2.1 ᒵ)

    View Slide

  60. ᇇ๜ّ਻
    SEMANTIC VERSIONING8
    x(major).y(minor).z(patch)
    8 http://semver.org

    View Slide

  61. ᇇ๜ّ਻
    > major - لو API දۖ౲ᘏڢٺ
    > minor - ෛႲےԧلو API
    > patch - bug ץྋᒵ
    > 0.x.y ݝ᭽ਝ๋ݸӞ๵

    View Slide

  62. ᇇ๜ّ਻
    ֵአ git tag ᬰᤈᇇ๜ຽᦕ
    ֦ጱአಁ/۱ᓕቘᔮᕹ๗๕ݳቘጱّ
    ਻ᇇ๜

    View Slide

  63. ᇇ๜ّ਻

    View Slide

  64. ᇇ๜ّ਻
    // MyFramework.h
    //! Project version string for MyFramework.
    FOUNDATION_EXPORT const unsigned char MyFrameworkVersionString[]; // 1.8.3
    //! Project version number for MyFramework.
    FOUNDATION_EXPORT double MyFrameworkVersionNumber; // 347
    // Exported module map
    //! Project version number for MyFramework.
    public var MyFrameworkVersionNumber: Double
    // ଚဌํ੕ڊ MyFrameworkVersionString

    View Slide

  65. ೮ᖅᵞ౮
    ᭌೠݳᭇጱ CI ሾह
    TRAVIS CI, CIRCLE CI, COVERALLS, CODECOV...

    View Slide

  66. ᛔۖ۸ጱݎ૲ၞᑕ
    FASTLANE9
    9 https://fastlane.tools

    View Slide

  67. ᛔۖ۸ጱݎ૲ၞᑕ
    # Fastfile
    desc "Release new version"
    lane :release do |options|
    target_version = options[:version]
    raise "The version is missed." if target_version.nil?
    ensure_git_branch # Ꮯᦊ master ړඪ
    ensure_git_status_clean # Ꮯᦊဌํ๚൉Իጱ෈կ
    scan # ᬩᤈၥᦶ
    sync_build_number_to_git # ਖ਼ build ݩᦡԅ git commit හ
    increment_version_number(version_number: target_version) # ᦡᗝᇇ๜ݩ
    version_bump_podspec(path: "Kingfisher.podspec",
    version_number: target_version) # ๅෛ podspec
    git_commit_all(message: "Bump version to #{target_version}") # ൉Իᇇ๜ݩץද
    add_git_tag tag: target_version # ᦡᗝ tag
    push_to_git_remote # വᭆک git ՙପ
    pod_push # ൉Իک CocoaPods
    end
    $ fastlane release version:1.8.4

    View Slide

  68. ᛔۖ۸ጱݎ૲ၞᑕ
    ݚक़ጱֺৼғ
    AFNETWORKING/FASTLANE

    View Slide

  69. ڠୌӞӻսᐹጱ໛ຝ
    ෈໩҅ဳ᯽҅ၥᦶ҅դᎱᨶᰁ҅
    ๅෛ෭ப҅issue ߥଫ᭛ଶ...

    View Slide

  70. View Slide

  71. ڠୌӞӻսᐹጱ໛ຝ
    ෈໩҅ဳ᯽҅ၥᦶ҅դᎱᨶᰁ҅
    ๅෛ෭ப҅issue ߥଫ᭛ଶ...
    COCOAPODS QUALITY
    HTTPS://COCOAPODS.ORG/PODS/KINGFISHER/QUALITY
    QUALITY INDEXES GUIDE

    View Slide

  72. ݢᚆጱᳯ᷌
    ّ਻௔כᦤ (database҅Key-archiving)

    View Slide

  73. ݢᚆጱᳯ᷌
    ᯿॔۱ތ
    ਖ਼ EMBEDDED_CONTENT_CONTAINS_SWIFT
    ᦡᗝԅ NO
    ӧᥝਖ਼ׁᩢጱ framework copy ک
    Framework Ӿ

    View Slide

  74. ݢᚆጱᳯ᷌
    ෫ဩّ਻ጱ໛ຝׁᩢ10
    10 Dependency Hells

    View Slide

  75. View Slide

  76. View Slide

  77. ݢᚆጱᳯ᷌
    Framework ے᫹᭛ଶ 11 12
    12 rdar://22948371
    11 App launch time increased

    View Slide

  78. ݢᚆጱᳯ᷌
    Swift ᇇ๜ๅෛ

    View Slide

  79. ՗Քॠ୏ত୏ݎ໛ຝ

    View Slide

  80. WRITE THE CODE
    CHANGE THE WORLD

    View Slide

  81. QUESTIONS

    View Slide