Làm cách nào để bạn thiết kế các gói khuôn khổ mã cho Mac App Store?


81

Sau khi gửi gần đây, tôi đã gặp lỗi sau:

Chữ ký không hợp lệ - gói ứng dụng lồng nhau (FooBar.app/Contents/Frameworks/GData.framework) không được ký, chữ ký không hợp lệ hoặc không được ký bằng chứng chỉ gửi của Apple. Tham khảo Hướng dẫn ký mã và hộp cát ứng dụng để biết thêm thông tin.

Chữ ký không hợp lệ - gói ứng dụng lồng nhau (FooBar.app/Contents/Frameworks/Growl.framework) không được ký, chữ ký không hợp lệ hoặc không được ký bằng chứng chỉ gửi của Apple. Tham khảo Hướng dẫn ký mã và hộp cát ứng dụng để biết thêm thông tin.

Chữ ký không hợp lệ - gói ứng dụng lồng nhau libcurl (FooBar.app/Contents/Frameworks/libcurl.framework) không được ký, chữ ký không hợp lệ hoặc không được ký bằng chứng chỉ gửi của Apple. Tham khảo Hướng dẫn ký mã và hộp cát ứng dụng để biết thêm thông tin.

Vì vậy, tôi đã ký tất cả các gói khuôn khổ cho mỗi Technote 2206 :

codesign -f -v -s "3rd Party Mac Developer Application: Name" ./libcurl.framework/Versions/A/libcurl
codesign -f -v -s "3rd Party Mac Developer Application: Name" ./libcurl.framework/Versions/A/libssh2.1.dylib
codesign -f -v -s "3rd Party Mac Developer Application: Name" ./Growl.framework/Versions/A/Growl
codesign -f -v -s "3rd Party Mac Developer Application: Name" ./GData.framework/Versions/A/GData

Technote 2206 nói:

Khung ký tên

Xem như các khuôn khổ là các gói, có vẻ hợp lý khi kết luận rằng bạn có thể ký một khuôn khổ trực tiếp. Tuy nhiên, đây không phải là trường hợp. Để tránh các vấn đề khi ký khung, hãy đảm bảo rằng bạn ký một phiên bản cụ thể thay vì toàn bộ khung:

# Đây là cách sai:

ký hiệu -s my-ký-nhận dạng ../FooBarBaz.framework

# Đây là cách đúng:

ký mã -s my-ký-nhận dạng ../FooBarBaz.framework/Versions/A

Và khi tôi cố gắng xác minh kết quả, nó có vẻ tốt với tôi:

% codesign -vvv FooBar.app/Contents/Frameworks/libcurl.framework
FooBar.app/Contents/Frameworks/libcurl.framework: valid on disk
FooBar.app/Contents/Frameworks/libcurl.framework: satisfies its Designated Requirement
% codesign -vvv FooBar.app/Contents/Frameworks/Growl.framework
FooBar.app/Contents/Frameworks/Growl.framework: valid on disk
FooBar.app/Contents/Frameworks/Growl.framework: satisfies its Designated Requirement

Để giải trí, tôi đã thử ký trực tiếp vào gói khuôn khổ và nó vẫn bị từ chối. Nhưng đó chính xác là những gì tài liệu nói rằng không nên làm.

Bất kỳ phỏng đoán tại sao điều đó sẽ được coi là không hợp lệ? Tôi đang sử dụng cùng một chứng chỉ mà tôi sử dụng để ký mã ứng dụng của mình - một chứng chỉ đã hoạt động trong quá khứ.

Dự đoán duy nhất của tôi sẽ là điều gì đó liên quan đến các danh sách hiện có (tôi có cần sở hữu số nhận dạng trong Info.plists của khuôn khổ không?) Hoặc các quyền - bất kỳ đề xuất nào?


