Slide 1

Slide 1 text

Mergeable LibraryͰ ߴ଎ͳΞϓϦىಈΛ࣮ݱ͠Α͏ʂ 2024/08/23 @giginet iOSDC 2024

Slide 2

Slide 2 text

͜Μʹͪ͸ • @giginet (X/GitHub) • LINEϠϑʔגࣜձࣾ σϕϩούʔΤΫεϖϦΤϯενʔϜ • LINEΞϓϦͷ։ൃऀମݧΛ޲্ͤ͞Δ࢓ࣄΛͯ͠·͢ • ٕज़ސ໰ɿϚωʔϑΥϫʔυɺϢϏϨδ

Slide 3

Slide 3 text

ΞϓϦͷىಈΛ଎ͭͭ͘͠ ։ൃମݧ΋࠷ߴʹ͍ͨ͠ʂ

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

࿩͢͜ͱ • ϑϨʔϜϫʔΫͷϦϯΫͷ࢓૊Έͷ͓͞Β͍ • ैདྷͷख๏ͱτϨʔυΦϑ • Mergeable Libraryͷ঺հ • ࢓૊Έͱઃఆํ๏ • ઃఆ஋ʹΑΔڍಈΛݟͯΈΔ • Mergeable XCFrameworkͷ഑෍

Slide 7

Slide 7 text

࿩͢͜ͱ • ϑϨʔϜϫʔΫͷϦϯΫͷ࢓૊Έͷ͓͞Β͍ • ैདྷͷख๏ͱτϨʔυΦϑ • Mergeable Libraryͷ঺հ • ࢓૊Έͱઃఆํ๏ • ઃఆ஋ʹΑΔڍಈΛݟͯΈΔ • Mergeable XCFrameworkͷ഑෍

Slide 8

Slide 8 text

࿩͢͜ͱ • ϑϨʔϜϫʔΫͷϦϯΫͷ࢓૊Έͷ͓͞Β͍ • ैདྷͷख๏ͱτϨʔυΦϑ • Mergeable Libraryͷ঺հ • ࢓૊Έͱઃఆํ๏ • ઃఆ஋ʹΑΔڍಈΛݟͯΈΔ • Mergeable XCFrameworkͷ഑෍

Slide 9

Slide 9 text

NyanPayCore NyanPayUI NyanPayKit GiginyanPay

Slide 10

Slide 10 text

Dynamic Framework • ϏϧυࡁΈͷϑϨʔϜϫʔΫΛΞϓϦ಺ʹ࣋ͪɺىಈ࣌ʹϦϯΫ͢Δ NyanPayCore NyanPayUI NyanPayKit GiginyanPay Dynamic Framework

Slide 11

Slide 11 text

Dynamic Framework • ϏϧυࡁΈͷϑϨʔϜϫʔΫΛΞϓϦ಺ʹ࣋ͪɺىಈ࣌ʹϦϯΫ͢Δ NyanPayCore NyanPayUI NyanPayKit Dynamic Link ࣮ߦ࣌ʹϦϯΫ͢Δ GiginyanPay

Slide 12

Slide 12 text

Dynamic Frameworkͷಛ௃ Ϗϧυ࣌ؒ Ϗϧυ࣌ʹϦϯΫ͕ෆཁͳͨΊ୹Ί Ωϟογϡ ϏϧυࡁΈͷϑϨʔϜϫʔΫΛ࠶ར༻ՄೳͳͨΊΩϟογϡ͠΍͍͢ Xcode Preview ར༻Մೳ ىಈ଎౓΁ͷӨڹ ϥϯλΠϜͰϦϯΫ͢ΔͨΊىಈ࣌ؒʹӨڹ͕͋Δ ΞϓϦͷαΠζ embed͕ඞཁɺ࠷దԽ͕೉͍ͨ͠Ίେ͖͘ͳΓ͕ͪ

Slide 13

Slide 13 text

Static Framework • Ϗϧυ࣌ʹඞཁͳ࣮૷Λ୳ࡧͯ͠ղܾɺϦϯΫ͢Δ NyanPayKit GiginyanPay Static Framework NyanPayCore NyanPayUI

