Làm cách nào để xuất Khung cảm ứng ca cao “béo” (cho Trình mô phỏng và Thiết bị)?


107

Với Xcode 6, chúng tôi có khả năng tạo Động riêng Cocoa Frameworks.

nhập mô tả hình ảnh ở đây

Bởi vì:

  • Trình mô phỏng vẫn sử dụng 32-bitthư viện

  • bắt đầu từ ngày 1 tháng 6 năm 2015, các bản cập nhật ứng dụng được gửi đến App Store phải bao gồm hỗ trợ 64-bit và được xây dựng với iOS 8 SDK ( developer.apple.com )

Chúng ta phải tạo thư viện béo để chạy dự án trên các thiết bị và trình mô phỏng. tức là hỗ trợ cả 32 và 64 bit trong Frameworks.

Nhưng tôi không tìm thấy bất kỳ tài liệu hướng dẫn nào, cách xuất ra Universal fat Framework để tích hợp trong tương lai với các dự án khác (và chia sẻ thư viện này với ai đó).

Đây là các bước của tôi để tái tạo:

  1. Đặt ONLY_ACTIVE_ARCH=NOtrongBuild Settings

    nhập mô tả hình ảnh ở đây

  2. Thêm hỗ trợ armv7 armv7s arm64 i386 x86_64cho Architectures(chắc chắn)

nhập mô tả hình ảnh ở đây

  1. Xây dựng Framework và mở nó trong Finder:

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

  1. Thêm khuôn khổ này vào một dự án khác

Kết quả thực tế:

Nhưng cuối cùng, tôi vẫn gặp sự cố khi chạy dự án với khuôn khổ này trên các thiết bị và trình mô phỏng cùng một lúc.

  • nếu tôi lấy khuôn khổ từ Debug-iphoneosthư mục - nó hoạt động trên các thiết bị và gặp lỗi trên trình mô phỏng:ld: symbol(s) not found for architecture i386

      xcrun lipo -info CoreActionSheetPicker

    Các kiến ​​trúc trong tệp béo: CoreActionSheetPicker là: armv7 armv7s arm64

  • nếu tôi lấy khuôn khổ từ Debug-iphonesimulatorthư mục - nó hoạt động trên trình mô phỏng. và tôi gặp lỗi trên thiết bị:ld: symbol(s) not found for architecture arm64

      xcrun lipo -info CoreActionSheetPicker

    Kiến trúc trong tệp béo: CoreActionSheetPicker là: i386 x86_64

Vậy, làm thế nào để tạo một khung động hoạt động trên các thiết bị và trình mô phỏng?

Câu trả lời này liên quan đến Xcode 6 iOS Tạo khung cảm ứng ca cao - Các vấn đề về kiến ​​trúc nhưng nó không trùng lặp.


Cập nhật:

Tôi đã tìm thấy một "hack bẩn" cho trường hợp này. Xem câu trả lời của tôi dưới đây . Nếu ai đó biết cách thuận tiện hơn - vui lòng cho tôi biết!



@ AndriusSteponavičius câu hỏi này đã được hỏi 2 tháng trước đó.
skywinder

Vâng, nhưng có nhiều hơn nữa những câu trả lời chi tiết ở đó, mà tôi nghĩ rằng người dùng nên biết về
Andrius Steponavičius

Đặt ONLY_ACTIVE_ARCH = NO trong Cài đặt Xây dựng là một bước quan trọng.
Jedidja

khuôn khổ của bạn cần cả hai lát i386 x86_64 trong nhị phân béo nếu bạn muốn chạy nó trên trình mô phỏng NGAY LÚC NẾU MÁY TÍNH CỦA BẠN CÓ KIẾN TRÚC 64 BIT !!! Học được rằng một cách khó khăn.
J.beenie

Câu trả lời:


82

Thực tế của câu trả lời này là: Tháng 7 năm 2015. Rất có thể mọi thứ sẽ thay đổi.

TLDR;

Hiện tại Xcode không có công cụ để xuất tự động khuôn khổ chất béo phổ quát nên nhà phát triển phải sử dụng lipocông cụ thủ công. Cũng theo radar này trước khi trình lên nhà phát triển AppStore, người tiêu dùng framework cũng phải sử dụng lipođể loại bỏ các lát mô phỏng khỏi framework.

Câu trả lời dài hơn sau


Tôi đã thực hiện nghiên cứu tương tự trong chủ đề (liên kết ở cuối câu trả lời).