Tôi cũng đã phát hiện ra điều này sớm hơn khi tôi gửi ứng dụng của mình. Rất may, Apple đã không từ chối nó nhưng lưu ý rằng chúng tôi sẽ phải ký các khuôn khổ sau. Tôi nghĩ tốt hơn nên đăng trên trang các vấn đề về mã Growl của google và rất nhanh mọi người sẽ gặp phải vấn đề tương tự.
koo

2
Cũng gặp phải sự cố này khi gửi ứng dụng với khung Growl. Tôi đoán rằng bạn sẽ phải thay đổi số nhận dạng gói growl.framework thành số nhận dạng mà bạn sở hữu và sau đó ký mã cho nó.
Andrew

Điều này thật kỳ lạ: Tôi đã xuất bản một ứng dụng, bao gồm hai khuôn khổ (CorePlot và MacRuby), cả hai đều không có dấu. Tôi chỉ chạy lệnh ký mã trên gói ứng dụng một lần và ứng dụng đã được chấp nhận mà không có bất kỳ nhận xét nào về khuôn khổ. Bây giờ nếu bạn nhìn vào gói ứng dụng ( bit.ly/charterapp ), cả hai khuôn khổ dường như đã được ký. Bạn đã cố gắng chỉ cần ký toàn bộ ứng dụng?
p4010

@ p4010, tôi đã làm - trước đây họ không có dấu. Ví dụ như Growl chỉ là gói thẳng mà họ phân phối. Bây giờ, tôi đã có ứng dụng này trong cửa hàng một thời gian, vì vậy tôi cho rằng điều này liên quan đến nội dung hộp cát mới. Bạn gửi ứng dụng của mình khi nào?
csexton

@Andrew, việc thay đổi số nhận dạng gói có hiệu quả với bạn không?
csexton

Câu trả lời:


45

Dựa trên câu trả lời của baptr, tôi đã phát triển tập lệnh shell này để gán mã cho tất cả các khung công tác của tôi và các tài nguyên nhị phân / tệp thực thi phụ trợ khác (các loại hiện được hỗ trợ: dylib, gói và mục đăng nhập):

#!/bin/sh

# WARNING: You may have to run Clean in Xcode after changing CODE_SIGN_IDENTITY! 

# Verify that $CODE_SIGN_IDENTITY is set
if [ -z "${CODE_SIGN_IDENTITY}" ] ; then
    echo "CODE_SIGN_IDENTITY needs to be set for framework code-signing!"

    if [ "${CONFIGURATION}" = "Release" ] ; then
        exit 1
    else
        # Code-signing is optional for non-release builds.
        exit 0
    fi
fi

if [ -z "${CODE_SIGN_ENTITLEMENTS}" ] ; then
    echo "CODE_SIGN_ENTITLEMENTS needs to be set for framework code-signing!"

    if [ "${CONFIGURATION}" = "Release" ] ; then
        exit 1
    else
        # Code-signing is optional for non-release builds.
        exit 0
    fi
fi

ITEMS=""

FRAMEWORKS_DIR="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
if [ -d "$FRAMEWORKS_DIR" ] ; then
    FRAMEWORKS=$(find "${FRAMEWORKS_DIR}" -depth -type d -name "*.framework" -or -name "*.dylib" -or -name "*.bundle" | sed -e "s/\(.*framework\)/\1\/Versions\/A\//")
    RESULT=$?
    if [[ $RESULT != 0 ]] ; then
        exit 1
    fi

    ITEMS="${FRAMEWORKS}"
fi

LOGINITEMS_DIR="${TARGET_BUILD_DIR}/${CONTENTS_FOLDER_PATH}/Library/LoginItems/"
if [ -d "$LOGINITEMS_DIR" ] ; then
    LOGINITEMS=$(find "${LOGINITEMS_DIR}" -depth -type d -name "*.app")
    RESULT=$?
    if [[ $RESULT != 0 ]] ; then
        exit 1
    fi

    ITEMS="${ITEMS}"$'\n'"${LOGINITEMS}"
fi

