アプリをサンドボックス化し、XML ファイルを使用して複数のファイルのインポート/エクスポートを許可しようとしています。私のアプリ (または別のサンドボックス化されたアプリ) が XML にリストされたファイルにアクセスできるようにするために、シリアル化されたセキュリティ スコープのブックマークも含めます。この回答で説明されているようにシリアル化しています。単体テスト (サンドボックス化されていない) は、問題なく XML データの書き込みと読み取りを行います。私のアプリがブックマークを解決するNSURL
と、参照と同様に nil が返されNSError
ます。私はそうあるべきだとは思わないのに、なぜそうなってしまったのでしょうか? でファイル/ディレクトリを選択するようにユーザーに促すことで回避できますNSOpenPanel
が、ブックマークを正常に機能させたいと思っています。
テストプロジェクトで再現
自宅で再現するには、Xcode で新しい Cocoa アプリを作成し、プロジェクト内のファイルに次の Gist を使用します: https://gist.github.com/2582589 (適切な next-view ループで更新)
次に、Apple の指示に従って、プロジェクトにコード署名します。ボタンを順番にクリックして、問題 (Apple にrdar://11369377として送信) を再現します。ディスク (アプリのコンテナーの外部) 上の任意のファイルを選択し、エクスポートする XML を選択してから、同じ XML をインポートします。
うまくいけば、私が間違っていることを理解するのを手伝ってくれるでしょう。私が何か間違ったことをしていて、フレームワークが誤ってそれ自体を維持しているか、または私が正しくやっているのに完全に壊れています。フレームワークを責めないようにしていますが、それはどちらですか? それとも別の可能性がありますか?
サンプルコード
XML を にエクスポートしていますdocURL
:
// After the user picks an XML (docURL) destination with NSSavePanel
[targetURL startAccessingSecurityScopedResource];
NSData *bookmark = [targetURL bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
includingResourceValuesForKeys:nil
relativeToURL:docURL
error:&error];
[targetURL stopAccessingSecurityScopedResource];
からの XML のインポートdocURL
:
// After the user selected the XML (docURL) from an NSOpenPanel
NSURL *result = [NSURL URLByResolvingBookmarkData:bookmarkData
options:NSURLBookmarkResolutionWithSecurityScope
relativeToURL:docURL
bookmarkDataIsStale:nil
error:&error];
この呼び出しを[docURL ..AccessingSecurityScopedResource]
で囲んでみましたが、違いはありませんでした (予想どおり、オープン パネルで選択された後、docURL は既にスコープ内にあるため)
また、app.entitlements
ファイルで次のように指定します。
com.apple.security.files.user-selected.read-write
com.apple.security.files.bookmarks.app-scope
com.apple.security.files.bookmarks.collection-scope
前述のように、2 番目のステップ (ブックマークの解決) は完了しますが、両方とも nil のままerror
ですresult
。サンドボックスを実装してきたので、私が犯した間違いのほとんどNSError
が返され、バグを解決するのに役立ちました. しかし、今ではエラーは発生せず、URL は解決されません。
その他のトラブルシューティング手順
XML ファイルをアプリのサンドボックスに配置しようとしましたが、違いはなかったので、XML ファイルへのアクセスは問題ではありません
アプリは ARC を使用しますが、単体テストも同様に成功します。自動解放されたクラス メソッドの代わりに alloc/init も使用してみました (念のため)
ブックマークを作成した直後に URL 解決コードを貼り付けたところ、問題なく動作し、セキュリティ スコープの URL が生成されました
最初に作成された
po
ブックマーク (シリアル化前) と、逆シリアル化後のブックマークに対して実行したところ、100% 一致しました。シリアル化は問題ではありません解決の呼び出しを に置き換えましたが、
CFURLCreateByResolvingBookmarkData(..)
変更はありません。バグの場合は、Core Foundation API と Cocoa レイヤーに存在します。に値を指定し
bookmarkDataIsStale:
ても効果がない0
forを指定するとoptions:
、有効な NSURL が返されますが、セキュリティ スコープがないため、ファイルを読み取る後続の呼び出しは失敗します。つまり、逆シリアル化されたブックマークは有効に見えます。ブックマーク データが破損していた場合、NSURL で何かできるとは思えません。
NSURL.h
私が間違っていることを指摘するのに役立つコメントが含まれていませんでした
サンドボックス化されたアプリケーションでセキュリティ スコープのドキュメント ブックマークを使用して成功した人は他にいますか? もしそうなら、あなたは私と何が違うのですか?
OS バージョンのリクエスト
Mountain Lion ベータ版にアクセスできる人は、私のサンプル プロジェクトで同じ (エラーがない) エラーが表示されるかどうかを確認できますか? ライオン以降に修正されたバグなら気にしません。私はまだ開発者プログラムに参加していないため、アクセスできません。その質問に答えることが NDA に違反するかどうかはわかりませんが、そうならないことを願っています。