Tôi đã không tìm thấy bất kỳ tài liệu chính thức về phân phối của rất nghiên cứu của tôi được dựa trên thăm dò của Diễn đàn của Apple phát triển, các dự án Carthage và Realm và thí nghiệm của riêng tôi với xcodebuild, lipo, codesigncông cụ này.

Đây là trích dẫn dài (với một chút đánh dấu của tôi) từ chuỗi Diễn đàn nhà phát triển Apple Xuất ứng dụng với khung nhúng :

Cách thích hợp để xuất một khuôn khổ từ một dự án khuôn khổ là gì?

Hiện tại, cách duy nhất là chính xác những gì bạn đã làm:

  • Xây dựng mục tiêu cho cả trình mô phỏng và thiết bị iOS.
  • Điều hướng đến thư mục DerivedData của Xcode cho dự án đó và ghép hai tệp nhị phân lại với nhau thành một khuôn khổ duy nhất. Tuy nhiên, khi bạn xây dựng mục tiêu khung trong Xcode, hãy đảm bảo điều chỉnh cài đặt mục tiêu 'Chỉ xây dựng kiến ​​trúc hoạt động' thành 'KHÔNG'. Điều này sẽ cho phép Xcode xây dựng mục tiêu cho nhiều loại hai chính phủ (arm64, armv7, v.v.). Đây sẽ là lý do tại sao nó hoạt động từ Xcode nhưng không phải là một tệp nhị phân độc lập.

  • Ngoài ra, bạn sẽ muốn đảm bảo rằng lược đồ được đặt thành Bản phát hành và xây dựng mục tiêu khung chống lại bản phát hành. Nếu bạn vẫn gặp lỗi không tải được thư viện, hãy kiểm tra các lát mã trong khuôn khổ.

  • Sử dụng lipo -info MyFramworkBinaryvà kiểm tra kết quả.

lipo -info MyFrameworkBinary

Kết quả là i386 x86_64 armv7 arm64

  • Các khung công tác phổ thông hiện đại sẽ bao gồm 4 phần, nhưng có thể bao gồm nhiều hơn: i386 x86_64 armv7 arm64 Nếu bạn không thấy ít nhất 4 phần này thì đó là do cài đặt Kiến trúc Hoạt động Xây dựng.

Điều này mô tả quá trình khá giống với @skywinder đã thực hiện nó trong câu trả lời của mình.

Đây là cách Carthage sử dụng lipoRealm sử dụng lipo .


CHI TIẾT QUAN TRỌNG

Có radar: Xcode 6.1.1 & 6.2: Không thể gửi các khuôn khổ iOS chứa các lát trình mô phỏng lên App Store và một cuộc thảo luận dài về nó trên Realm # 1163Carthage # 188 đã kết thúc bằng cách giải quyết đặc biệt:

trước khi gửi đến AppStore iOS, các tệp nhị phân khuôn khổ phải được gỡ bỏ khỏi các lát trình mô phỏng

Carthage có mã đặc biệt: CopyFrameworks và phần tài liệu tương ứng:

Tập lệnh này hoạt động xung quanh lỗi gửi App Store được kích hoạt bởi các mã nhị phân chung.

Realm có tập lệnh đặc biệt: strip-frameworks.sh và phần tài liệu tương ứng:

Bước này là bắt buộc để khắc phục lỗi gửi trên App Store khi lưu trữ các tệp nhị phân chung.

Ngoài ra còn có bài viết hay: Tước các kiến ​​trúc không mong muốn khỏi các thư viện động trong Xcode .

Bản thân tôi đã sử dụng Realm's strip-frameworks.shhoạt động hoàn hảo cho tôi mà không có bất kỳ sửa đổi nào mặc dù tất nhiên bất kỳ ai cũng có thể tự do viết một cái từ đầu.


Liên kết đến chủ đề của tôi mà tôi khuyên bạn nên đọc vì nó chứa một khía cạnh khác của câu hỏi này: ký mã - Tạo Khung công tác iOS / OSX: có cần thiết phải ký mã chúng trước khi phân phối cho các nhà phát triển khác không?


1
Tôi đã sử dụng lipo nhưng khi khung công tác đang xây dựng trong trình mô phỏng, nó hiển thị số nhận dạng chưa được giải quyết với tên lớp nhưng trong thiết bị nó hoạt động. Nếu sử dụng phiên bản giả lập của nhị phân thì nó đang hoạt động .. có ý kiến ​​gì không?
Susim Samanta

2
Tôi không tìm thấy bất kỳ bằng chứng nào mà điều này đã thay đổi bởi Xcode 8.2 vào tháng 12 năm 2016.: /
Geoffrey Wiseman

