Xcode 11 dan XCFrameworks: format kemasan kerangka kerja baru


Dalam kehidupan banyak perusahaan yang memiliki dan mengembangkan sendiri tumpukan perpustakaan dan komponen, ada saatnya ketika volume tumpukan ini menjadi sulit untuk dipelihara.


Dalam hal pengembangan untuk platform iOS, dan secara umum, ekosistem Apple, ada dua opsi untuk menghubungkan perpustakaan sebagai dependensi:


  1. Kumpulkan mereka setiap kali Anda membangun aplikasi.
  2. Kumpulkan mereka terlebih dahulu menggunakan dependensi yang sudah dikumpulkan.

Ketika memilih pendekatan kedua, masuk akal untuk menggunakan sistem CI / CD untuk merakit perpustakaan menjadi artefak yang siap digunakan.


Namun, kebutuhan untuk membangun perpustakaan untuk beberapa platform atau arsitektur prosesor di ekosistem Apple, seringkali tidak selalu memerlukan operasi sepele, baik ketika membangun perpustakaan dan produk akhir yang menggunakannya.


Terhadap latar belakang ini, sulit untuk tidak memperhatikan dan sangat menarik untuk dipelajari, salah satu inovasi dari Apple, dipresentasikan di WWDC 2019 sebagai bagian dari presentasi Binary Frameworks in Swift - format kemasan kerangka adalah XCFramework.


XCFramework memiliki beberapa keunggulan dibandingkan pendekatan yang ditetapkan:


  1. Kemasan ketergantungan untuk semua platform dan arsitektur target dalam satu bundel di luar kotak.
  2. Bundel koneksi dalam format XCFramework, sebagai ketergantungan tunggal untuk semua platform dan arsitektur target.
  3. Tidak perlu membangun kerangka kerja yang gemuk / universal.
  4. Tidak perlu lagi menyingkirkan x86_64 slice sebelum memuat aplikasi final ke AppStore.

Pada artikel ini, kami akan menjelaskan mengapa format baru ini diperkenalkan, apa itu, dan juga apa yang diberikan pengembang.


Bagaimana format baru muncul


Apple sebelumnya merilis manajer dependensi Swift Package Manager .
Intinya adalah bahwa Swift PM memungkinkan Anda untuk mengirim pustaka dalam bentuk kode sumber terbuka dengan deskripsi dependensi.


Dari sudut pandang pengembang yang memasok perpustakaan, saya ingin menyoroti dua aspek Swift PM.


  • Minus yang jelas adalah bahwa karena satu dan lain alasan, tidak semua vendor perpustakaan ingin membuka kode sumber mereka kepada konsumen.
  • Suatu nilai tambah yang jelas - ketika mengkompilasi dependensi dari sumber, kami menghilangkan kebutuhan untuk mengamati kompatibilitas biner dari perpustakaan.

XCFramework Apple menawarkan sebagai format biner baru untuk perpustakaan pengemasan, menganggapnya sebagai alternatif untuk Paket Swift.


Format ini, serta kemampuan untuk menghubungkan pustaka yang dirakit dalam XCFramework, tersedia mulai dengan Xcode 11 dan versi beta-nya.


Apa itu XCFramework


Pada intinya, XCFramework adalah cara baru untuk mengemas dan mengirim perpustakaan, dalam berbagai versi mereka.


Antara lain, format baru juga memungkinkan pengemasan perpustakaan statis beserta file headernya, termasuk yang ditulis dalam C / Objective-C.