Slide 14

Slide 14 text

Static Framework • Ϗϧυ࣌ʹඞཁͳ࣮૷Λ୳ࡧͯ͠ղܾɺϦϯΫ͢Δ Static Link Ϗϧυ࣌ʹϦϯΫࡁΈ GiginyanPay

Slide 15

Slide 15 text

Static Frameworkͷಛ௃ Ϗϧυ࣌ؒ Ϗϧυ࣌ʹϦϯΫ͕ඞཁͳͨΊ௕͘ͳΓ͕ͪ Ωϟογϡ ϦϯΫ͠௚͢ඞཁ͕͋Γޮ͖ͮΒ͍ Xcode Preview ར༻ෆՄ ʢͨͩ͠Xcode 16͔Β͸αϙʔτʣ ىಈ଎౓΁ͷӨڹ Өڹ͕ͳ͍ ΞϓϦͷαΠζ embed͕ෆཁɺෆཁͳ࣮૷ͷ࠷దԽ͕ޮ͖΍͘͢খ͘͞͠΍͍͢

Slide 16

Slide 16 text

ࢀߟࢿྉ • Swiftʹ͓͚ΔΠϯϙʔτͱϦϯΫͷ࢓૊ΈΛ୳Δ - Speaker Deck • https://speakerdeck.com/kishikawakatsumi/ swiftniokeruinpototorinkufalseshi-zu-miwotan-ru • Link fast: Improve build and launch times - WWDC22 • https://developer.apple.com/videos/play/wwdc2022/110362

Slide 17

Slide 17 text

Dynamic Framework Static Framework Ϗϧυ࣌ؒ ୹Ί Ϗϧυ࣌ʹϦϯΫ͕ෆཁ Ωϟογϡ͠΍͍͢ ௕Ί Ϗϧυ࣌ʹϦϯΫ͕ඞཁ Ωϟογϡͮ͠Β͍ Ωϟογϡ ͠΍͍͢ ͮ͠Β͍ Xcode Preview Մೳ ෆՄ ʢXcode 16Ҏ߱͸Մೳʣ ىಈ଎౓ Өڹ͕͋Δ ʢىಈ࣌ͷϦϯΫ͕ൃੜʣ Өڹ͕ͳ͍ ΞϓϦͷαΠζ େ͖͘ͳΓ͕ͪ embed͕ඞཁ ࠷దԽͮ͠Β͍ খ͞Ί embed͕ෆཁ ࠷దԽ͠΍͍͢ ϦϦʔε࣌ʹ༗ར ։ൃ࣌ʹѻ͍΍͍͢

Slide 18

Slide 18 text

ैདྷͷख๏ɿϏϧυઃఆΛཱ྆ͤ͞Δ • ैདྷख๏ɿBuild Con fi gurationʹΑͬͯMach-O Type(ϑϨʔϜϫʔΫͷܗࣜ) Λ੾Γସ͑Δ

Slide 19

Slide 19 text

ैདྷख๏ͷ໰୊఺ • Debug, ReleaseؒͰϏϧυઃఆ͕ҟͳΔͨΊෳࡶʹͳΔ • ͳʹ͔Ϗϧυ࣌ͷ໰୊͕ى͖ͨͱ͖ͷௐ͕ࠪ೉͍͠ʢγϯϘϧॏෳͳͲʣ • ຒΊࠐΈʢembedʣͷ੍ޚ͕೉͍͠ • Static Framework͸embedͯ͠͸ͳΒͳ͍ • Ϧιʔεόϯυϧͷѻ͍ʹؾΛ͚ͭΔඞཁ͕͋Δ • `Bundle(for: )` ͷϥϯλΠϜͷڍಈ͕มΘͬͯ͠·͏

Slide 20

Slide 20 text

Resource Bundle Framework Bundle MyApp.app/Frameworks/ MyUI.framework Dynamic Framework Static Framework Main Bundle MyApp.app/Frameworks/ MyUI.framework Static Framework಺ͷ Bundle͸ࢀরͰ͖ͳ͍ let bundle = Bundle(for: MyClass.self)

