Program Tip

Xcode 6 및 임베디드 프레임 워크는 iOS8에서만 지원됩니다.

programtip 2020. 11. 8. 10:57
반응형

Xcode 6 및 임베디드 프레임 워크는 iOS8에서만 지원됩니다.


배포 대상이 iOS 8 미만인 Xcode 6.0.1에서 포함 된 프레임 워크 (dyld)를 사용할 때 다음을 얻습니다.

  • 빌드 성공
  • 런타임 라이브러리로드 오류

오류:

dyld: Library not loaded: @rpath/ObjectiveLyricsTouch2.framework/ObjectiveLyricsTouch2        
Referenced from: /private/var/mobile/Containers/Bundle/Application/DC65ACA9-98E5-46CD-95F8-829D3416F6C0/musiXmatch.app/musiXmatch
Reason: image not found
(lldb) 

얼마 동안 나는 이것이 내 문제라고 생각했지만 일반 앱 ( 비 iOS-8 확장 )의 경우 캐주얼 Xcode 6 iOS Universal Framework 대상 ( Mach-O 유형 설정)에서 하나의 빌드 설정 만 변경하면됩니다. 정적 라이브러리로 ) :

정적 라이브러리로 설정

그 후 iTunes Connect 및 iOS 7에는 문제가 없습니다. :)


그래서 주위를 파고 나서 해결책을 찾았습니다.

앱에 추가 할 MyEmbeddedFramework.framework가 있다고 가정하면 다음과 같이하십시오.

  1. 일반> 포함 된 바이너리 탭에서 MyEmbeddedFramework.framework를 제거합니다.
  2. MyEmbeddedFramework.framework가있는 경우 Build Phases> Copy Phase "Frameworks"를 제거합니다.
  3. 빌드 폴더 정리
  4. void Embedded Frameworks 섹션에서 MyEmbeddedFramework.framework를 이동합니다.
  5. 이제 새로운 빌드 단계> 임베디드 프레임 워크가 XCode6에 의해 생성 된 것을 볼 수 있습니다 (사용자가 아니라 자동으로 수행됨).
  6. 이제 5 개가 있으면 오류없이 실행됩니다.

요약하자면, 작동하게하려면 MyEmbeddedFramework.framework를

A) 일반> 임베디드 바이너리 일반> 임베디드 바이너리

B) 빌드 단계> 임베디드 프레임 워크 빌드 단계> 임베디드 프레임 워크

iPhone4S / iOS7이 아닌 iPhone5 / iOS8 에서 잘 작동했습니다 .

dyld : 라이브러리가로드되지 않음 : @ rpath / ObjectiveLyricsTouch2.framework / ObjectiveLyricsTouch2 참조 위치 : /var/mobile/Applications/739D9C44-3B91-4D4F-805B-83BE66C9CBCA/musiXmatch.app/musiXmatch 이유 : 적합한 이미지가 없습니다. 발견 : /private/var/mobile/Applications/739D9C44-3B91-4D4F-805B-83BE66C9CBCA/musiXmatch.app/Frameworks/ObjectiveLyricsTouch2.framework/ObjectiveLyricsTouch2 : 호환되지 않는 cpu-subtype : / private / var / mobile / Applications /에서 0x0000000B 739D9C44-3B91-4D4F-805B-83BE66C9CBCA / musiXmatch.app / Frameworks / ObjectiveLyricsTouch2.framework / ObjectiveLyricsTouch2

문제는 EmbeddedFramework에있었습니다. 나는해야했다

1) 아키텍처를 기본값으로 설정합니다. 2) 유효한 아키텍처를 armv7, armv7s 및 armv64로 설정합니다 (Apple에서 임베디드 프레임 워크가 작동하려면 armv64가 필요하다고 제안했듯이).

그런 다음 임베디드 프레임 워크로 앱을 실행할 수있었습니다.

  • iPhone5S / iPhone5C iOS8
  • iPhone5S / iPhone5C iOS7
  • iPod 5 세대 / iOS7
  • iPhone4S / iOS7
  • iPhone4 / iOS7

어쨌든 iTunesConnect에 제출할 때 최소 필수 버전에 대해 몇 가지 오류가 발생합니다.

  • 프레임 워크 "..."의 MinimumOSVersion이 잘못되었습니다. 최소값은 iOS 8.0입니다.
  • 잘못된 아키텍처 : 및 앱 확장 및 프레임 워크를 포함하는 앱은 arm64를 지원해야합니다.