Pertimbangkan formatnya lebih detail.


  1. Kemasan ketergantungan untuk semua platform dan arsitektur target dalam satu bundel di luar kotak


    Semua rakitan perpustakaan untuk setiap platform dan arsitektur target sekarang dapat dikemas dalam satu bundel dengan ekstensi .xcframework.
    Namun, untuk ini, pada saat ini, Anda harus menggunakan skrip untuk menjalankan xcodebuild dengan sakelar -create-xcframework untuk Xcode 11.


    Proses perakitan dan pengemasan akan dipertimbangkan lebih lanjut.


  2. Bundel koneksi dalam format XCFramework, sebagai ketergantungan tunggal untuk semua platform dan arsitektur target


    Karena bundel .xcframework berisi semua opsi perakitan ketergantungan yang diperlukan, kita tidak perlu khawatir tentang arsitektur dan platform targetnya.


    Di Xcode 11, pustaka yang dikemas dalam .xcframework terhubung seperti .framework biasa.
    Lebih khusus, ini dapat dicapai dengan cara-cara berikut dalam pengaturan target:


    • menambahkan .xcframework ke bagian "Frameworks and Libraries" pada tab "General"
    • menambahkan .xcframework ke "Tautan Biner Dengan Perpustakaan" pada tab "Bangun Fase"

  3. Tidak perlu membangun kerangka gemuk / universal


    Sebelumnya, untuk mendukung beberapa perpustakaan dan beberapa arsitektur di perpustakaan plug-in, perlu untuk menyiapkan apa yang disebut kerangka kerja lemak atau universal.
    Ini dilakukan menggunakan lipo untuk menjahit semua opsi kerangka kerja yang dirangkai menjadi satu biner tebal.


    Rincian lebih lanjut tentang ini dapat ditemukan, misalnya, dalam artikel berikut:



  4. Tidak perlu lagi menyingkirkan x86_64 slice sebelum memuat aplikasi akhir di AppStore


    Biasanya, irisan seperti itu digunakan untuk menyediakan perpustakaan di simulator iOS.
    Saat Anda mencoba mengunduh aplikasi dengan dependensi yang mengandung x86_64 slice di AppStore, Anda mungkin menemukan kesalahan yang terkenal ITMS-90087 .



Membuat dan mengemas XCFramework: teori


Dalam presentasi yang disebutkan sebelumnya, beberapa langkah diperlukan yang diperlukan untuk mengumpulkan dan mengemas perpustakaan dalam format XCFramework:


  1. Persiapan proyek


    Untuk memulainya, di semua area target proyek yang bertanggung jawab untuk membangun perpustakaan untuk platform target, Anda harus mengaktifkan pengaturan Build Libraries for Distribution untuk Xcode 11.



  2. Perakitan proyek untuk platform dan arsitektur target


    Selanjutnya, kita harus mengumpulkan semua target untuk platform dan arsitektur target.
    Mari kita perhatikan contoh-contoh perintah pemanggilan menggunakan contoh konfigurasi proyek tertentu.


    Katakanlah dalam proyek kami memiliki dua skema "XCFrameworkExample-iOS" dan "XCFramework-macOS".



    Juga dalam proyek ini ada dua target yang mengumpulkan perpustakaan untuk iOS dan macOS.



    Untuk membangun semua konfigurasi pustaka yang diperlukan, kita perlu mengumpulkan kedua target menggunakan skema yang sesuai.
    Namun, untuk iOS, kami membutuhkan dua perangkat: satu untuk perangkat akhir (ARM), dan yang lainnya untuk simulator (x86_64).


    Secara total, kita perlu mengumpulkan 3 kerangka kerja.


    Untuk melakukan ini, Anda dapat menggunakan perintah xcodebuild :


     # iOS devices xcodebuild archive \ -scheme XCFrameworkExample-iOS \ -archivePath "./build/ios.xcarchive" \ -sdk iphoneos \ SKIP_INSTALL=NO # iOS simulator xcodebuild archive \ -scheme XCFrameworkExample-iOS \ -archivePath "./build/ios_sim.xcarchive" \ -sdk iphonesimulator \ SKIP_INSTALL=NO # macOS xcodebuild archive \ -scheme XCFrameworkExample-macOS \ -archivePath "./build/macos.xcarchive" \ SKIP_INSTALL=NO 

    Hasilnya, kami mendapat 3 kerangka kerja yang dirakit, yang akan kami bungkus lebih lanjut dalam wadah .xcframework.


  3. Kemasan dirakit. Kerangka dalam. Xcframework


    Anda dapat melakukan ini dengan perintah berikut:


     xcodebuild -create-xcframework \ -framework "./build/ios.xcarchive/Products/Library/Frameworks/XCFrameworkExample.framework" \ -framework "./build/ios_sim.xcarchive/Products/Library/Frameworks/XCFrameworkExample.framework" \ -framework "./build/macos.xcarchive/Products/Library/Frameworks/XCFrameworkExample.framework" \ -output "./build/XCFrameworkExample.xcframework" 

    Mungkin ada banyak -framework parameter -framework yang menunjuk ke semua .framework assemblies yang ingin Anda lampirkan ke .xcframework.