Slide 21

Slide 21 text

։ൃऀମݧ Ϣʔβʔମݧ

Slide 22

Slide 22 text

Mergeable Library

Slide 23

Slide 23 text

Mergeable Library • ϝλσʔλΛ࣋ͬͨ৽͍͠Dynamic Library • Build Con fi gurationʹԠͯ͡ϦϯΫํࣜΛ੾Γସ͑ΒΕΔ • DebugϏϧυ࣌͸Dynamic Frameworkͱͯ͠ৼΔ෣͏ • ReleaseϏϧυ࣌͸Static Frameworkͱͯ͠ৼΔ෣͏ ਤͷҾ༻ɿhttps://developer.apple.com/documentation/xcode/con fi guring-your-project-to-use-mergeable-libraries

Slide 24

Slide 24 text

Linking > Mergeable Libraries > Create Merged Binary

Slide 25

Slide 25 text

NyanPayCore NyanPayUI NyanPayKit App Create Merged Binary Automatic

Slide 26

Slide 26 text

NyanPayCore NyanPayUI NyanPayKit Merged App Create Merged Binary Automatic

Slide 27

Slide 27 text

DebugϏϧυ࣌ - ΞϓϦόϯυϧ • Ϛʔδ͞ΕͨDynamic Framework͕ReexportedBinariesͱͯ͠࠶ΤΫεϙʔ τ͞ΕɺDynamic Link͞ΕΔ Dynamic Framework͕ Mergeable Framework͔Β ࠶ΤΫεϙʔτ͞Ε embed͞ΕΔ

Slide 28

Slide 28 text

ReleaseϏϧυ࣌ - ΞϓϦόϯυϧ • શͯͷFramework͕Ϛʔδ͞ΕɺStatic Frameworkͱͯ͠ৼΔ෣͏ ґଘؔ܎͸ΞϓϦຊମͷόΠφϦʹ౷߹͞ΕΔ Merged Static Binary 91KB -> 322KB

Slide 29

Slide 29 text

Ϛʔδ͞ΕͨόΠφϦΛݟͯΈΑ͏ $ nm -gU GiginyanPay.app/GiginyanPay 0000000100014070 S _$s10NyanPayKit7TopViewV7SwiftUI0E0AAMc 0000000100008f78 T _$s11NyanPayCore6WalletC6amountACSi_tcfC 0000000100014268 S _$s9NyanPayUI10QRCodeViewV05SwiftC00E0AAMc 00000001000141f0 S _$s9NyanPayUI9ImageViewV05SwiftC00E0AAMc 0000000100014150 S _NyanPayCoreVersionNumber 0000000100014120 S _NyanPayCoreVersionString 0000000100014068 S _NyanPayKitVersionNumber 0000000100014038 S _NyanPayKitVersionString 00000001000141e8 S _NyanPayUIVersionNumber 00000001000141b8 S _NyanPayUIVersionString 0000000100000000 T __mh_execute_header 00000001000054ac T _main • ΞϓϦόΠφϦʹଞͷϑϨʔϜϫʔΫͷγϯϘϧʢ࣮૷ʣ͕ຒΊࠐ·Ε͍ͯ Δ͜ͱ͕Θ͔ΔʢStatic Link)

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

Instruments

Slide 32

Slide 32 text

14.771s x104 0.1415s Mergeable Framework + Release Build Dynamic Framework

Slide 33

Slide 33 text

Resource Lookup • Dynamic / Staticͷ৔߹͍ͣΕ΋`Bundle(for:)`ʹΑΔϦιʔεόϯυϧͷऔಘ ΛϥϯλΠϜͰಡΈସ͑ͯ͘ΕΔ Framework Bundle MyApp.app/Frameworks/ MyUI.framework Dynamic Framework Static Framework Framework Bundle MyApp.app/Frameworks/ MyUI.framework

Slide 34

Slide 34 text

