Mac App Store 용 프레임 워크 번들을 어떻게 코딩합니까?


81

최근 제출 후 다음 오류가 발생했습니다.

잘못된 서명-중첩 된 앱 번들 (FooBar.app/Contents/Frameworks/GData.framework)이 서명되지 않았거나 서명이 잘못되었거나 Apple 제출 인증서로 서명되지 않았습니다. 자세한 내용은 코드 서명 및 애플리케이션 샌드 박싱 가이드를 참조하세요.

잘못된 서명-중첩 된 App Bundle (FooBar.app/Contents/Frameworks/Growl.framework)이 서명되지 않았거나 서명이 유효하지 않거나 Apple 제출 인증서로 서명되지 않았습니다. 자세한 내용은 코드 서명 및 애플리케이션 샌드 박싱 가이드를 참조하세요.

잘못된 서명-중첩 된 앱 번들 libcurl (FooBar.app/Contents/Frameworks/libcurl.framework)이 서명되지 않았거나 서명이 잘못되었거나 Apple 제출 인증서로 서명되지 않았습니다. 자세한 내용은 코드 서명 및 애플리케이션 샌드 박싱 가이드를 참조하세요.

그래서 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은 다음과 같이 말합니다.

서명 프레임 워크

프레임 워크가 번들이기 때문에 프레임 워크에 직접 서명 할 수 있다는 결론을 내리는 것이 논리적으로 보입니다. 그러나 이것은 사실이 아닙니다. 프레임 워크에 서명 할 때 문제를 방지하려면 전체 프레임 워크가 아닌 특정 버전에 서명해야합니다.

# 이것은 잘못된 방법입니다.

codesign -s my-signing-identity ../FooBarBaz.framework

# 이것이 올바른 방법입니다.

codesign -s my-signing-identity ../FooBarBaz.framework/Versions/A

그리고 결과를 확인하려고하면 나에게 좋게 보입니다.

% 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

재미로 프레임 워크 번들에 직접 서명을 시도했지만 여전히 거부되었습니다. 그러나 그것은 정확히 문서가하지 말라고 말한 것입니다.

왜 그것이 유효하지 않은지 추측합니까? 나는 과거에 작동했던 내 앱을 코딩하는 데 사용하는 것과 동일한 인증서를 사용하고 있습니다.

내 유일한 추측은 기존 plist (프레임 워크의 Info.plists에있는 식별자를 소유해야합니까?) 또는 권한 (제안 사항)과 관련이있을 것입니다.


앱을 제출했을 때이 사실을 일찍 발견했습니다. 고맙게도 Apple은이를 거부하지 않았지만 나중에 프레임 워크에 서명해야한다고 언급했습니다. Growl Google 코드 문제 페이지에 게시하는 것이 더 낫다고 생각하며 곧 사람들이 같은 문제에 부딪 힐 것입니다.
koo

2
또한 Growl 프레임 워크로 앱을 제출할 때이 문제가 발생했습니다. growl.framework 번들 식별자를 자신이 소유 한 식별자로 변경 한 다음 코드 서명해야한다고 생각합니다.
앤드류

이것은 이상합니다. 두 개의 프레임 워크 (CorePlot 및 MacRuby)가 모두 서명되지 않은 앱을 게시했습니다. 앱 번들에서 코드 서명 명령을 한 번만 실행했는데 프레임 워크에 대한 설명없이 앱이 승인되었습니다. 이제 앱 번들 ( bit.ly/charterapp )을 살펴보면 두 프레임 워크가 모두 서명 된 것처럼 보입니다. 단순히 전체 앱에 서명하려고 했습니까?
p4010

@ p4010, 나는했다-그들은 이전에 서명되지 않았다. 예를 들어 으르렁 거리는 것은 그들이 배포하는 곧은 묶음이었다. 이제이 앱이 한동안 스토어에 있었기 때문에 이것이 새로운 샌드 박싱 작업과 관련이 있다고 가정합니다. 언제 앱을 제출 했습니까?
csexton

@Andrew, 번들 식별자 변경이 효과가 있었습니까?
csexton

답변:


45

baptr의 답변을 기반으로 모든 프레임 워크 및 기타 바이너리 리소스 / 보조 실행 파일 (현재 지원되는 유형 : dylib, 번들 및 로그인 항목)을 코드 서명하는이 쉘 스크립트를 개발했습니다.

#!/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. 프로젝트의 파일에 저장하십시오. Scripts내 프로젝트 루트의 하위 디렉토리에 사본을 보관 합니다.
    • 내 이름은 codesign-frameworks.sh.
  2. "임베디드 프레임 워크 복사"빌드 단계 직후에 "스크립트 실행"빌드 단계를 추가합니다.
    • 이를 "Codesign Embedded Frameworks"라고 부를 수 있습니다.
  3. ./codesign-frameworks.sh스크립트 편집기 텍스트 필드에 붙여 넣으 십시오 (또는 위에서 스크립트라고 부르는 이름). ./Scripts/codesign-frameworks.sh스크립트를 하위 디렉토리에 저장하는 경우 사용 합니다.
  4. 앱을 빌드하십시오. 번들로 제공되는 모든 프레임 워크는 코드 서명됩니다.