1
@Geoffrey, điều này có thay đổi trong Xcode 9.2 hay có gì khác không? Đây là lần đầu tiên tôi tạo một khuôn khổ nhị phân để phân phối và tôi đã rất sợ ...
ScottyB

Tôi đã không làm điều này trong một chút, thật đáng buồn - không thể nói. Chúc may mắn.
Geoffrey Wiseman

57

Đây không phải là giải pháp quá rõ ràng, nhưng tôi thấy có cách duy nhất:

  1. Đặt ONLY_ACTIVE_ARCH=NOtrongBuild Settings

    • Xây dựng thư viện cho trình mô phỏng
    • Xây dựng thư viện cho thiết bị
  2. Mở trong Productsthư mục bảng điều khiển cho khung của bạn (bạn có thể mở bằng thư mục khung mở và cd ..từ đó)

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

  1. Chạy tập lệnh này từ Productsthư mục. Nó tạo Khung chất béo trong thư mục này. (hoặc làm theo cách thủ công như được giải thích bên dưới trong 3. 4. )

Hoặc là:

  1. Kết hợp 2 Framework này bằng lipo bằng script này (thay thế YourFrameworkNamethành tên Framework của bạn)

    lipo -create -output "YourFrameworkName" "Debug-iphonesimulator/YourFrameworkName.framework/YourFrameworkName" "Debug-iphoneos/YourFrameworkName.framework/YourFrameworkName"
  2. Thay thế bằng nhị phân mới một trong các khuôn khổ hiện có:

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

  1. Lợi nhuận: ./YourFrameworkName.framework- là bản nhị phân chất béo đã sẵn sàng sử dụng! Bạn có thể nhập nó vào dự án của mình!

Đối với dự án, không có trong Không gian làm việc:

Bạn cũng có thể thử sử dụng ý chính này như được mô tả ở đây . Nhưng có vẻ như, nó không hoạt động cho các dự án trong không gian làm việc.


Tôi đã nghĩ Apple không chấp nhận các mã nhị phân béo nữa. kodmunki.wordpress.com/2015/03/04/…
Monstieur

1
@skywinder Bạn có tìm thấy bất kỳ cách đơn giản nào khác để xuất Cocoa Touch Framework sang sẵn sàng sử dụng nhị phân béo không? Tôi đang sử dụng cách tiếp cận tương tự như trên nhưng tôi không thích nó. Xcode nên có một số tự động hóa quy trình.
dev gr

1
@devgr chưa .. đó là lý do tại sao tôi không chấp nhận câu trả lời của chính mình. Vẫn đang tìm kiếm một giải pháp tốt hơn.
skywinder

1
Không thể chạy trong trình giả lập nhưng làm việc trong thiết bị với 3 và 4 bước
jose920405

1
@có ai có thể giải thích tại sao chỉ Debug-sử dụng thư mục với lipo -create? Khung này có thể được sử dụng để Releasecấu hình không và tại sao? Cảm ơn.
Yevhen Dubinin

10

Câu trả lời @Stainlav rất hữu ích nhưng thay vào đó, những gì tôi làm là biên dịch hai phiên bản của khung (một cho thiết bị và một cho trình mô phỏng) và sau đó thêm phần sau Run Script Phaseđể tự động sao chép khung được biên dịch trước cần thiết cho kiến ​​trúc đang chạy

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

Bằng cách này, tôi không sử dụng lipođể tạo một khuôn khổ béo cũng như Realm's strip-frameworks.shđể loại bỏ các phần không cần thiết khi gửi lên App Store.


Bạn liên kết với cái nào?
Jaka Jančar

@ JakaJančar Tôi liên kết với những cái trong ${SRCROOT}/Frameworks/Activethư mục. Chúng được thay thế cho các khuôn khổ được biên dịch trước phù hợp cho kiến ​​trúc hoạt động vào thời gian biên dịch.
odm

2
Yêu nó! Điều này đơn giản hơn nhiều so với cách lipotiếp cận kết hợp rồi chia nhỏ .
clozach

2

