Bagaimana cara mengekspor Kerangka Sentuh Kakao "gemuk" (untuk Simulator dan Perangkat)?

107

Dengan Xcode 6 kita mendapatkan kemampuan untuk membuat Dynamic sendiri Cocoa Frameworks.

masukkan deskripsi gambar di sini

Karena:

  • Simulator masih menggunakan 32-bitperpustakaan

  • mulai 1 Juni 2015, pembaruan aplikasi yang dikirimkan ke App Store harus menyertakan dukungan 64-bit dan dibuat dengan iOS 8 SDK ( developer.apple.com )

Kita harus membuat perpustakaan besar untuk menjalankan proyek pada perangkat dan simulator. yaitu mendukung 32 dan 64 bit di Frameworks.

Tetapi saya tidak menemukan manual apa pun, cara mengekspor Kerangka lemak universal untuk integrasi di masa mendatang dengan proyek lain (dan membagikan pustaka ini dengan seseorang).

Inilah langkah saya untuk mereproduksi:

  1. Diatur ONLY_ACTIVE_ARCH=NOdiBuild Settings

    masukkan deskripsi gambar di sini

  2. Tambahkan dukungan armv7 armv7s arm64 i386 x86_64ke Architectures(pasti)

masukkan deskripsi gambar di sini

  1. Bangun Kerangka dan buka di Finder:

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

  1. Tambahkan kerangka kerja ini ke proyek lain

Hasil sebenarnya:

Namun pada akhirnya saya masih menemui kendala dalam menjalankan project dengan framework ini pada perangkat dan simulator sekaligus.

  • jika saya mengambil kerangka kerja dari Debug-iphoneosfolder - ini berfungsi pada perangkat dan mendapat kesalahan pada simulator:ld: symbol(s) not found for architecture i386

      xcrun lipo -info CoreActionSheetPicker

    Arsitektur dalam file lemak: CoreActionSheetPicker adalah: armv7 armv7s arm64

  • jika saya mengambil kerangka kerja dari Debug-iphonesimulatorfolder - ini berfungsi pada simulator. dan saya mengalami kesalahan pada perangkat:ld: symbol(s) not found for architecture arm64

      xcrun lipo -info CoreActionSheetPicker

    Arsitektur dalam file lemak: CoreActionSheetPicker adalah: i386 x86_64

Jadi, bagaimana cara membuat kerangka kerja dinamis yang berfungsi pada perangkat dan simulator?

Jawaban ini terkait dengan Xcode 6 iOS Membuat Kerangka Kerja Cocoa Touch - Masalah arsitektur tetapi tidak duplikat.


Memperbarui:

Saya menemukan "peretasan kotor" untuk kasus ini. Lihat jawaban saya di bawah . Jika seseorang tahu cara yang lebih nyaman - tolong beri tahu saya!

skywinder
sumber
masalah duplikat stackoverflow.com/questions/24039470/…
Andrius Steponavičius
@ AndriusSteponavičius pertanyaan ini ditanyakan 2 bulan sebelumnya.
skywinder
Ya, tetapi ada jawaban yang jauh lebih rinci di sana, yang menurut saya harus diketahui pengguna
Andrius Steponavičius
Set ONLY_ACTIVE_ARCH = NO di Build Settings merupakan langkah penting.
Jedidja
kerangka kerja Anda memerlukan irisan i386 x86_64 dalam biner lemak jika Anda ingin menjalankannya di simulator BAHKAN JIKA KOMPUTER ANDA MEMILIKI ARSITEKTUR 64 BIT !!! Mempelajari itu dengan cara yang sulit.
J.beenie

Jawaban:

82

Kenyataan dari jawaban ini adalah: Juli 2015. Kemungkinan besar segalanya akan berubah.

TLDR;

Saat ini Xcode tidak memiliki alat untuk ekspor otomatis kerangka lemak universal sehingga pengembang harus menggunakan lipoalat secara manual . Juga menurut radar ini sebelum diserahkan ke pengembang AppStore yang merupakan konsumen framework juga harus menggunakan lipountuk melepaskan potongan simulator dari suatu framework.

Jawaban yang lebih panjang mengikuti


Saya melakukan penelitian serupa dalam topik (tautan di bagian bawah jawaban).

Aku tidak menemukan dokumentasi resmi tentang distribusi sehingga penelitian saya didasarkan pada eksplorasi Apple Developer Forum, proyek Carthage dan Realm dan percobaan saya sendiri dengan xcodebuild, lipo, codesignalat-alat.

Berikut kutipan panjang (dengan sedikit markup dari saya) dari utas Forum Pengembang Apple Mengekspor aplikasi dengan kerangka kerja tersemat :

