web-dev-qa-db-ja.com

Xcode 6および埋め込みフレームワークはiOS8でのみサポートされています

Xcode 6.0.1の組み込みフレームワーク(dyld)を、iOS 8未満の展開ターゲットで使用すると、次のようになります:

  • ビルドが成功しました
  • ランタイムライブラリの読み込みエラー

エラー:

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) 
68
loretoparisi

しばらくの間、これも私の問題だと思っていましたが、通常のアプリ(non-iOS-8-extension)では、カジュアルなXcode 6 iOS Universal Frameworkで1つのビルド設定を変更するだけですターゲット(Mach-Oタイプを静的ライブラリに設定):

Set it to Static Library

その後、iTunes ConnectとiOS 7に問題はないはずです:)

39
Maciek Czarnik

だから、掘り下げた後、私は解決策を思いついた

MyEmbeddedFramework.frameworkをアプリに追加する場合は、これを実行します

  1. [一般]> [埋め込みバイナリ]タブでMyEmbeddedFramework.frameworkを削除します
  2. MyEmbeddedFramework.frameworkがある場合は、ビルドフェーズ>コピーフェーズ「Frameworks」を削除します。
  3. ビルドフォルダーのクリーンアップ
  4. Void Embedded FrameworksセクションでMyEmbeddedFramework.frameworkを移動します。
  5. 新しいビルドフェーズ> Embedded FrameworksがXCode6によって作成されていることがわかります(あなたではなく、自動的に行われます)。
  6. 5があれば、エラーなしで実行されるはずです。

要約すると、動作させるには、MyEmbeddedFramework.frameworkが

A)一般>埋め込みバイナリ General > Embedded Binaries

B)ビルドフェーズ>組み込みフレームワーク Build Phase > Embedded Frameworks

iPhone5/iOS8ではなくiPhone4S/iOS7でうまくいきました:

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:incompatible cpu-subtype:0x0000000B in/private /var/mobile/Applications/739D9C44-3B91-4D4F-805B-83BE66C9CBCA/musiXmatch.app/Frameworks/ObjectiveLyricsTouch2.framework/ObjectiveLyricsTouch2

問題はEmbeddedFrameworkにありました。そうしなければならなかった

1)アーキテクチャをデフォルトに設定します2)有効なアーキテクチャをarmv7、armv7s、およびarmv64に設定します(Appleは、Embedded Frameworksを動作させるためにarmv64が必要であることを示唆しています)。

その後、埋め込みフレームワークでアプリを実行することができました

  • iPhone5S/iPhone5C iOS8
  • iPhone5S/iPhone5C iOS7
  • iPod第5世代/ iOS7
  • iPhone4S/iOS7
  • iPhone4/iOS7

とにかく、iTunesConnectに送信すると、最小必要バージョンのエラーが表示されます。

  • フレームワーク「...」のMinimumOSVersionが無効です。最小値はiOS 8.0です。
  • 無効なアーキテクチャ:アプリ拡張機能とフレームワークを含むアプリはarm64をサポートする必要があります。

Embedded Framework Issues

30
loretoparisi

現時点では、組み込みフレームワークを使用してアプリとウィジェットの間でコードを共有し、iOS 8およびiOS 7以前で実行する方法はありません。

これについては、さらにいくつかの読み物があります http://atomicbird.com/blog/ios-app-extension-tips

フレームワークとiOS 7

アプリと拡張機能の間でコードを共有している場合、そのための良い方法の1つは、コードを保持する独自の埋め込みフレームワークを作成することです。 iOS 8では、どちらの場合も動的にロードされるため、設定は完了です。

IOS 7(またはそれ以前)をまだサポートしている場合、それほど明確ではありません。組み込みフレームワークはそこでは機能しません。 App Extensionプログラミングガイドでは、dlopenを使用してこれに対処できることを簡単に説明しています。そのアプローチを使用すると、コードがそれをサポートするiOSのバージョンで実行されていることを確認した場合、iOSがロードすることに依存するのではなく、実行時にフレームワークを動的にロードするコードを記述します。

しかし、iOS 7でそのコードをどのように使用しますか?あなたはしません。共有コードが組み込みフレームワークにある場合、iOS 7でそれを実行する方法はありません。ただ利用できません。

Dlopenのアプローチは、iOS 8でのみ共有コードが必要な場合に便利です。iOS7で共有コードが必要な場合は、アプリのターゲットに含める必要があります。そして、一度それを行えば、フレームワークは必要ありません。アプリの拡張にフレームワークを使用することもできますが、実際に使用することは実際には役に立ちません。あなたはフレームワークを作成する作業をしますが、それから利益を得ることはありません。両方のターゲットに共有コードを含めるだけです。

Appleの拡張ガイドから https://developer.Apple.com/library/ios/documentation/General/Conceptual/ExtensibilityPG/ExtensibilityPG.pdf

含まれているアプリから埋め込みフレームワークにリンクする場合、埋め込みフレームワークはそれらのバージョンでは使用できませんが、8.0よりも古いバージョンのiOSにデプロイできます。

12
BigCheesy

さらに詳しく Apple Documentationdlopenコマンドについて知りました。サポートされているシステムのバージョンとライブラリに応じて、いくつかの条件でライブラリのリンクを作成するために使用されます。

dlopenの使用例: 関数 'dlopen()' private API?

Apple Docsが提供するソリューションを見てみましょう。

含まれるアプリを古いバージョンのiOSにデプロイする

含まれているアプリから埋め込みフレームワークにリンクする場合、埋め込みフレームワークはそれらのバージョンでは使用できませんが、8.0よりも古いバージョンのiOSにデプロイできます。