Mempersiapkan proyek perpustakaan untuk perakitan dan pengemasan XCFramework di masa mendatang


TL; DR: proyek yang sudah selesai dapat diunduh dari repositori di Github .


Sebagai contoh, kami menerapkan perpustakaan yang akan tersedia untuk dua platform: iOS dan macOS.
Kami akan menggunakan konfigurasi proyek yang disebutkan di bagian artikel sebelumnya: dua skema dan dua target Kerangka yang sesuai untuk platform iOS dan macOS.


Apakah perpustakaan itu sendiri memberi kami ekstensi sederhana untuk String? ( Optional where Wrapped == String ), dengan satu properti.


Kami menyebut properti ini isNilOrEmpty dan, seperti namanya, akankah ia memberi tahu kami saat berada di dalam String? nilai yang hilang atau string yang disimpan di dalamnya kosong.


Kode tersebut dapat diimplementasikan sebagai berikut:


 public extension Optional where Wrapped == String { var isNilOrEmpty: Bool { if case let .some(string) = self { return string.isEmpty } return true } } 

Kami melanjutkan langsung ke pembuatan dan konfigurasi proyek.


  1. Untuk memulainya, kita perlu membuat proyek jenis "Kerangka" untuk salah satu dari dua platform target pilihan Anda: iOS atau macOS.


    Anda dapat melakukan ini dalam Xcode melalui item menu “File” => “New” => “Project”, atau dengan menggunakan pintasan keyboard ⇧ + + N (secara default).


    Selanjutnya, di bagian atas dialog, pilih platform yang diinginkan (iOS atau macOS), pilih jenis proyek Framework, dan lanjutkan ke tombol "Next".


    Pada layar berikutnya, kita perlu mengatur nama proyek di bidang "Nama Produk".


    Atau, Anda dapat menggunakan "basis" nama proyek, dalam konfigurasi yang disebutkan sebelumnya adalah "XCFrameworkExample".


    Di masa mendatang, saat mengonfigurasi proyek, kami akan menambahkan akhiran yang menunjukkan platform ke nama dasar yang digunakan atas nama target.


  2. Setelah itu, Anda perlu membuat Target lain dari jenis "Kerangka Kerja" di proyek untuk platform lain yang terdaftar (kecuali untuk yang awalnya dibuat proyek).


    Untuk melakukan ini, gunakan item menu "File" => "New" => "Target".


    Selanjutnya, kami memilih di dialog yang lain (relatif terhadap yang dipilih dalam paragraf 1) dari dua platform, setelah itu kami kembali memilih jenis proyek "Kerangka Kerja".


    Untuk bidang "Nama Produk", kami dapat langsung menggunakan nama dengan akhiran platform, yang kami tambahkan target dalam paragraf ini. Jadi, jika platformnya adalah macOS, maka namanya bisa menjadi "XCFrameworkExample-macOS" (% base_name% -% platform%).


  3. Kami akan menetapkan target dan bagan untuk membuatnya lebih mudah dibedakan.


    Pertama, ganti nama skema kami dan target yang terpasang pada mereka sehingga nama mereka mencerminkan platform, misalnya seperti ini:


    • "XCFrameworkExample-iOS"
    • "XCFrameworkExample-macOS"

  4. Selanjutnya, tambahkan file dengan kode ekstensi kami untuk String? ke proyek .swift String?


    Tambahkan file .swift baru ke proyek dengan nama "Optional.swift".
    Dan dalam file itu sendiri kami menempatkan ekstensi yang disebutkan sebelumnya untuk Optional .


    Penting untuk tidak lupa menambahkan file kode ke kedua target.




Sekarang kita memiliki proyek yang bisa kita satukan di XCFramework menggunakan perintah dari tahap sebelumnya.


Proses perakitan dan pengemasan perpustakaan dalam format .xcframework


Pada tahap ini, Anda dapat menggunakan skrip bash dalam file terpisah untuk membangun pustaka dan mengemasnya dalam format .xcframework. Selain itu, ini akan memungkinkan di masa depan untuk menggunakan perkembangan ini untuk mengintegrasikan solusi ke dalam sistem CI / CD.


