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

318643095c83b914cf80a7f99f247fe6?s=47 Wei Wang
January 10, 2016

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

For @swift, Beijing, 2016/01/10

318643095c83b914cf80a7f99f247fe6?s=128

Wei Wang

January 10, 2016
Tweet

Transcript

  1. onevcat (onev@onevcat.com)

  2. onevcat (onev@onevcat.com)

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

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

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

  6. ӞӻඳԪ

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

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

  10. ֵአ໛ຝ

  11. ᬱݘ෸դ

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

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

  14. Ջԍฎᶉாପ (STATIC LIBRARY) .a + .h ፓຽ෈կ (Object files, .o)

    ጱ ᵞݳ ᯈݳᝑଗ१෈կ (.h) ֵአ ᱾ളک๋ᕣጱݢಗᤈ෈ կӾ ࣁӞԶӤԧଙ१ጱᒫӣ ොପӾݢᚆᬮᚆᥠک
  15. ᔮᕹ໛ຝ .FRAMEWORK

  16. Ջԍฎۖா໛ຝ (DYNAMIC FRAMEWORK) ਂࣁԭᔮᕹٖ᮱ ᬩᤈ෸᭗ᬦ dyld ۖா᱾ ള ӧᵱᥝ᯿ෛے᫹ ፗک

    iOS 8҅ݝํ Apple ګ֢ ጱ໛ຝ಍ᚆֵአۖாොୗ
  17. UNIVERSAL FRAMEWORK զڹጱӞԶᒫӣො໛ຝԞ൉ ׀ .framework ෈կ ਫᨶӤฎ಑۱ጱᶉாପ1 2 2 https://github.com/jverkoey/iOS-Framework

    1 https://github.com/kstenerud/iOS-Universal-Framework
  18. LIBRARY V.S. FRAMEWORK

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

    ᴴګ)
  21. ۱޾ׁᩢᓕቘ

  22. COCOAPODS3 3 http://cocoapods.org

  23. զڹ workspace + libPod.a ୏ݎᘏ᭗ᬦ PodSpec ຽᦩᶱፓ አಁֵአ Podfile ೰ਧֵአጱ໛ຝ

    ץදᶱፓ෈կ̵Build Phase ޾ᚕ๜຅ ୌᶉாପ “׍فୗ”ጱᵞ౮ොୗ
  24. ๋ᬪ From 0.36.0 - Swift ޾ۖா໛ຝඪ೮ use_frameworks!

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

    or All
  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
  27. CARTHAGE4 4 https://github.com/Carthage/Carthage

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

  29. ֵአ CARTHAGE # Cartfile github "ReactiveCocoa/ReactiveCocoa" github "onevcat/Kingfisher" ~> 1.8

    github "https://enterprise.local/hello/repo.git" $ carthage update
  30. None
  31. None
  32. SWIFT PACKAGE MANAGER5 5 https://swift.org/package-manager/

  33. ڠୌ໛ຝ

  34. None
  35. ӞԶᦣᑶ

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

  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() { ... }
  38. API ᦡᦇ ޸ݷ҅ฎވႴศฃ౜ਠෆ

  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?
  40. API ᦡᦇ ޸ݷ҅ฎވႴศฃ౜ਠෆ ႴศกᏟጱ޸ݷ // Do this public func recursivelyFetch(urls:

    [(String, Range<Version>)]) throws -> [T] // Don't do this public func fetch(urls: [(String, Range<Version>)]) throws -> [T] // <- how?
  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`?
  42. API ᦡᦇ ޸ݷ҅ฎވႴศฃ౜ਠෆ ੤ᦶԅ֦ጱොဩٟဳ᯽෈໩ Ӟݙᦾ෫ဩᤒᬿႴ༩ᬯӻොဩٍ֛؉ԧՋԍ -> ᧗ᘍᡤ᯿຅ ቘమᇫாғդᎱӧᵱᥝ෈໩੪ᚆᤩ፡౜

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

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

  45. API ᦡᦇ սضၥᦶ҅ၥᦶḝۖ୏ݎ // In Test Target import XCTest @testable

    import YourFramework class FrameworkTypeTests: XCTestCase { // ... }
  46. ୏ݎ෸ጱᭌೠ ޸ݷ٫ᑱ // F1.framework extension UIImage { public method() {

    print("F1") } } // F2.framework extension UIImage { public method() { print("F2") } }
  47. ୏ݎ෸ጱᭌೠ ޸ݷ٫ᑱ - CASE 1 // app import F1 import

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

    // ᬌڊ F2 ҁᕮຎӧᏟਧ҂
  49. ୏ݎ෸ጱᭌೠ ੒ԭ COCOA ᔄࣳጱ extension ஠ᶳႲےڹᖗ

  50. ୏ݎ෸ጱᭌೠ ޸ݷ٫ᑱ // Don't do this // F1.framework extension UIImage

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

    public f1_method() { print("F1") } } // F2.framework extension UIImage { public f2_method() { print("F2") } }
  52. ୏ݎ෸ጱᭌೠ ᩒრ BUNDLE let bundle = NSBundle(forClass: ClassInFramework.self) let path

    = bundle.pathForResource("resource", ofType: "png") YourApp.app/Frameworks/YourFramework.framework/ resource.png
  53. ݎ૲໛ຝ

  54. GITHUB

  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
  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
  57. CARTHAGE

  58. SWIFT PM ਖ਼რ෈կනف Sources Ӿ // Package.swift import PackageDescription let

    package = Package( name: "MyKit", dependencies: [ .Package(url: "https://github.com/onevcat/anotherPacakge.git", majorVersion: 1) ] )
  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 ᒵ)
  60. ᇇ๜ّ਻ SEMANTIC VERSIONING8 x(major).y(minor).z(patch) 8 http://semver.org

  61. ᇇ๜ّ਻ > major - لو API දۖ౲ᘏڢٺ > minor -

    ෛႲےԧلو API > patch - bug ץྋᒵ > 0.x.y ݝ᭽ਝ๋ݸӞ๵
  62. ᇇ๜ّ਻ ֵአ git tag ᬰᤈᇇ๜ຽᦕ ֦ጱአಁ/۱ᓕቘᔮᕹ๗๕ݳቘጱّ ਻ᇇ๜

  63. ᇇ๜ّ਻

  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
  65. ೮ᖅᵞ౮ ᭌೠݳᭇጱ CI ሾह TRAVIS CI, CIRCLE CI, COVERALLS, CODECOV...

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

  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
  68. ᛔۖ۸ጱݎ૲ၞᑕ ݚक़ጱֺৼғ AFNETWORKING/FASTLANE

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

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

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

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

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

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

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

  79. ՗Քॠ୏ত୏ݎ໛ຝ

  80. WRITE THE CODE CHANGE THE WORLD

  81. QUESTIONS