これを可能にするメカニズムは、dlopenコマンドであり、条件付きでリンクおよびロードするために使用しますフレームワークバンドル。 Xcode GeneralまたはBuild Phasesで指定できるビルド時リンクの代わりにこのコマンドを使用しますターゲットエディター。主なアイデアは、iOS 8.0以降で実行している場合にのみ、組み込みフレームワークを含むアプリにリンクすることです

フレームワークバンドルを条件付きでロードするコードステートメントでは、SwiftではなくObjective-Cを使用する必要があります。アプリの残りの部分はどちらの言語でも記述でき、組み込みフレームワーク自体も同様にいずれかの言語で記述できます。

dlopenを呼び出した後、次のタイプのステートメントを使用して埋め込みフレームワーククラスにアクセスします。

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

重要

含まれているアプリのターゲットが埋め込みフレームワークにリンクしている場合、arm64アーキテクチャを含める必要があります。そうしないと、App Storeによって拒否されます。

条件付きリンクを利用するようにアプリ拡張機能のXcodeプロジェクトをセットアップするには

  1. 含まれているアプリ拡張機能ごとに、通常どおり、展開ターゲットをiOS 8.0以降に設定します。これは、Xcodeターゲットエディターの[全般]タブの[展開情報]セクションで行います。
  2. 含まれているアプリの場合、サポートするiOSの最も古いバージョンに展開ターゲットを設定します。
  3. 含まれているアプリで、systemVersionメソッドを使用して、iOSバージョンのランタイムチェック内でdlopenコマンドの呼び出しを条件付きにします。含まれているアプリがiOS 8.0以降で実行されている場合にのみ、dlopenコマンドを呼び出します。この呼び出しを行うときは、SwiftではなくObjective-Cを使用してください。

特定のiOS APIは、dlopenコマンドを介して組み込みフレームワークを使用します。 dlopenを直接呼び出す場合と同様に、これらのAPIの使用を条件付けする必要があります。これらのAPIは、CFBundleRef不透明型からのものです。

CFBundleGetFunctionPointerForName
CFBundleGetFunctionPointersforNames

NSBundleクラスから:

負荷
loadAndReturnError:
classNamed:

8.0より古いバージョンのiOSにデプロイする包含アプリケーションでは、これらのAPIを、iOS 8.0以降で実行されていることを確認するランタイムチェック内でのみ呼び出し、Objective-Cを使用してこれらのAPIを呼び出します。

4
E-Riddie

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:warning:embedded dylibs/frameworksはiOS 8以降でのみ実行されます

これは、異なるiosターゲットを誤って設定し、エラーを引き起こすxcodeのバグのように見えます。

4
Gamma-Point

記録のためだけに...プロジェクトをiOS8からiOS7展開タイプに変更するときにこの問題が発生しました。

このアプリはココアポッドを使用し、カスタムの組み込みフレームワークは使用しませんでした。

メインプロジェクトの2つのターゲットを変更する必要がありました
応用
アプリケーションテスト

Mach-Oタイプを静的に変更します(上記の回答から)。

次に、cocoapodsプロジェクトについて。各サブポッドプロジェクトの下で、Mach-Oタイプを静的に変更し、メインポッドのプロジェクトMach-O設定を空白のままにします。

2
StuartM

Mach-O TypeをEXECUTABLEに設定すると、うまくいきました。静的、動的、またはバンドルに設定すると、実行時に他のエラーが発生しました。

ターゲット>「あなたのアプリ」>ビルド設定>リンク> Mach-Oタイプ>実行可能ファイル

2
ctw

次の構成で最新のコードを実行してみました。

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

アプリは3つのデバイスすべてで正常に動作していますが、コンパイル中にXcodeに警告が表示されます。 「組み込みdylibs/frameworksはiOS 8以降でのみ実行されます」

また、私はそれがうまくいったアプリストアに提出するために、アプリをアーカイブしようとしました。

また、Apple開発者がこれをバグであると述べているリンクを見つけました https://devforums.Apple.com/message/999579#999579

2
Ravi Dalmia

私はこの問題を次のように解決します:ターゲット「Embedded Framework」と「main App」ターゲットの両方で同じデプロイメントターゲットを使用します。

1
Payal Maniyar

だから、一時的に、iOS 7の多くのデバイスでは動的ライブラリーにノーと言いました。どうやって問題を解決したのですか。アプリと拡張機能の間でモデルを転送するにはlibが必要でした。だから、JSON文字列にモデルを共有コンテナーに入れます。そして、それは魅力のように機能します。

1
Andrey Gagan

私はいくつかのライブラリを組み込みフレームワークとして含める必要があるという問題に直面していました。

私の解決策は、ポッドを使用して、「use_frameworks!」のコメントを外すことです。ライン。

0
Jason Silver

Xcode 7.3にアップデートするときにバグがありました。そして、私には解決策がありました。 -ポッドプロジェクトのターゲットを変更する-> 7.0-それが役立つことを願っています! attack

0
PhuocLuong

使用フレームワークを削除してください!フレームワークをiOS 7.0で動作させる場合は、PodFileから。つまり、pod deintegrateコマンドを実行し、PodFileを変更してから、pod installコマンドを再実行します

また、この後、フレームワークのすべての.hファイルをブリッジングファイルに追加する必要があり、問題が修正されました。 SwiftファイルからインポートTestLibraryも削除します

0
Sohil Dedhia

IOSでダイナミックライブラリを使用する場合、ライブラリにコード署名する必要があります。 Xcode 6では、「Code Sign On Copy」を選択する必要があります。 Xcode5では、実行スクリプトを使用して自分でライブラリに署名する必要があります。好む :

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