Scriptnya terlihat sangat sederhana dan, pada kenyataannya, menyatukan perintah yang disebutkan sebelumnya untuk perakitan:


 #!/bin/sh # ---------------------------------- # BUILD PLATFORM SPECIFIC FRAMEWORKS # ---------------------------------- # iOS devices xcodebuild archive \ -scheme XCFrameworkExample-iOS \ -archivePath "./build/ios.xcarchive" \ -sdk iphoneos \ SKIP_INSTALL=NO # iOS simulator xcodebuild archive \ -scheme XCFrameworkExample-iOS \ -archivePath "./build/ios_sim.xcarchive" \ -sdk iphonesimulator \ SKIP_INSTALL=NO # macOS xcodebuild archive \ -scheme XCFrameworkExample-macOS \ -archivePath "./build/macos.xcarchive" \ SKIP_INSTALL=NO # ------------------- # PACKAGE XCFRAMEWORK # ------------------- xcodebuild -create-xcframework \ -framework "./build/ios.xcarchive/Products/Library/Frameworks/XCFrameworkExample.framework" \ -framework "./build/ios_sim.xcarchive/Products/Library/Frameworks/XCFrameworkExample.framework" \ -framework "./build/macos.xcarchive/Products/Library/Frameworks/XCFrameworkExample.framework" \ -output "./build/XCFrameworkExample.xcframework" 

Konten .Xcframework


Sebagai hasil dari skrip perakitan dari paragraf artikel sebelumnya, kita mendapatkan bundel yang didambakan .xcframework, yang dapat ditambahkan ke proyek.


Jika kita melihat ke dalam bundel ini, yang, seperti .framework, pada dasarnya adalah folder sederhana, kita akan melihat struktur berikut:



Di sini kita melihat bahwa di dalam .xcframework adalah rakitan dalam format .framework, dipecah oleh platform dan arsitektur. Juga untuk menggambarkan isi bundel .xcframework, di dalamnya terdapat file Info.plist.


File Info.plist memiliki konten berikut
 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>AvailableLibraries</key> <array> <dict> <key>LibraryIdentifier</key> <string>ios-arm64</string> <key>LibraryPath</key> <string>XCFrameworkExample.framework</string> <key>SupportedArchitectures</key> <array> <string>arm64</string> </array> <key>SupportedPlatform</key> <string>ios</string> </dict> <dict> <key>LibraryIdentifier</key> <string>ios-x86_64-simulator</string> <key>LibraryPath</key> <string>XCFrameworkExample.framework</string> <key>SupportedArchitectures</key> <array> <string>x86_64</string> </array> <key>SupportedPlatform</key> <string>ios</string> <key>SupportedPlatformVariant</key> <string>simulator</string> </dict> <dict> <key>LibraryIdentifier</key> <string>macos-x86_64</string> <key>LibraryPath</key> <string>XCFrameworkExample.framework</string> <key>SupportedArchitectures</key> <array> <string>x86_64</string> </array> <key>SupportedPlatform</key> <string>macos</string> </dict> </array> <key>CFBundlePackageType</key> <string>XFWK</string> <key>XCFrameworkFormatVersion</key> <string>1.0</string> </dict> </plist> 

Anda mungkin memperhatikan bahwa untuk kunci "CFBundlePackageType", berbeda dengan format .framework, nilai baru "XFWK" digunakan, bukan "FMWK".


Ringkasan


Jadi, format kemasan perpustakaan di XCFramework tidak lebih dari wadah biasa untuk perpustakaan yang dikompilasi dalam format .framework.


Namun, format ini memungkinkan Anda untuk menyimpan dan menggunakan secara terpisah masing-masing arsitektur dan platform yang disajikan di dalamnya. Ini menghilangkan sejumlah masalah yang melekat dalam pendekatan luas untuk membangun kerangka kerja lemak / universal.


Meskipun demikian, saat ini, ada nuansa penting mengenai masalah penggunaan XCFramework dalam proyek nyata - manajemen ketergantungan, yang belum diterapkan oleh Apple dalam format XCFramework.


Untuk tujuan ini, Swift PM, Carthage, CocoaPods dan sistem manajemen ketergantungan lainnya dan rakitan mereka biasanya digunakan. Oleh karena itu, tidak mengherankan bahwa dukungan untuk format baru sudah berlangsung tepatnya dalam proyek CocoaPods dan Carthage .

Source: https://habr.com/ru/post/id475816/


All Articles