6

私のアプリは を使用しNSDocumentDirectoryて画像を保存しています。画像を保存する安全な方法 (最大 100) かどうかを尋ねたいだけです。いくつかのスレッドと質問を読みましたが、どれに従うべきかわかりません.そこに保存しても大丈夫だと言う人もいます. NSDocumentDirectoryによってバックアップされるため、保存に使用するべきではないという人もいiCloudます。では、ユーザーがアプリを終了してアプリを再度実行したときに、画像がまだそこにあるはずであることをどこに保存できますか? tmpディレクトリまたはディレクトリについてあまり知りませんcache。しかし、それが私が使用する必要がある2つのいずれかである場合、ここで私のコードでそれらを使用するにはどうすればよいですか:

                NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory,    NSUserDomainMask ,YES );
                NSString *documentsDir = [paths objectAtIndex:0];
                NSString *savedImagePath = [documentsDir stringByAppendingPathComponent:[NSString stringWithFormat:@"Images%d.png", i]];
                ALAssetRepresentation *rep = [[info objectAtIndex: i] defaultRepresentation];
                UIImage *image = [UIImage imageWithCGImage:[rep fullResolutionImage]];
                //----resize the images
                image = [self imageByScalingAndCroppingForSize:image toSize:CGSizeMake(256,256*image.size.height/image.size.width)];

                NSData *imageData = UIImagePNGRepresentation(image);
                [imageData writeToFile:savedImagePath atomically:YES];

助けてくれてありがとう。

4

4 に答える 4

19

tmpおよびディレクトリは、cacheiOS によって定期的にクリーンアップされます。画像が一般的に使用される場合は、他の2つの回答が示唆するようにカメラロールを使用してください. ただし、これらの画像がアプリの範囲のみを対象としている場合でも、Documents ディレクトリに安全に保存できます。Apple を防ぐために、保存後に各ファイルに「iCloud バックアップから除外」関数呼び出しを含める必要があります。 iCloud 容量を使いすぎたためにアプリを拒否する。もちろん、トレードオフがあります。これを無効にすると、ユーザーがアプリを削除したり、別のデバイスを取得したりすると、とにかく写真が失われますが、ストアでアプリをまったく取得しないよりは、この警告の方が望ましいです。

ファイルの iCloud バックアップを無効にするには、iOS バージョンが 5.0 を超える場合、次の 2 つの方法があります。

アップデート!両方の方法を、iOS バージョンを自動的に処理する単一の関数にマージしました。

#include <sys/xattr.h> // Needed import for setting file attributes

+(BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)fileURL {

    // First ensure the file actually exists
    if (![[NSFileManager defaultManager] fileExistsAtPath:[fileURL path]]) {
        NSLog(@"File %@ doesn't exist!",[fileURL path]);
        return NO;
    }

    // Determine the iOS version to choose correct skipBackup method
    NSString *currSysVer = [[UIDevice currentDevice] systemVersion];

    if ([currSysVer isEqualToString:@"5.0.1"]) {
        const char* filePath = [[fileURL path] fileSystemRepresentation];
        const char* attrName = "com.apple.MobileBackup";
        u_int8_t attrValue = 1;
        int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
        NSLog(@"Excluded '%@' from backup",fileURL);
        return result == 0;
    }
    else if (&NSURLIsExcludedFromBackupKey) {
        NSError *error = nil;
        BOOL result = [fileURL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
        if (result == NO) {
            NSLog(@"Error excluding '%@' from backup. Error: %@",fileURL, error);
            return NO;
        }
        else { // Succeeded
            NSLog(@"Excluded '%@' from backup",fileURL);
            return YES;
        }
    } else {
        // iOS version is below 5.0, no need to do anything
        return YES;
    }
}

アプリが 5.0 をサポートする必要がある場合、残念ながら唯一のオプションは、これらの写真を Caches ディレクトリに保存することです。つまり、写真はバックアップされません (その理由で App Store で拒否されることはありません)。キャッシュ フォルダーをクリーニングするときが来ました。これらの写真は失われます。まったく理想的な実装ではありませんが、これが 5.0 の野獣の性質であり、Apple は後付けとして Backup の除外を追加しました。

編集:質問の「tmp/cacheディレクトリに保存する方法」の部分に答えるのを忘れました。その道を進むことにした場合:

  • 保存先tmp:

    NSString *tempDir = NSTemporaryDirectory();
    NSString *savedImagePath = [tempDir stringByAppendingPathComponent:[NSString stringWithFormat:@"Images%d.png", i]];
    

(これはシミュレーターでは何の効果もないように見えますが、デバイスでは期待どおりに機能することに注意してください)

  • 保存先Cache:

    NSString *cacheDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES)lastObject];
    NSString *savedImagePath = [cacheDir stringByAppendingPathComponent:[NSString stringWithFormat:@"Images%d.png", i]];
    