# Prefer the expanded name, if available.
CODE_SIGN_IDENTITY_FOR_ITEMS="${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
if [ "${CODE_SIGN_IDENTITY_FOR_ITEMS}" = "" ] ; then
    # Fall back to old behavior.
    CODE_SIGN_IDENTITY_FOR_ITEMS="${CODE_SIGN_IDENTITY}"
fi

echo "Identity:"
echo "${CODE_SIGN_IDENTITY_FOR_ITEMS}"

echo "Entitlements:"
echo "${CODE_SIGN_ENTITLEMENTS}"

echo "Found:"
echo "${ITEMS}"

# Change the Internal Field Separator (IFS) so that spaces in paths will not cause problems below.
SAVED_IFS=$IFS
IFS=$(echo -en "\n\b")

# Loop through all items.
for ITEM in $ITEMS;
do
    echo "Signing '${ITEM}'"
    codesign --force --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" --entitlements "${CODE_SIGN_ENTITLEMENTS}" "${ITEM}"
    RESULT=$?
    if [[ $RESULT != 0 ]] ; then
        echo "Failed to sign '${ITEM}'."
        IFS=$SAVED_IFS
        exit 1
    fi
done

# Restore $IFS.
IFS=$SAVED_IFS
  1. Lưu nó vào một tệp trong dự án của bạn. Tôi giữ bản sao của mình trong một Scriptsthư mục con trong thư mục gốc của dự án của tôi.
    • Của tôi được gọi codesign-frameworks.sh.
  2. Thêm giai đoạn xây dựng "Chạy tập lệnh" ngay sau giai đoạn xây dựng "Sao chép khung nhúng" của bạn.
    • Bạn có thể gọi nó là “Khung nhúng Codesign”.
  3. Dán ./codesign-frameworks.sh(hoặc bất cứ thứ gì bạn gọi là tập lệnh của mình ở trên) vào trường văn bản của trình chỉnh sửa tập lệnh. Sử dụng ./Scripts/codesign-frameworks.shnếu bạn lưu trữ tập lệnh trong một thư mục con.
  4. Xây dựng ứng dụng của bạn. Tất cả các khuôn khổ đi kèm sẽ được ký mã.