임베디드 프레임 워크 문제


현재로서는 임베디드 프레임 워크를 사용하여 앱과 위젯간에 코드를 공유하고 iOS 8 및 iOS 7 및 이전 버전에서 실행할 수있는 방법이 없습니다.

http://atomicbird.com/blog/ios-app-extension-tips 에 대한 추가 정보가 있습니다.

프레임 워크 대 iOS 7

앱과 확장간에 코드를 공유하는 경우이를위한 한 가지 좋은 방법은 코드를 보유 할 자체 임베디드 프레임 워크를 만드는 것입니다. iOS 8에서는 두 경우 모두 동적으로로드되므로 설정이 완료됩니다.

iOS 7 (또는 이전 버전)을 여전히 지원한다면 그렇게 명확하지 않습니다. 임베디드 프레임 워크는 작동하지 않습니다. 앱 확장 프로그래밍 가이드에서는 dlopen을 사용하여이 문제를 해결할 수 있음을 쉽게 설명합니다. 이러한 접근 방식을 사용하면 코드가이를 지원하는 iOS 버전에서 실행되고 있음을 확인한 경우 iOS에 의존하지 않고 런타임에 동적으로 프레임 워크를로드하는 코드를 작성합니다.

하지만 iOS 7에서이 코드를 어떻게 사용합니까? 당신은하지 않습니다. 공유 코드가 포함 된 프레임 워크에있는 경우 iOS 7에서 실행할 방법이 없습니다. 사용할 수 없습니다.

dlopen 접근 방식은 iOS 8에서 공유 코드 만 필요한 경우 유용 할 수 있습니다. iOS 7에서 필요한 경우 앱 대상에 포함해야합니다. 그렇게하면 프레임 워크가 필요하지 않습니다. 앱 확장을위한 프레임 워크를 계속 사용할 수 있지만 그렇게하는 것은 실제로 유용하지 않습니다. 당신은 프레임 워크를 만드는 작업을하고 있지만 그것으로부터 어떤 이점도 얻지 못할 것입니다. 두 대상 모두에 공유 코드를 포함하기 만하면됩니다.

그리고 Apple의 확장 가이드 https://developer.apple.com/library/ios/documentation/General/Conceptual/ExtensibilityPG/ExtensibilityPG.pdf

포함 된 앱에서 포함 된 프레임 워크에 연결하는 경우 해당 버전에서 포함 된 프레임 워크를 사용할 수없는 경우에도 8.0 이전 버전의 iOS에 배포 할 수 있습니다.


xcode 6.1.1의 오류 수정

vim 또는 vi를 사용하여 project.pbxproj 파일을 엽니 다.

파일의 끝에 (8.1 검색) Begin XCBuildConfiguration 섹션이 있습니다.

프레임 워크를 찾으십시오.

Xcode를 통해 배포 대상이 7.1로 설정 되었더라도-> 대상 설정에서 일반 파일의 항목은 디버그 및 릴리스 모두에 대해 8.1이었습니다.

이전 파일 섹션은 다음과 같습니다.

CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
INFOPLIST_FILE = ENFramework/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";

새 섹션은 다음과 같습니다.

CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
INFOPLIST_FILE = ENFramework/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 7.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";

이제 경고 만 표시되는 것이 아니라 iOS 7.1 장치에서 작동합니다. ld : 경고 : 임베디드 dylibs / frameworks는 iOS 8 이상에서만 실행됩니다.

이것은 다른 ios 타겟을 잘못 설정하고 오류를 일으키는 xcode 버그처럼 보입니다.


Going deeper on Apple Documentation I found out about dlopen command, which is used to make the linking of the libraries on some conditions, depending on system versions and libraries supported.

dlopen example of use: Is the function 'dlopen()' private API?

So let's look at the solution provided by Apple Docs:

Deploying a Containing App to Older Versions of iOS

If you link to an embedded framework from your containing app, you can still deploy it to versions of iOS older than 8.0, even though embedded frameworks are not available in those versions.

The mechanism that lets you do this is the dlopen command, which you use to conditionally link and load a framework bundle. You employ this command as an alternative to the build-time linking you can specify in the Xcode General or Build Phases target editor. The main idea is to link embedded frameworks into your containing app only when running in iOS 8.0 or newer.

