Сохранение в NSDocumentDirectory или NSCachesDirectory

Попробовали хранить объект NSUserDefaults для NSUserDefaults но не повезло. Мой NSMutableArray содержит этот журнал прямо здесь:

 `ALAsset - Type:Photo, URLs:assets-library://asset/asset.JPG?id=92A7A24F-D54B-496E-B250-542BBE37BE8C&ext=JPG` 

Я знаю, что его ALAsset object , в AGImagePickerController он сравнивается как NSDictionary, поэтому мне нужно было сохранить NSDictionary или массив, в котором я использовал, где я ALAsset object затем сохраняю его в NSDocu или NSCaches как файл, а затем вернуть его (это была моя идея).

Но проблема в том, что я пробовал этот код, но не работал, и ничего не показываю в NSDocu или NSCache .

Первая попытка ( info – это та, которая содержит ALAsset object ):

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil; NSString *filePath = [basePath stringByAppendingPathComponent:@"filename.plist"]; NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfURL:filePath]; NSString *error; NSData *plistData = [NSPropertyListSerialization dataFromPropertyList:plistDict format:NSPropertyListXMLFormat_v1_0 errorDescription:&error]; if(plistData) { [info writeToFile:filePath atomically:YES]; } else { NSLog(error); } 

Вторая попытка :

 - (NSString *)createEditableCopyOfFileIfNeeded:(NSString *)_filename { // First, test for existence. BOOL success; NSFileManager *fileManager = [NSFileManager defaultManager]; NSError *error; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *writableFilePath = [documentsDirectory stringByAppendingPathComponent: _filename ]; success = [fileManager fileExistsAtPath:writableFilePath]; if (success) return writableFilePath; // The writable file does not exist, so copy the default to the appropriate location. NSString *defaultFilePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: _filename ]; success = [fileManager copyItemAtPath:defaultFilePath toPath:writableFilePath error:&error]; if (!success) { NSLog([error localizedDescription]); NSAssert1(0, @"Failed to create writable file with message '%@'.", [error localizedDescription]); } return writableFilePath; } 

Сохраните это так:

  NSString *writableFilePath = [self createEditableCopyOfFileIfNeeded:[NSString stringWithString:@"hiscores"]]; if (![info writeToFile:writableFilePath atomically:YES]){ NSLog(@"WRITE ERROR"); } 

Третья попытка :

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *filePath = [documentsDirectory stringByAppendingPathComponent:??????]; [info writeToFile:filePath atomically:YES]; 

Четвертая попытка (Невозможно из-за ее модификации в приложении): https://stackoverflow.com/a/6311129/1302274

Есть ли другой способ? Надеюсь, кто-то будет вести меня.

3 Solutions collect form web for “Сохранение в NSDocumentDirectory или NSCachesDirectory”

Вы можете сохранить свой NSMutableArray в NSUserDefault, заархивировав его в NSData, а затем извлекая его, отправив его обратно в NSMutableArray.

 -(NSData*) getArchievedDataFromArray:(NSMutableArray*)arr { NSData *data = [NSKeyedArchiver archivedDataWithRootObject:arr]; return data; } -(NSMutableArray*) getArrayFromArchievedData:(NSData*)data { NSMutableArray *arr = [NSKeyedUnarchiver unarchiveObjectWithData:data]; return arr; } 

Для сохранения массива в NSUserDefault:

  [[NSUserDefaults standardUserDefaults] setObject:[self getArchievedDataFromArray: yourArray] forKey:@"YourKey"]; [[NSUserDefaults standardUserDefaults] synchronize]; 

Для получения массива из NSUserDefault:

 NSMutableArray *yourArray = [self getArrayFromArchievedData:[[NSUserDefaults standardUserDefaults]objectForKey:@"YourKey"]]; 

Также вы можете сохранить Array в виде NSData в файл в NSDocumentDirectory или NSCachesDirectory. Надеюсь это поможет….

Отредактировано: категория UIImage + NSCoding

файл .h

 #import <UIKit/UIKit.h> @interface UIImage (NSCoding) - (id) initWithCoderForArchiver:(NSCoder *)decoder; - (void) encodeWithCoderForArchiver:(NSCoder *)encoder ; @end 

.m файл

 #import "UIImage+NSCoding.h" #import <objc/runtime.h> #define kEncodingKey @"UIImage" @implementation UIImage (NSCoding) + (void) load { @autoreleasepool { if (![UIImage conformsToProtocol:@protocol(NSCoding)]) { Class class = [UIImage class]; if (!class_addMethod( class, @selector(initWithCoder:), class_getMethodImplementation(class, @selector(initWithCoderForArchiver:)), protocol_getMethodDescription(@protocol(NSCoding), @selector(initWithCoder:), YES, YES).types )) { NSLog(@"Critical Error - [UIImage initWithCoder:] not defined."); } if (!class_addMethod( class, @selector(encodeWithCoder:), class_getMethodImplementation(class, @selector(encodeWithCoderForArchiver:)), protocol_getMethodDescription(@protocol(NSCoding), @selector(encodeWithCoder:), YES, YES).types )) { NSLog(@"Critical Error - [UIImage encodeWithCoder:] not defined."); } } } } - (id) initWithCoderForArchiver:(NSCoder *)decoder { if (self = [super init]) { NSData *data = [decoder decodeObjectForKey:kEncodingKey]; self = [self initWithData:data]; } return self; } - (void) encodeWithCoderForArchiver:(NSCoder *)encoder { NSData *data = UIImagePNGRepresentation(self); [encoder encodeObject:data forKey:kEncodingKey]; } @end 

Документация NSArray для метода writeToFile: atomically: показывает, что все члены должны быть объектами списка свойств. ALAsset не является объектом списка свойств, поэтому запись этого файла не будет работать.

Я знаю, что его объект ALAsset, в AGImagePickerController сравнивается как NSDictionary

Если бы вы внимательно посмотрели, вы бы увидели, что он не сравнивает ALAsset, а их свойство «ALAssetPropertyURLs». Значение этого свойства является NSDictionary.

Поскольку у ALAsset нет публичного конструктора, вы не можете его восстановить после чтения из файла или NSUserDefaults, даже если вам удастся его написать.

Поэтому самое лучшее, что вы можете сделать, это повторно извлечь ALAssets из источника, из которого вы изначально их получили. Я предполагаю, что это ALAssetsGroup? Вместо сохранения в файл и повторного поиска, почему бы вам просто не восстановить их с тем же запросом в ALAssetsGroup, как вы изначально использовали для их создания?

EDIT :

Итак, вы говорите, что у вас есть оригинальный ALAset от AGImagePickerController. Чтобы сохранить их, вы можете взять рекомендации Matej в комментариях и сохранить URL-адреса, которые их идентифицируют.

Но имейте в виду, что AGImagePickerController – это средство для пользователя, чтобы выбрать несколько фотографий, а затем сделать что-то с ними . То есть, ALAssets – это просто промежуточные результаты, указывающие на исходные местоположения фотографий. Если вы сохраните URL-адрес и получите их позже, нет никакой гарантии, что оригиналы все еще существуют.

Поэтому спросите себя: что вы хотите, чтобы пользователь делал с фотографиями, и сохраните результат этого действия, а не сами активы. Например, одно разумное действие, которое вы можете сделать, – создать новую ALAssetGroup (с помощью метода addAssetsGroupAlbumWithName: ALAssetsLibrary) и сохранить там активы. ALAssetGroups автоматически сохраняются, поэтому вам не нужно ничего делать самостоятельно.

EDIT 2 – после получения дополнительной информации от OP

То, что Matej намекает в комментариях, состоит в том, чтобы преобразовать массив ALAssets, который у вас есть, в массив словарей, извлекая URL-адреса из активов. Как вы можете прочитать в документации класса ALAsset, вы можете сделать это следующим образом:

 NSArray *assetArray = // your array of ALAssets NSMutableArray *urls = [NSMutableArray arrayWithCapacity:assetArray.count]; for( ALAsset *asset in assetArray ) { NSDictionary *urlDictionary = [asset valueForProperty:@"ALAssetPropertyURLs"]; [urls addObject:urlDictionary]; } 

Результирующий массив словарей, которые вы можете сохранить любым способом.

После перезапуска вашего приложения вы читаете массив словарей назад, откуда вы его сохранили. Затем Matej предлагает использовать активную базу данных assetForURL:resultBlock:failureBlock: воссоздать ALAssets. Но, как мы теперь знаем, вы хотите снова поставить галочку на исходные активы, лучше получить исходный массив ALAssets и проверить, присутствует ли какой-либо из них в восстановленных URL-адресах. Для этого должны работать следующие:

 NSArray *assetArray = // the full array of ALAssets from AGImagePickerController NSArray *urls = // the recovered array of NSDictionaries for( ALAsset *asset in assetArray ) { NSDictionary *urlDictionary = [asset valueForProperty:@"ALAssetPropertyURLs"]; if( [urls containsObject:urlDictionary] ) { ... // set checkmark on asset } } 

Это предполагает, что первоначальные активы не изменились, что не под вашим контролем (например, пользователь удалил / добавил фотографии).

Это метод, который я использую для хранения объектов массива или словаря.

 - (NSArray*)readPlist { NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); NSString *plistPath = [[documentPaths lastObject] stringByAppendingPathComponent:@"filename.plist"]; NSFileManager *fMgr = [NSFileManager defaultManager]; if (![fMgr fileExistsAtPath:plistPath]) { [self writePlist:[NSArray array]]; } return [NSArray arrayWithContentsOfFile:plistPath]; } - (void)writePlist:(NSArray*)arr { NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); NSString *plistPath = [[documentPaths lastObject] stringByAppendingPathComponent:@"filename.plist"]; NSFileManager *fMgr = [NSFileManager defaultManager]; if ([fMgr fileExistsAtPath:plistPath]) [fMgr removeItemAtPath:plistPath error:nil]; [arr writeToFile:plistPath atomically:YES]; } 
  • Перетасовка массива в объекте-c
  • Быстрое изменение языка на лету
  • Индекс, такой как приложение для контактов iOS
  • Как я могу сделать снимок UIView, который не отображается?
  • CIFaceFeature trackingID всегда подходит для нескольких лиц
  • Как отправлять параметры с помощью MonoTouch.ObjCRuntime.Selector и Perform Selector
  • Как добавить индикатор в UIImagePickerController
  • Скрыть кнопку в панели навигации в iPhone sdk
  • Ошибка файла Info.plist "no such file"
  • Стоит ли продолжать поддерживать iOS 4.x при выпуске iOS 6?
  • Не удается проверить / развернуть устройство iPhone? Я получаю «Command / usr / bin / codesign failed with exit code 1»
  • Interesting Posts

    Воспроизведение звука UILocalNotification, когда приложение находится в фоновом режиме и не отключено.

    Приобретите диалог «Приложение будет использовать ваше текущее местоположение» снова

    Как изменить общий цвет оттенков на iOS 9?

    Можно ли отличать HTTP-запросы, сделанные через 3G от других запросов

    Автозапуск iOS 7, встроенный в прокрутку

    RestKit: как получить простой массив строк JSON?

    Попытка создать IOS WKWebView с размером, меньшим, чем экран, программным способом

    Цвет фона метки удаляется при выборе строки в Swift

    drawInRect: потеря качества изображения

    Преобразование Unicode (например, 1f564) в Emoji в Swift

    Цель C: Объект Разделен, пока наблюдатели с ключевыми значениями все еще зарегистрированы с ним

    AFNetworking не возобновляет загрузку

    dyld: библиотека не загружена: @ rpath / libswiftCore.dylib. Проблема сохраняется

    дублирующие символы для архитектуры i386

    Xcode всегда останавливается на main.m после сбоя

    PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.