Apa cara yang tepat untuk mengekspor kerangka dari proyek kerangka?

Saat ini satu-satunya cara adalah persis seperti yang telah Anda lakukan:

  • Buat target untuk simulator dan perangkat iOS.
  • Arahkan ke folder DerivedData Xcode untuk proyek itu dan lipo dua biner bersama-sama ke dalam satu kerangka tunggal. Namun, saat Anda membangun target kerangka kerja di Xcode, pastikan untuk menyesuaikan setelan target 'Bangun Hanya Arsitektur Aktif' ke 'TIDAK'. Ini akan memungkinkan Xcode membuat target untuk beberapa jenis binarty (arm64, armv7, dll). Inilah mengapa ia bekerja dari Xcode tetapi tidak sebagai biner mandiri.

  • Anda juga ingin memastikan skema disetel ke Rilis build dan buat target framework terhadap rilis. Jika Anda masih mendapatkan kesalahan pustaka tidak dimuat, periksa potongan kode dalam kerangka kerja.

  • Gunakan lipo -info MyFramworkBinarydan periksa hasilnya.

lipo -info MyFrameworkBinary

Hasilnya adalah i386 x86_64 armv7 arm64

  • Kerangka kerja universal modern akan menyertakan 4 bagian, tetapi dapat menyertakan lebih banyak: i386 x86_64 armv7 arm64 Jika Anda tidak melihat setidaknya 4 bagian ini, kemungkinan besar karena pengaturan Bangun Arsitektur Aktif.

Ini menggambarkan proses yang kurang lebih sama seperti yang dilakukan @skywinder dalam jawabannya.

Beginilah cara Carthage menggunakan lipo dan Realm menggunakan lipo .


DETAIL PENTING

Ada radar: Xcode 6.1.1 & 6.2: kerangka kerja iOS yang berisi irisan simulator tidak dapat dikirimkan ke App Store dan diskusi panjang seputar itu di Realm # 1163 dan Carthage # 188 yang berakhir dengan solusi khusus:

sebelum dikirimkan ke AppStore kerangka kerja iOS, biner harus dilepaskan dari irisan simulator

Carthage memiliki kode khusus: CopyFrameworks dan bagian dokumentasi yang sesuai:

Skrip ini mengatasi bug pengiriman App Store yang dipicu oleh binari universal.

Realm memiliki skrip khusus: strip-frameworks.sh dan bagian dokumentasi yang sesuai:

Langkah ini diperlukan untuk mengatasi bug pengiriman App Store saat mengarsipkan binari universal.

Juga ada artikel bagus: Melucuti Arsitektur Yang Tidak Diinginkan Dari Perpustakaan Dinamis Di Xcode .

Saya sendiri menggunakan Realm strip-frameworks.shyang bekerja untuk saya dengan sempurna tanpa modifikasi apapun meskipun tentu saja siapa pun bebas untuk menulis satu dari awal.


Tautan ke topik saya yang saya sarankan untuk dibaca karena mengandung aspek lain dari pertanyaan ini: penandatanganan kode - Membuat Kerangka Kerja iOS / OSX: apakah perlu menandatanganinya sebelum didistribusikan ke pengembang lain?

Stanislav Pankevich
sumber
1
Saya menggunakan lipo tetapi ketika kerangka sedang dibangun di simulator itu menunjukkan pengenal yang belum terselesaikan dengan nama kelas tetapi di perangkat itu berfungsi. Jika menggunakan versi simulator biner maka itu berfungsi .. ada ide?
Susim Samanta
2
Saya belum menemukan bukti apa pun yang telah diubah oleh Xcode 8.2 pada Desember 2016.: /
Geoffrey Wiseman
1
@ Geoffrey, apakah ini berubah di Xcode 9.2 atau ada yang berbeda? Ini adalah pertama kalinya saya membuat kerangka biner untuk distribusi, dan saya sudah takut ...
ScottyB
Sayangnya belum melakukan ini sedikit pun - tidak bisa mengatakannya. Semoga berhasil.
Geoffrey Wiseman
57

Ini bukan solusi yang begitu jelas, tetapi hanya ada cara, yang saya temukan:

  1. Diatur ONLY_ACTIVE_ARCH=NOdiBuild Settings

    • Bangun perpustakaan untuk simulator
    • Bangun perpustakaan untuk perangkat
  2. Buka di Productsfolder konsol untuk kerangka Anda (Anda dapat membukanya dengan folder kerangka terbuka dan cd ..dari sana)

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

  1. Jalankan skrip ini dari Productsfolder. Ini menciptakan Kerangka lemak di folder ini. (atau lakukan secara manual seperti yang dijelaskan di bawah pada 3. 4. )

