アプリの/ soundsフォルダー内にフォルダーを作成しようとしています。
-(void)productPurchased:(UAProduct*) product {
NSLog(@"[StoreFrontDelegate] Purchased: %@ -- %@", product.productIdentifier, product.title);
NSFileManager *manager = [NSFileManager defaultManager];
NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
NSError *error;
NSString *dataPath = [NSString stringWithFormat:@"%@/sounds/%@", bundleRoot, product.title];
if (![manager fileExistsAtPath:dataPath isDirectory:YES]) {
[manager createDirectoryAtPath:dataPath withIntermediateDirectories:YES attributes:nil error:&error];
NSLog(@"Creating folder");
}
NSLog(@"%@", error);
}
しかし、私はこのエラーを受け取ります:
Error Domain=NSCocoaErrorDomain Code=513 "The operation couldn’t be completed. (Cocoa error 513.)" UserInfo=0x175120 {NSFilePath=/var/mobile/Applications/D83FDFF9-2600-4056-9047-05F82633A2E4/App.app/sounds/Test Tones, NSUnderlyingError=0x117520 "The operation couldn’t be completed. Operation not permitted"}
私は何が間違っているのですか?ありがとう。
エラードメインでGoogleを検索すると、 NSCocoaErrorDomain
コード513
はエラーに変換されます NSFileWriteNoPermissionError
。
これにより、この問題を解決するための重要な手がかりが得られます。
具体的には、コンパイルされたアプリのバンドルフォルダーの内容を変更することはできません。これは、バンドルがコンパイル済みアプリケーションであるためです。
最終的にiTunesApp Storeを通じてアプリを配布すると、アプリケーションには、アプリのコンテンツを検証するデジタル署名が付けられます。この署名はコンパイル時に生成されます。
コンパイル後にバンドルを変更しようとすると、アプリが変更され、デジタル署名が無効になります。これはアプリケーションを無効にします—そこにどんなコードがあるか誰が知っていますか? —そしてエンドユーザーはそれを実行することができなくなります。したがって、Appleは、バンドルを変更しようとするとエラーをスローするようにiOSを設定しました。
バンドルに書き込む代わりに、アプリは 受け入れられている3つのアプリ固有のフォルダーの1つ :Documents
、Temp
、およびCache
に書き込むことができます。ほとんどの場合、Documents
フォルダーに書き込みます。
これらのフォルダーには、アプリからのみアクセスできます。他のアプリはこれらのフォルダーの内容にアクセスできません。 (同様に、アプリは別のアプリのフォルダーにアクセスできません。)
デスクトップファイル共有サポート を介して、エンドユーザーがiTunesを介してファイルデータへのアクセスを管理できるようにアプリを設定できます。
これは、実行時にアプリケーションのバンドルを変更してはならないためです。代わりに、リソースを追加できるフォルダーを別の場所に配置する必要があります。
編集:
表示されているエラーは、バンドルに書き込めないことが原因である可能性があります。
Logライブラリを使用すると、同じ問題が発生します。最後に、それはパスフォーマットの問題です。 dataPath
形式を確認してください。 Case 1
の場合、有効です。私の場合はCase 2
なので、ディレクトリの作成に失敗しました。
// Case 1
/var/mobile/Containers/Data/Application/5FB2CD2D-91DC-4FB2-8D6F-06369C70BB4A/Library/Caches/AppLogs
// Case 2, invalid format
file://var/mobile/Containers/Data/Application/5FB2CD2D-91DC-4FB2-8D6F-06369C70BB4A/Library/Caches/AppLogs
dataPath
にプレフィックスが付いている場合(例:file://
)、それは無効です。
NSURL
のインスタンスの場合、path
はcase 1
のような文字列を返し、absolutePath
はcase 2
のような文字列を返します。
私の場合、513エラーの意味はまだ完全にはわかりませんが、[NSFileHandle fileHandleForReadingFromURL:theUrl error:&err ]
を使用して開いたファイルのURLを読み取ろうとしたときにエラーが発生していました。
この回答 から、iOS 13では、アプリで開かれている外部ファイルにアクセスするためにstartAccessingSecurityScopedResource
を使用する必要があることに気付きました。次のようにファイル呼び出しをラップすると、エラー513の発生が停止しました。
if( [myURL startAccessingSecurityScopedResource] )
{
NSFileHandle* myFile = [NSFileHandle fileHandleForReadingFromURL:myURL error:&err ];
// ...Do file reads here...
[theUrl stopAccessingSecurityScopedResource];
}