về cơ bản cho điều này tôi tìm thấy giải pháp rất tốt. bạn chỉ cần làm theo các bước đơn giản.

  1. Tạo khuôn khổ cảm ứng ca cao.
  2. Đặt bitcode được bật thành Không.
  3. Chọn mục tiêu của bạn và chọn các lược đồ chỉnh sửa. Chọn Run và chọn Release from Info tab.
  4. Không cần cài đặt khác.
  5. Bây giờ xây dựng khung cho bất kỳ trình mô phỏng nào vì trình mô phỏng chạy trên kiến ​​trúc x86.
  6. Nhấp vào nhóm Sản phẩm trong Bộ điều hướng dự án và tìm tệp .framework.
  7. Nhấp chuột phải vào nó và nhấp vào Hiển thị trong công cụ tìm. Sao chép và dán nó vào bất kỳ thư mục nào, cá nhân tôi thích tên 'simulator' hơn.
  8. Bây giờ hãy xây dựng khuôn khổ cho Thiết bị iOS Chung và làm theo các bước từ 6 đến 9. Chỉ cần đổi tên thư mục thành 'thiết bị' thay vì 'trình mô phỏng'.
  9. Sao chép tệp .framework của thiết bị và dán vào bất kỳ thư mục nào khác. Tôi thích thư mục siêu cấp ngay lập tức của cả hai. Vì vậy, cấu trúc thư mục bây giờ trở thành:
    • Máy tính để bàn
    • thiết bị
      • MyFramework.framework
    • giả lập
      • MyFramework.framework
    • MyFramework.framework Bây giờ hãy mở terminal và cd vào Desktop. Bây giờ hãy bắt đầu gõ lệnh sau:

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

và đó là nó. Ở đây chúng tôi kết hợp trình mô phỏng và phiên bản thiết bị của tệp nhị phân MyFramework hiện diện bên trong MyFramework.framework. Chúng tôi nhận được một khuôn khổ chung xây dựng cho tất cả các kiến ​​trúc bao gồm trình mô phỏng và thiết bị.


tôi muốn tạo tệp FAT với mã bit được bật. Xin vui lòng hướng dẫn cho tôi.
user3898700

2

Tôi chỉ muốn cập nhật câu trả lời tuyệt vời này của @odm. Kể từ Xcode 10, CURRENT_ARCHbiến không phản ánh kiến ​​trúc xây dựng nữa. Vì vậy, tôi đã thay đổi tập lệnh để kiểm tra nền tảng thay thế:

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

Tôi cũng đã thêm một dòng để xóa thư mục đích trước khi sao chép, vì tôi nhận thấy rằng các tệp bổ sung trong thư mục con sẽ không bị ghi đè nếu không.


1

Câu trả lời của tôi bao gồm các điểm dưới đây:

  • Tạo khuôn khổ hoạt động cho cả trình mô phỏng và Thiết bị

  • Làm cách nào để xuất Khung cảm ứng ca cao “béo” (cho cả Trình mô phỏng và Thiết bị)?

  • Các ký hiệu không xác định cho kiến ​​trúc x86_64

  • ld: (các) biểu tượng không tìm thấy cho kiến ​​trúc x86_64

Bước 1: Đầu tiên xây dựng các khuôn khổ của bạn với mục tiêu Trình mô phỏng

Bước 2: Sau thành công của quá trình xây dựng trình mô phỏng, bây giờ hãy xây dựng cho khuôn khổ của bạn với lựa chọn mục tiêu thiết bị hoặc lựa chọn Thiết bị iOS chung

Bước 3: Bây giờ chọn mục tiêu khung của bạn và cho mục tiêu đó Trong "Giai đoạn xây dựng", hãy chọn "Thêm Tập lệnh chạy" và sao chép mã tập lệnh bên dưới)

Bước 4: Bây giờ cuối cùng, hãy xây dựng lại và khuôn khổ của bạn đã sẵn sàng cho cả trình mô phỏng và khả năng tương thích với thiết bị. Tiếng hoan hô!!!!

[Lưu ý: Chúng tôi phải chuẩn bị sẵn cả hai khung tương thích trước bước 4 cuối cùng (trình mô phỏng và kiến ​​trúc thiết bị tương thích, nếu không, vui lòng thực hiện đúng các bước 1 và 2 ở trên)

Xem hình ảnh tham khảo:

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

Đặt mã bên dưới vào vùng 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"


Tập lệnh này dường như gọi chính nó và do đó gây ra một vòng lặp vô hạn !! Phải khởi động lại máy tính của tôi sau khi chạy nó! Liên tục tạo ra các quy trình xcodebuild mới ... và mở các cửa sổ công cụ tìm mới - Sẽ bỏ phiếu
J.beenie

Kiểm tra câu trả lời của @ l0gg3r trong SO Q / A này để biết tập lệnh tương tự không có vấn đề đệ quy.
J.beenie
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.