Atau:

  1. Gabungkan 2 Kerangka ini menggunakan lipo dengan skrip ini (ganti YourFrameworkNameke nama Kerangka Anda)

    lipo -create -output "YourFrameworkName" "Debug-iphonesimulator/YourFrameworkName.framework/YourFrameworkName" "Debug-iphoneos/YourFrameworkName.framework/YourFrameworkName"
  2. Ganti dengan biner baru salah satu kerangka kerja yang ada:

    cp -R Debug-iphoneos/YourFrameworkName.framework ./YourFrameworkName.framework
    mv YourFrameworkName ./YourFrameworkName.framework/YourFrameworkName

  1. Keuntungan: ./YourFrameworkName.framework- adalah biner lemak siap pakai! Anda dapat mengimpornya ke proyek Anda!

Untuk proyek, yang tidak ada di Workspaces:

Anda juga dapat mencoba menggunakan inti ini seperti yang dijelaskan di sini . Tapi tampaknya, itu tidak berfungsi untuk proyek di ruang kerja.

skywinder
sumber
Saya pikir Apple tidak lagi menerima biner lemak. kodmunki.wordpress.com/2015/03/04/…
Monstieur
1
@skywinder Apakah Anda menemukan cara sederhana lainnya untuk mengekspor Cocoa Touch Framework ke siap menggunakan biner lemak? Saya menggunakan pendekatan yang sama seperti di atas tetapi saya tidak menyukainya. Xcode harus memiliki beberapa proses yang mengotomatiskan.
dev gr
1
@devgr belum .. itu sebabnya saya tidak menerima jawaban saya sendiri. Masih mencari solusi yang lebih baik.
skywinder
1
Tidak dapat berjalan di simulator tetapi berfungsi di perangkat dengan langkah 3 dan 4
jose920405
1
@dapatkah ada yang menjelaskan mengapa hanya Debug-folder yang digunakan dengan lipo -create? Bisakah kerangka ini digunakan untuk Releasekonfigurasi dan mengapa? Terima kasih.
Yevhen Dubinin
10

Jawaban @Stainlav sangat membantu tetapi yang saya lakukan adalah mengkompilasi dua versi kerangka kerja (satu untuk perangkat dan satu untuk simulator) dan kemudian menambahkan yang berikut ini Run Script Phaseuntuk secara otomatis menyalin kerangka kerja yang telah dikompilasi yang diperlukan untuk arsitektur yang sedang berjalan

echo "Copying frameworks for architecture: $CURRENT_ARCH"
if [ "${CURRENT_ARCH}" = "x86_64" ] || [ "${CURRENT_ARCH}" = "i386" ]; then
  cp -af "${SRCROOT}/Frameworks/Simulator/." "${SRCROOT}/Frameworks/Active"
else
  cp -af "${SRCROOT}/Frameworks/Device/." "${SRCROOT}/Frameworks/Active"
fi

Dengan cara ini saya tidak memiliki penggunaan lipountuk membuat kerangka yang gemuk dan juga Realm strip-frameworks.shuntuk menghapus irisan yang tidak perlu saat mengirimkan ke App Store.

odm
sumber
Yang mana yang Anda tautkan?
Jaka Jančar
@ JakaJančar Saya menautkan dengan yang ada di ${SRCROOT}/Frameworks/Activefolder. Mereka diganti untuk kerangka prakompilasi yang tepat untuk arsitektur aktif pada waktu kompilasi.
odm
2
Suka! Ini jauh lebih sederhana daripada pendekatan menggabungkan-kemudian-mengoyak lipo.
clozach
2

pada dasarnya untuk ini saya menemukan solusi yang sangat bagus. Anda hanya perlu mengikuti langkah-langkah sederhana ini.

  1. Buat kerangka sentuh kakao.
  2. Atur bitcode diaktifkan ke Tidak.
  3. Pilih target Anda dan pilih edit skema. Pilih Jalankan dan pilih Lepaskan dari tab Info.
  4. Tidak ada pengaturan lain yang diperlukan.
  5. Sekarang buat kerangka kerja untuk simulator apa pun karena simulator berjalan pada arsitektur x86.
  6. Klik pada grup Produk di Project Navigator dan temukan file .framework.
  7. Klik kanan padanya dan klik Show in finder. Salin dan tempel di folder mana saja, saya pribadi lebih suka nama 'simulator'.
  8. Sekarang buat kerangka kerja untuk Perangkat iOS Generik dan ikuti langkah 6 hingga 9. Ubah saja nama folder menjadi 'perangkat' alih-alih 'simulator'.
  9. Salin file .framework perangkat dan tempel di direktori lain. Saya lebih suka direktori super langsung dari keduanya. Jadi struktur direktori sekarang menjadi:
    • Desktop
    • alat
      • MyFramework.framework
    • simulator
      • MyFramework.framework
    • MyFramework.framework Sekarang buka terminal dan cd ke Desktop. Sekarang mulailah mengetik perintah berikut:

lipo -create 'device / MyFramework.framework / MyFramework' 'simulator / MyFramework.framework / MyFramework' -output 'MyFramework.framework / MyFramework'

dan hanya itu. Di sini kami menggabungkan simulator dan versi perangkat dari biner MyFramework yang ada di dalam MyFramework.framework. Kami mendapatkan kerangka kerja universal yang dibangun untuk semua arsitektur termasuk simulator dan perangkat.

Nrip
sumber
saya ingin membuat file FAT dengan bitcode diaktifkan. Mohon bimbingannya.
pengguna3898700
2

Saya hanya ingin memperbarui jawaban hebat ini oleh @odm. Sejak Xcode 10, CURRENT_ARCHvariabel tidak lagi mencerminkan arsitektur build. Jadi saya mengubah skrip untuk memeriksa platform sebagai gantinya:

echo "Copying frameworks for platform: $PLATFORM_NAME"
rm -R "${SRCROOT}/Frameworks/Active"
if [ "${PLATFORM_NAME}" = "iphonesimulator" ]; then
    cp -af "${SRCROOT}/Frameworks/Simulator/." "${SRCROOT}/Frameworks/Active"
else
    cp -af "${SRCROOT}/Frameworks/Device/." "${SRCROOT}/Frameworks/Active"
fi

Saya juga menambahkan baris untuk menghapus direktori target sebelum menyalin, karena saya perhatikan bahwa file tambahan di subdirektori tidak akan ditimpa sebaliknya.

Dorian Roy
sumber
1

Jawaban Saya mencakup poin-poin di bawah ini:

  • Buat kerangka kerja yang berfungsi untuk simulator dan Perangkat

  • Bagaimana cara mengekspor Kerangka Sentuh Kakao "gemuk" (untuk Simulator dan Perangkat keduanya)?

  • Simbol tak terdefinisi untuk arsitektur x86_64

  • ld: simbol tidak ditemukan untuk arsitektur x86_64

Langkah 1: Pertama, bangun kerangka kerja Anda dengan target Simulator

Langkah 2: Setelah proses pembuatan simulator berhasil, sekarang buat kerangka kerja Anda dengan pemilihan target perangkat atau pemilihan Perangkat iOS Umum

Langkah 3: Sekarang pilih target kerangka kerja Anda dan untuk itu Di bawah "Build Phases" pilih "Add Run Script" dan salin kode skrip di bawah ini)

Langkah4: Sekarang akhirnya, buat lagi dan kerangka Anda siap untuk simulator dan kompatibilitas perangkat. Hore!!!!

[Catatan: Kita harus menyiapkan kedua kerangka kerja yang kompatibel sebelum langkah terakhir4 (simulator dan arsitektur perangkat kompatibel, jika tidak, ikuti langkah 1 dan 2 di atas dengan benar)

Lihat gambar referensi:

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

Masukkan kode di bawah ini ke dalam area shell:

#!/bin/sh


UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal


# make sure the output directory exists

mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"


# Step 1. Build Device and Simulator versions

xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos  BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build

xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build


# Step 2. Copy the framework structure (from iphoneos build) to the universal folder

cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"


# Step 3. Copy Swift modules from iphonesimulator build (if it exists) to the copied framework directory

SIMULATOR_SWIFT_MODULES_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/."

if [ -d "${SIMULATOR_SWIFT_MODULES_DIR}" ]; then

cp -R "${SIMULATOR_SWIFT_MODULES_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"

fi


# Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory

lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"


# Step 5. Convenience step to copy the framework to the project's directory

cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"


# Step 6. Convenience step to open the project's directory in Finder

open "${BUILD_DIR}/${CONFIGURATION}-universal"

Sandip Patel - SM
sumber
Skrip ini sepertinya memanggil dirinya sendiri dan dengan demikian menyebabkan loop tak terbatas !! Harus me-restart komputer saya setelah menjalankannya! Terus-menerus menelurkan proses xcodebuild baru ... dan membuka jendela pencari baru - Tidak akan memilih
J.beenie
Lihat jawaban @ l0gg3r di SO Q / A ini untuk skrip serupa tanpa masalah rekursi.
J.beenie