У меня очень странная ошибка, которую я пытаюсь отслеживать несколько дней. Я сохраняю данные состояния для игры в файле в каталоге Документов приложения.NSKeyedArchiver Проблема, когда приложение загружается с iTunes через TestFlight
Все работало нормально до недавнего обновления iOS (не совсем точно, где-то около 9,0). Внезапно данные не архивируются/не сортируются правильно.
Странная часть кода работает нормально, когда я запускаю ее с Xcode с iPad, привязанным к моему MAC или когда в эмуляторе. Когда я загружаю приложение из iTunes с помощью TestFlight, он больше не работает. Это затрудняет отладку.
Я проверил и дважды проверил все, я использую URL-путь, добавлен код улавливания ошибок и т. Д., Но архивирование не работает корректно, когда приложение установлено из iTunes через TestFlight.
В крайнем случае я добавил новый код, который архивирует мой объект, сразу же распаковывает его в другую переменную, а затем отображает некоторые данные в метке. Получаемый объект содержит нулевые данные.
Исключения не выбрасываются.
Чтобы повторить, код не работает ТОЛЬКО при установке приложения из iTunes.
Это код фрагмента;
NSString *documentDirectory = [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] path];
NSString* filePath = [documentDirectory stringByAppendingPathComponent:@"playerTest.data"];
LBYPlayerData* pd1 = [[LBYPlayerData alloc ]init];
pd1.currentCountryID = 1;
pd1.lsn = @"123.456";
BOOL success = [NSKeyedArchiver archiveRootObject:pd1 toFile:filePath];
NSAssert(success, @"archiveRootObject failed");
LBYPlayerData* pd2 = nil;
@try {
pd2 = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
} @catch (NSException *exception) {
playerDataLabel.text = [NSString stringWithFormat:@"%@",exception.name];
playerUndoDataLabel.text = [NSString stringWithFormat:@"%@",exception.description];
} @finally {
NSAssert((pd2 != nil), @"archivePlayerDataUndo failed to unarchive");
playerDataLabel.text = [NSString stringWithFormat:@"path: %@",filePath];
playerUndoDataLabel.text = [NSString stringWithFormat:@"Undo Country:%li LSN:%@",(long)pd2.currentCountryID,pd2.lsn];
}
Вот модель данных
//
// LBYPlayerData.h
#import <Foundation/Foundation.h>
@interface LBYPlayerData : NSObject
@property (nonatomic,readonly) BOOL isNewGame;
@property (nonatomic) NSInteger playerID;
@property (nonatomic) NSInteger usCardIdx;
@property (nonatomic) NSInteger drawDeckIdx;
@property (nonatomic) NSInteger discardDeckIdx;
@property (nonatomic) NSInteger removeDeckIdx;
@property (nonatomic) NSInteger currentCountryID;
@property (nonatomic) NSString* lsn;
@property (nonatomic) NSString* build;
@end
//
// LBYPlayerData.m
#import "LBYPlayerData.h"
@implementation LBYPlayerData
-(id)init
{
self = [super init];
_isNewGame = YES;
return self;
}
-(void)encodeWithCoder:(NSCoder *)aCoder
{
// NSLog(@"Saving Player Data");
_isNewGame = NO;
[aCoder encodeBool:_isNewGame forKey: NSStringFromSelector(@selector(isNewGame))];
[aCoder encodeInt64:_playerID forKey: NSStringFromSelector(@selector(playerID))];
[aCoder encodeInt64:_usCardIdx forKey: NSStringFromSelector(@selector(usCardIdx))];
[aCoder encodeInt64:_drawDeckIdx forKey: NSStringFromSelector(@selector(drawDeckIdx))];
[aCoder encodeInt64:_discardDeckIdx forKey: NSStringFromSelector(@selector(discardDeckIdx))];
[aCoder encodeInt64:_removeDeckIdx forKey: NSStringFromSelector(@selector(removeDeckIdx))];
[aCoder encodeInt64:_currentCountryID forKey: NSStringFromSelector(@selector(currentCountryID))];
[aCoder encodeObject:_lsn forKey: NSStringFromSelector(@selector(lsn))];
[aCoder encodeObject:_build forKey: NSStringFromSelector(@selector(build))];
// NSLog(@"Current Counry: %li",(long)_currentCountryID);
}
-(id)initWithCoder:(NSCoder *)aDecoder
{
// NSLog(@"Loading Player Data");
self = [self init];
if (self) {
_isNewGame =[aDecoder decodeBoolForKey:NSStringFromSelector(@selector(isNewGame))];
[self setPlayerID :[aDecoder decodeIntegerForKey:NSStringFromSelector(@selector(playerID))]];
[self setUsCardIdx :[aDecoder decodeIntegerForKey:NSStringFromSelector(@selector(usCardIdx))]];
[self setDrawDeckIdx :[aDecoder decodeIntegerForKey:NSStringFromSelector(@selector(drawDeckIdx))]];
[self setDiscardDeckIdx :[aDecoder decodeIntegerForKey:NSStringFromSelector(@selector(discardDeckIdx))]];
[self setRemoveDeckIdx :[aDecoder decodeIntegerForKey:NSStringFromSelector(@selector(removeDeckIdx))]];
[self setCurrentCountryID:[aDecoder decodeIntegerForKey:NSStringFromSelector(@selector(currentCountryID))]];
[self setLsn :[aDecoder decodeObjectForKey :NSStringFromSelector(@selector(lsn))]];
[self setBuild :[aDecoder decodeObjectForKey :NSStringFromSelector(@selector(build))]];
}
return self;
}
@end
'NSAssert' будет отключен в выпуске Release, а описания' NSException', назначенные для меток, всегда будут перезаписаны оператором '@ finally'. Поэтому я не вижу никакой информации о проблеме. – mmtootmm
NSAssert, похоже, проблема. Я нашел код, который сделал вызов функции, которая заархивировала файл внутри инструкции NSAssert. Благодарю. Это сводило меня с ума. – JVC