Nếu bạn vẫn gặp lỗi “ Identity : mập mờ (so khớp:…”, vui lòng bình luận bên dưới. Điều này sẽ không xảy ra nữa.

Cập nhật ngày 14 tháng 11 năm 2012: Thêm hỗ trợ cho các khung có các ký tự đặc biệt trong tên của chúng (điều này không bao gồm các dấu ngoặc kép) vào “Codeign-frameworks.sh”.

Cập nhật 2013-01-30: Thêm hỗ trợ cho các ký tự đặc biệt trong tất cả các đường dẫn (điều này phải bao gồm các dấu ngoặc kép) cho “Codeign-frameworks.sh”.

Cập nhật ngày 10 tháng 10 năm 2013: Thêm hỗ trợ dylib thử nghiệm.

Cập nhật ngày 28 tháng 11 năm 2013: Thêm hỗ trợ quyền lợi. Cải thiện hỗ trợ dylib thử nghiệm.

Cập nhật 2014-06-13: Khắc phục sự cố sắp xếp mã với các khung chứa các khung (lồng nhau). Điều này được thực hiện bằng cách thêm -depthtùy chọn vào find, điều này khiến findbạn thực hiện chuyển tải theo chiều sâu. Điều này đã trở nên cần thiết, vì vấn đề được mô tả ở đây . Tóm lại: một gói có chứa chỉ có thể được ký nếu các gói lồng nhau của nó đã được ký.

Cập nhật 2014-06-28: Thêm hỗ trợ gói thử nghiệm.

Cập nhật ngày 28 tháng 8 năm 2014: Cải thiện mã và ngăn chặn việc không khôi phục được IFS.

Cập nhật 2014-09-26: Thêm hỗ trợ cho các mục đăng nhập.

Cập nhật 2014-10-26: Kiểm tra thư mục trích dẫn. Điều này sửa lỗi "dòng 31/42: quá nhiều đối số" và kết quả là lỗi "đối tượng mã hoàn toàn không được ký" cho các đường dẫn bao gồm các ký tự đặc biệt.

Cập nhật ngày 11 tháng 11 năm 2014: Giải quyết lỗi nhận dạng không rõ ràng (như “Nhà phát triển Mac: không rõ ràng…”) khi sử dụng giải pháp nhận dạng tự động trong Xcode. Bạn không cần phải đặt danh tính một cách rõ ràng nữa và chỉ có thể sử dụng “Mac Developer”!

Cập nhật 2015-08-07: Cải thiện ngữ nghĩa.

Cải tiến được chào đón!


Cảm ơn vì điều này, chỉ cần một lưu ý, nó không hoạt động nếu mục tiêu của bạn có khoảng trắng trong tên của nó. Tôi đã cố gắng sửa chữa nhưng không thể làm cho nó hoạt động nên đã thay đổi mục tiêu.
Craig,

Sẽ hoạt động ngay bây giờ khi FRAMEWORK_DIR có dấu cách / ký tự đặc biệt trong tên của nó.
Ngày 2

Tuy nhiên, tôi cũng cần phải tắt tùy chọn dấu thời gian bằng cách thêm "--timestamp" vào cuối lệnh ký mã.
Elmer Cat

Hấp dẫn. Bạn có phải là @Elmer Cat, tình cờ, làm điều này trên phiên bản OS X chưa phát hành không? Trang người đàn ông mô tả tùy chọn này có "hành vi mặc định dành riêng cho hệ thống".
JanX2

1
Elmer Cat - Tôi không biết bạn đang chạy phiên bản Xcode nào, nhưng tôi đang sử dụng phiên bản 5.0.1 và nó chắc chắn KHÔNG tự động ký các khuôn khổ của tôi. Tôi đã vò đầu bứt tóc cho đến khi tôi tìm thấy kịch bản này.
Bryan

11

Nhận xét của bạn cho thấy bạn đã ký các đối tượng trong thư mục phiên bản của gói. Technote hiển thị để ký vào chính thư mục.

Những điều sau phù hợp với Technote hơn:

codesign -f -v -s "3rd Party Mac Developer Application: Name" ./libcurl.framework/Versions/A
codesign -f -v -s "3rd Party Mac Developer Application: Name" ./Growl.framework/Versions/A
codesign -f -v -s "3rd Party Mac Developer Application: Name" ./GData.framework/Versions/A

4

Đây là cách tôi đã sửa nó;

  • Nhập cài đặt xây dựng của mục tiêu của bạn
  • Tìm dòng "Cờ ký mã khác"
  • Nhập giá trị --deep vào thông số phát hành
  • Đóng XCode
  • Nhập vào thư mục dữ liệu dẫn xuất trên máy Mac của bạn và xóa dữ liệu dẫn xuất cũ (đường dẫn mặc định là: / Users / YOUR_USER_NAME / Library / Developer / Xcode / DerivedData)
  • Mở Xcode và xây dựng

Sau khi lưu trữ bản dựng và gửi lại ứng dụng ...


3
Trong một thế giới giấc mơ "--deep" sẽ hoạt động như mong đợi nhưng chúng ta không sống trong một thế giới mơ ...
mike

0

Một điều tôi không thấy được đề cập ở đây là bạn cần có Info.plist bên trong / Tài nguyên bên trong thư mục khuôn khổ được phiên bản. Nếu không, bạn sẽ gặp phải lỗi "định dạng gói không được công nhận, không hợp lệ hoặc không phù hợp" khi bạn cố gắng ký vào thư mục được tạo phiên bản.

Tôi đã cung cấp một câu trả lời mở rộng hơn ở đây: Cách thiết kế mã Growl.framework cho Ứng dụng Sandboxed Mac

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.