embed͞ΕͨStatic Framework $ nm -gU GiginyanPay.app/Frameworks/NyanPayUI.framework/NyanPayUI GiginyanPay.app/Frameworks/NyanPayUI.framework/NyanPayUI: no symbols • embed͞ΕͨStatic FrameworkͷόΠφϦʹ͸γϯϘϧؚ͕·Εͳ͍ • ϦιʔεόϯυϧͷΈembedͰ͖Δ ϦιʔεͷΈͷ ϑϨʔϜϫʔΫ

Slide 35

Slide 35 text

͢ͳΘͪ • ։ൃ࣌͸ϑϨʔϜϫʔΫ͕Dynamic Frameworkͱͯ͠ग़ྗ͞ΕɺDynamic Link͞ΕΔͷͰ։ൃऀମݧ͕޲্ • ϦϦʔε࣌͸Ϛʔδ͞ΕͨϑϨʔϜϫʔΫ͕Static Link͞ΕΔͷͰɺىಈ࣌ؒ ΍ΞϓϦͷ༰ྔ͕࡟ݮ͞ΕΔ • Ϧιʔεؚ͕·ΕΔ৔߹͸ࣗಈతʹಡΈସ͑ΒΕΔ • ͳΜ͔શ෦ྑ͍ײ͡ʹͳΔ

Slide 36

Slide 36 text

ϕϯνϚʔΫ Dynamic Framework Mergeable (Debug/Re-export) Mergeable (Release) Ϗϧυ࣌ؒ ΫϦʔϯϏϧυ 185s 151.6s 84.3s Ϗϧυ࣌ؒ ࠩ෼Ϗϧυ 7s 79.3s 10.16s ΞϓϦαΠζ 81.9MB 82MB 6.8MB

Slide 37

Slide 37 text

DebugϏϧυ͕શવૣ͘ͳͬͯͳ͍ • ϑϨʔϜϫʔΫͷ࠶ΤΫεϙʔτ͕ࢧ഑తʹ஗͍ ίϐʔ 90s~ Ϗϧυ ~5s

Slide 38

Slide 38 text

࠶ΤΫεϙʔτ • Mergeable Framework͔Βɺ௨ৗͷDynamic FrameworkΛநग़͠ɺ ReexportedBinariesͱͯ͠࠶ΤΫεϙʔτ͢Δ • େ఍͸͜ΕͰྑ͍͕ɺίϐʔίετ͕ແࢹͰ͖ͳ͘ͳΔ DebugϏϧυ ௨ৗ ґଘͷ਺͕ଟ͍৔߹͸ ࠶ΤΫεϙʔτʹ ͕͔͔࣌ؒΓϏϧυ଎౓͕ վળ͠ͳ͍

Slide 39

Slide 39 text

%ZOBNJD-JCSBSZ΁ͷϚʔδ • MAKE_MERGEABLE=YESΛࢦఆ͢Δͱɺ*.debug.dylibʹDynamic FrameworkͷόΠφϦ͕Ϛʔδ͞ΕΔ • ୅ΘΓʹReexportedBinaries͸ग़ྗ͞Εͳ͘ͳΓɺίϐʔίετ͕ͳ͘ͳΔ DebugϏϧυ MAKE_MERGEABLE =YES ґଘͷ࣮૷͸dylibʹ౷߹͞ΕΔ Merged Dynamic Binary 239KB -> 417KB $ nm -gU GiginyanPay.debug.dylib 0000000000008c88 T _$s10NyanPayKit7TopViewV4bodyQrvg 000000000001d3b0 S _$s10NyanPayKit7TopViewV4bodyQrvpMV 000000000001da4c S _$s10NyanPayKit7TopViewV4bodyQrvpQOMQ 0000000000008938 T _$s10NyanPayKit7TopViewV6wallet0aB4Core6WalletCvM 00000000000085fc T _$s10NyanPayKit7TopViewV6wallet0aB4Core6WalletCvg 0000000000020910 S _$s10NyanPayKit7TopViewV6wallet0aB4Core6WalletCvpMV 0000000000008870 T