You must use Objective-C, not Swift, in your code statements that conditionally load a framework bundle. The rest of your app can be written in either language, and the embedded framework itself can likewise be written in either language.

After calling dlopen, access the embedded framework classes using the following type of statement:

MyLoadedClass *loadedClass = [[NSClassFromString (@"MyClass") alloc] init];

IMPORTANT

If your containing app target links to an embedded framework, it must include the arm64 architecture or it will be rejected by the App Store.

To set up an app extension Xcode project to take advantage of conditional linking

  1. For each of your contained app extensions, set the deployment target to be iOS 8.0 or later, as usual. Do this in the “Deployment info” section of the General tab in the Xcode target editor.
  2. For your containing app, set the deployment target to be the oldest version of iOS that you want to support.
  3. In your containing app, conditionalize calls to the dlopen command within a runtime check for the iOS version by using the systemVersion method. Call the dlopen command only if your containing app is running in iOS 8.0 or later. Be sure to use Objective-C, not Swift, when making this call.

Certain iOS APIs use embedded frameworks via the dlopen command. You must conditionalize your use of these APIs just as you do when calling dlopen directly. These APIs are from the CFBundleRef opaque type:

CFBundleGetFunctionPointerForName
CFBundleGetFunctionPointersforNames

And from the NSBundle class:

load
loadAndReturnError:
classNamed:

In a containing app you are deploying to versions of iOS older than 8.0, call these APIs only within a runtime check that ensures you are running in iOS 8.0 or newer, and call these APIs using Objective-C.


We tried running the latest code on the following configurations:

iOS 8+ — iPhone 5s iOS 7.1.2 — iPhone 4 iOS 6.1.3 — iPad 4

The App is working fine on all the three devices but the warning is present in the Xcode while compiling . "embedded dylibs/frameworks only run on iOS 8 or later”

Also I tried to Archive the App in order to submit it to the app store it went on fine.

Also, found out a link where in an apple developer stated this to be a bug https://devforums.apple.com/message/999579#999579


Just for the record... I had this issue when changing a project from iOS8 to iOS7 deployment type.

The app used cocoapods and no custom embedded frameworks.

I had to change the main project two targets
Application
Application-Test

Changing Mach-O Type to static (from above answer).

Then on the cocoapods project. Under each sub pod project changing the Mach-O type to static, leaving the main pod Project Mach-O setting to blank.


I set the Mach-O Type to EXECUTABLE and it worked for me. Setting it to Static, Dynamic or Bundle created other errors when I ran it.

Target > "Your App" > Build Settings > Linking > Mach-O Type > Executable


I solve this problem following way : Use same deployment target in both target "Embedded Framework" and "main App" target.


So, temporary, i said no to dynamic library, while many devices on iOS 7. How i solved my problem. I was need lib for transferring model between app and extension. So, i put my model to JSON string into shared container. And it works like a charm.


When you use dynamic library on ios you must code signed the library. In the Xcode 6, you should select the "Code Sign On Copy". And with the Xcode5, you should sign the library by your self with run script. like :

LOCATION="${BUILT_PRODUCTS_DIR}"/"${FRAMEWORKS_FOLDER_PATH}"
IDENTITY="iPhone Developer: xxxxx"
codesign --verbose --force --sign "$IDENTITY" "$LOCATION/BeeFramework.framework/BeeFramework"

Remove the use frameworks! from your PodFile if you want the Framework to work in iOS 7.0. i.e. run pod deintegrate command, modify your PodFile and then rerun the pod install command

Also after this, I had to add all the .h file's of the Framework in the Bridging file, that fixed the issue. Also remove the import TestLibrary from the swift files


I had a bug when updating to xcode 7.3. And I had solution for me. - Change targets in pods project -> 7.0 - Hope it useful! 공격


나는 임베디드 프레임 워크로 일부 라이브러리를 포함 해야하는 문제가 발생했습니다. 그렇지 않으면 위의 오류가 발생하고 방금 그렇게했을 때 앱 스토어에 제출할 때 오류가 발생했습니다.

내 해결책은 Pod를 사용하고 "use_frameworks!"의 주석 처리를 제거하는 것이 었습니다. 선.

참고 URL : https://stackoverflow.com/questions/25909870/xcode-6-and-embedded-frameworks-only-supported-in-ios8

반응형