于 2012-07-25T01:09:54.900 に答える
2

ユーザーが他のアプリで画像を使用したり、写真と一緒に表示したりできるようにする場合は、Mike D が提案するようにフォト アルバムを使用します。ファイルがアプリでのみ使用するためにローカルで生成するものである場合は、おそらくドキュメント ディレクトリを使用する必要があります。ユーザーが iTunes を介してファイルを追加または削除できるようにする info.plist オプション「アプリケーションは iTunes ファイル共有をサポート」を使用して、ドキュメント ディレクトリを iTunes に公開できますが、ファイルは他のアプリには公開されません。

于 2012-07-25T00:39:52.797 に答える
1

スケーリングされた画像を保存しているので、実際にはゲームにのみ役立ちます。それらはそれほど大きくはならず、多くのスペースを占有しません。それらをアプリの Library ディレクトリに保存し、iCloud 全体を避けることができます。それらをバックアップする理由があるようには思えないからです。また、ライブラリを保存すると、他の理由で iTunes 共有がオンになっている場合に、ユーザーがライブラリを削除する可能性を回避できます。

更新:アプリ ライブラリ ディレクトリに保存するためのコード

- (void)saveSequences:(NSMutableDictionary*)sequences
{
    NSArray *path = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
    NSString *libDirectory = [path objectAtIndex:0];
    NSString *settingsPath = [libDirectory stringByAppendingPathComponent:@"userSequences.plist"];

    NSLog(@"settingsPath %@", settingsPath);

    [sequences writeToFile:settingsPath atomically:YES];
}

// 以下のコードは、'Documents' フォルダ内の名前付きディレクトリへのパスを取得し、存在しない場合は作成します。ライブラリ パスを使用する場合は、ライブラリ パスを使用するように調整します。

- (NSString *)getDirectoryBySequenceName:(NSString *)sequenceName 
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString * documentDirectory = [paths objectAtIndex:0];
    NSString * sequenceDirectory = [documentDirectory stringByAppendingPathComponent:sequenceName];

    NSError *error;
    BOOL success = [[NSFileManager defaultManager] createDirectoryAtPath:sequenceDirectory 
                                             withIntermediateDirectories:YES 
                                                              attributes:nil error:&error];   

    if (!success) {
        NSLog(@"Error creating data path: %@", [error localizedDescription]);
    }

    return sequenceDirectory;
}
于 2012-07-25T02:48:30.697 に答える
0

アプリの目的によっては、写真アプリに保存することもできます ( Apple のリファレンスUIImageWriteToSavedPhotosAlbum(image, self, nil, nil)だと思います)。ここ、またはドキュメント ディレクトリ (または任意のサブ フォルダー) に保存すると、ユーザーがそれらの画像を iCloud または iTunes にバックアップできるようになります。

画像は起動間で保持する必要があると述べているため、アプリケーションがメモリから削除されると、一時ディレクトリまたはキャッシュ ディレクトリが空になります (O/S が決定します)。

iOS ファイル システムの詳細

于 2012-07-24T14:20:34.123 に答える