Slide 40

Slide 40 text

ϕϯνϚʔΫ Dynamic Framework Mergeable (Debug/Merge) Mergeable (Release) Ϗϧυ࣌ؒ ΫϦʔϯϏϧυ 185s 149.3s 84.3s Ϗϧυ࣌ؒ ࠩ෼Ϗϧυ 7s 7.6s 10.16s ΞϓϦαΠζ 81.9MB 8.4MB 6.8MB

Slide 41

Slide 41 text

ߟ࡯ɿཧ૝஋͕ग़͍ͯͳ͍݅ • ΫϦʔϯϏϧυ࣌ͷDynamic Frameworkߏஙʹ͔͔ΔॳظίετΛࠩ෼Ϗϧυ ͰϖΠͰ͖͍ͯͳ͍ • Ծઆ1: μϛʔϓϩδΣΫτͷͨΊ࣮૷͕΄΅ͳ͍ • Static LinkͰ͋ͬͨͱͯ͠΋ϦϯΫ͕͔࣌ؒͳΓ୹͍ • Ծઆ2: ࠶Ϗϧυ࣌ͷมߋ͕ͳ͍ • Static FrameworkͰ͋ͬͯ΋Ωϟογϡ͕شൃͮ͠Β͘ɺDynamic FrameworkͷΩϟογϡͷར఺Λੜ͔͍ͤͯͳ͍

Slide 42

Slide 42 text

Ϛʔδ͢Δଆͷઃఆ • Ϛʔδ͢ΔଆʢΞϓϦଆʣ • Create Merged Library: Automatic/Manual • Automatic: ࢠґଘΛϚʔδՄೳʹ | Manual: ࢦఆͨ͠΋ͷͷΈ • Ϛʔδ͢Δ΋ͷΛFrameworks, Libraries, and Embedded Contentʹ௥Ճ • ໌ࣔతͳґଘ(௚઀ґଘ)ͷΈ͕Ϛʔδ͞ΕΔ • Ϧιʔε͕͋Δ΋ͷͷΈEmbed & Sign Create Merged Binary Frameworks, Libraries, and Embedded Content 1 2 1 2

Slide 43

Slide 43 text

Ϛʔδ͞ΕΔଆͷઃఆ • Ϛʔδ͞ΕΔଆʢϑϨʔϜϫʔΫଆʣ • Build Mergeable Library • ϑϨʔϜϫʔΫΛϚʔδՄೳʹ͢Δ͔ • ManualͳΒBuild Mergeable LibraryΛYES • MAKE_MERGEABLE • ϑϨʔϜϫʔΫΛϚʔδ͢Δ৔߹͸YES • ࢦఆ͠ͳ͍ͱσόοά࣌͸࠶ΤΫεϙʔτ͢Δ Build Mergeable Library MAKE_MERGEABLE 2 2 1 1

Slide 44

Slide 44 text

XCFrameworkͷMergeableԽ • ϏϧυࡁΈόΠφϦ(XCFramework)΋Mergeable Libraryͱͯ͠഑෍Ͱ͖Δ • ഑෍αΠζ͸େ͖͘ͳΔ͕ɺϥΠϒϥϦͷར༻ऀ͕Dynamic/Static྆ํΛ࢖ ͍Θ͚Δ͜ͱ͕Ͱ͖Δ • Framework͕Mergeable Library͔Ͳ͏͔͸ɺmetadataͷ༗ແͰ൑ผͰ͖Δ • LC_ATOM_INFOΛϩʔυ͢Δ͔Ͳ͏͔ $ otool -l MyFramework.xcframework/ios-arm64/MyFramework.framework/MyFramework Load command 49 cmd LC_ATOM_INFO cmdsize 16 dataoff 133328 datasize 63984

Slide 45

Slide 45 text