여전히 " ID : 모호함 (일치 :…"오류가 발생하면 아래에 주석을 달아주십시오. 더 이상 발생하지 않아야합니다.)

업데이트 된 2012-11-14 : 이름에 특수 문자가 포함 된 프레임 워크 (작은 따옴표는 포함되지 않음)에 대한 지원이 "codesign-frameworks.sh"에 추가되었습니다.

업데이트 된 2013 년 1 월 30 일 : "codesign-frameworks.sh"에 모든 경로 (작은 따옴표 포함)의 특수 문자 지원 추가.

업데이트 된 2013-10-29 : 실험적인 dylib 지원 추가.

업데이트 된 2013 년 11 월 28 일 : 권한 지원 추가. 실험적 dylib 지원 개선.

업데이트 된 2014 년 6 월 13 일 : (중첩 된) 프레임 워크를 포함하는 프레임 워크의 코드 서명 문제 수정. 이것은 추가하여 이루어졌다 -depth에 옵션 find의 원인, find깊이 우선 탐색을 할 수 있습니다. 이것은 여기에 설명 된 문제로 인해 필요하게되었습니다 . 간단히 말해서 포함 번들은 중첩 번들이 이미 서명 된 경우에만 서명 할 수 있습니다.

업데이트 된 2014 년 6 월 28 일 : 실험용 번들 지원 추가.

업데이트 된 2014 년 8 월 22 일 : 코드 개선 및 IFS 복원 실패 방지.

업데이트 된 2014 년 9 월 26 일 : 로그인 항목에 대한 지원 추가.

2014 년 10 월 26 일 업데이트 : 디렉터리 확인 인용. 이렇게하면 "31/42 행 : 너무 많은 인수"오류와 특수 문자를 포함하는 경로에 대한 "코드 개체가 전혀 서명되지 않았습니다"오류가 수정됩니다.

업데이트 된 2014-11-07 : Xcode에서 자동 ID 확인을 사용할 때 모호한 ID 오류 (예 : "Mac Developer : ambiguous…")를 해결합니다. 더 이상 명시 적으로 ID를 설정할 필요가 없으며 "Mac Developer"만 사용할 수 있습니다!

2015 년 8 월 7 일 업데이트 : 의미 체계 개선.

개선을 환영합니다!


이것에 대해 감사합니다. 다만 참고로, 대상 이름에 공백이 있으면 작동하지 않습니다. 나는 고치려고 노력했지만 작동하지 않아 목표가 변경되었습니다.
Craig

FRAMEWORK_DIR의 이름에 공백 / 특수 문자가 있으면 이제 작동합니다.
JanX2 2012

그러나 codesign 명령 끝에 "--timestamp"를 추가하여 타임 스탬프 옵션을 비활성화해야했습니다.
Elmer Cat

흥미 롭군. 우연히 @Elmer Cat이 출시되지 않은 OS X 버전에서이 작업을 수행하고 있습니까? 매뉴얼 페이지는 "시스템 별 기본 동작"을 갖는이 옵션을 설명합니다.
JanX2 2013

1
Elmer Cat-어떤 버전의 Xcode를 실행 중인지 모르겠지만 5.0.1을 사용 중이며 확실히 내 프레임 워크에 자동으로 서명하지 않습니다. 이 대본을 찾을 때까지 머리를 찢고있었습니다.
Bryan

11

귀하의 의견은 번들의 버전 디렉토리 내에서 객체에 서명했음을 보여줍니다. Technote는 디렉토리 자체에 서명하는 것을 보여줍니다.

다음은 Technote와 더 잘 일치합니다.

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

이것이 내가 고친 방법입니다.

  • 대상의 빌드 설정을 입력하십시오.
  • "기타 코드 서명 플래그"줄을 찾습니다.
  • 릴리스 매개 변수에 --deep 값을 입력하십시오.
  • XCode 닫기
  • Mac의 파생 데이터 폴더로 들어가 이전 파생 데이터를 삭제합니다 (기본 경로 : / Users / YOUR_USER_NAME / Library / Developer / Xcode / DerivedData).
  • Xcode를 열고 빌드

빌드 아카이브 후 앱을 다시 제출하십시오 ...


3
... 우리는 꿈의 세계에 살고 있지 않지만 예상대로 작동 것 "--deep"꿈의 세계에서
마이크

0

여기서 언급하지 않은 한 가지는 버전이 지정된 프레임 워크 디렉토리의 / Resources 내에 Info.plist가 있어야한다는 것입니다. 그렇지 않으면 버전이 지정된 디렉토리에 서명하려고 할 때 "인식 할 수없는 번들 형식, 유효하지 않은 또는 적합하지 않은"오류가 발생합니다.

여기에 좀 더 확장 된 답변을 제공했습니다 : 샌드 박스 Mac 앱용 Growl.framework 공동 디자인 방법

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.