Swift PackageͷMergeable XCFrameworkԽ • giginet/Scipio͸͢ͰʹMergeable LibraryαϙʔτࡁΈ • ଟ͘ͷSwift Package͸͜Ε͚ͩͰMergeable XCFrameworkԽͰ͖Δ • https://giginet.github.io/Scipio/documentation/scipio/mergeable-library Swift PackageΛ࢖ͬͨ ڊେͳґଘάϥϑͷΩϟογϡઓུ iOSDC2023 $ scipio create path/to/MyPackage --framework-type mergeable --enable-library- evolution

Slide 46

Slide 46 text

·ͱΊ • Mergeable Libraryͷ࢓૊Έͱಋೖํ๏ • ࠓ͙͢Create Merged Binary > Automatic • MAKE_MERGEABLE=YESΛ๨Εͣʹ • Prebuilt Framework͸ࠓ͙͢Mergeable FrameworkͰ഑෍ʂ • Ϧιʔεؚ͕·ΕΔ৔߹ͷରॲํ๏

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

ࢀߟࢿྉ - Mergeable Library - • Meet mergeable libraries - WWDC23 - Videos - Apple Developer • https://developer.apple.com/videos/play/wwdc2023/10268/ • Con fi guring your project to use mergeable libraries | Apple Developer Documentation • https://developer.apple.com/documentation/xcode/con fi guring-your- project-to-use-mergeable-libraries • https://github.com/kateinoigakukun/MergeableLibraryInternals • Understanding mergeable libraries • https://www.polpiella.dev/understanding-mergeable-libraries

Slide 49

Slide 49 text

ࢀߟࢿྉ - Metrics- • Reducing your app’s launch time | Apple Developer Documentation • https://developer.apple.com/documentation/xcode/reducing-your-app-s- launch-time • Ultimate application performance survival guide - WWDC21 - Videos - Apple Developer • https://developer.apple.com/videos/play/wwdc2021/10181/ • What’s new in Xcode 16 - WWDC24 - Videos - Apple Developer • https://developer.apple.com/videos/play/wwdc2024/10135/

Slide 50

Slide 50 text

Mergeable Libraryઃఆ஋ xccon fi g Xcode GUI આ໌ MERGED_BINARY_TYPE NO/automatic/manual Create Merged Binary ϦϯΫઌͷλʔήοτΛϚʔδ͢Δ͔ AutomaticͩͱࣗಈతʹϚʔδՄೳʹ͢Δ Manualͩͱ໌ࣔతʹࢦఆͯ͠Δ΋ͷͷΈ MERGEABLE_LIBRARY YES/NO Build Mergeable Library ϥΠϒϥϦΛϚʔδՄೳʹ͢Δ͔ɻManual ͷࡍ͸໌ࣔతʹࢦఆ͕ඞཁ MAKE_MERGEABLE YES/NO ઃఆෆՄ σόοάϏϧυ࣌ʹϥΠϒϥϦΛϦϯΫ࣌ʹ Ϛʔδ͢Δ͔ɺ࠶ΤΫεϙʔτ͢Δ͔

Slide 51

Slide 51 text

ىಈ࣌ؒܭଌͷ4ͭͷํ๏ Instruments Performance Tests MetricKit Xcode Organizer ར༻͢Δ΋ͷ App Launch Template XCTApplicationLaunch Metric MXAppRunTimeMetric Xcode Organizer ར༻ͷ؆୯͞ ˕ ○ ˚ ˕ ࣮ߦ λΠϛϯά ։ൃதͷ೚ҙ UI Tests࣮ߦ࣌(CIͳͲ) ΞϓϦ࣮ߦ࣌ɺϦϦʔεޙ ϦϦʔεޙ ࣮૷ ෆཁ UIςετέʔεΛ࣮૷ ϝτϦΫεऔಘ࣌ͷίʔϧ όοΫΛ࣮૷ ෆཁ ༻్ ։ൃ࣌ͷσόοά σάϨʔγϣϯͷݕ஌ ΤϯυϢʔβʔͷϩάΛ ࡉ͔͘औΔ ʢϩάج൫΁ͷૹ৴ͳͲʣ ΤϯυϢʔβʔͷ ܏޲Λόʔδϣϯຖʹ ஌Δ