CoreData, UIManagedDocument и пустое постоянное хранилище
Я использую UIManagedDocument
читать и писать CoreData
, я имею Document
учебный класс. Это документ из некоторого учебника:
.час
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
typedef void (^OnDocumentReady) (UIManagedDocument *document);
@interface Document : NSObject
@property (strong, nonatomic) UIManagedDocument *document;
+ (Document *)sharedDocument;
- (void)performWithDocument:(OnDocumentReady)onDocumentReady;
@end
.m
@interface Document ()
- (void)objectsDidChange:(NSNotification *)notification;
- (void)contextDidSave:(NSNotification *)notification;
@end;
@implementation Document
@synthesize document = _document;
static Document*_sharedInstance;
+ (Document *)sharedDocument
{
static dispatch_once_t once;
dispatch_once(&once, ^{
_sharedInstance = [[self alloc] init];
});
return _sharedInstance;
}
- (id)init {
self = [super init];
if (self) {
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:@"Document"];
self.document = [[UIManagedDocument alloc] initWithFileURL:url];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
self.document.persistentStoreOptions = options;
// Register for notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(objectsDidChange:)
name:NSManagedObjectContextObjectsDidChangeNotification
object:self.document.managedObjectContext];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contextDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:self.document.managedObjectContext];
}
return self;
}
- (void)performWithDocument:(OnDocumentReady)onDocumentReady
{
void (^OnDocumentDidLoad)(BOOL) = ^(BOOL success) {
onDocumentReady(self.document);
};
if (![[NSFileManager defaultManager] fileExistsAtPath:[self.document.fileURL path]]) {
[self.document saveToURL:self.document.fileURL
forSaveOperation:UIDocumentSaveForCreating
completionHandler:OnDocumentDidLoad];
} else if (self.document.documentState == UIDocumentStateClosed) {
[self.document openWithCompletionHandler:OnDocumentDidLoad];
} else if (self.document.documentState == UIDocumentStateNormal) {
OnDocumentDidLoad(YES);
}
}
- (void)objectsDidChange:(NSNotification *)notification
{
#ifdef DEBUG
NSLog(@"NSManagedObjects did change.");
#endif
}
- (void)contextDidSave:(NSNotification *)notification
{
#ifdef DEBUG
NSLog(@"NSManagedContext did save.");
#endif
}
@end
Затем в ViewController
я имею NSURLConnection
:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
DataParser *parser = [[DataParser alloc] init];
[parser startParsingData:self.myMutableData withContext:self.moc];
}
и я открываю документ здесь:
-(void)initDocument {
if (!self.moc) {
[[Document sharedDocument] performWithDocument:^(UIManagedDocument *document) {
self.moc = document.managedObjectContext;
[[NSNotificationCenter defaultCenter] postNotificationName:UIDocumentStateChangedNotification object:self];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"someURL"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60];
[NSURLConnection connectionWithRequest:request delegate:self];
}];
}
}
Затем я пытаюсь разобрать данные:
-(void)startParsingData:(NSData*)data withContext:(NSManagedObjectContext*)context {
self.moc = context;
self.startDate = [NSDate date];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
parser.delegate = self;
[parser parse];
}
Муравей пытается загрузить его в основные данные после XML
синтаксический анализ:
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if([elementName isEqualToString:@"Item"]) {
[self.moc performBlockAndWait:^{
TestEntity *te = [NSEntityDescription insertNewObjectForEntityForName:@"TestEntity" inManagedObjectContext:self.moc];
te.surname = @"5433fds";
te.name = @"5342fdsfsd";
}];
}
}
И я вижу журналы:
2014-01-24 16:21:21.692 Ce[85149:70b] NSManagedObjects did change.
2014-01-24 16:21:36.696 Ce[85149:70b] NSManagedContext did save.
Поэтому я предполагаю, что это должно быть в файле sqlite, но когда я пытаюсь прочитать, он полностью пуст. awl
Файл имеет больший размер, но persistentStore имеет 0 строк. Зачем?
2 ответа
Что происходит, когда вы запускаете приложение во второй раз, видите ли вы данные в своем приложении?
В iOS 7 в SQLite теперь включено ведение журналов. Интересно, не приводит ли путаница к путанице (данные есть, но пока нет в файле sqlite).
Я также хотел бы спросить, почему вы используете UIManagedDocument
, Похоже, вы используете Core Data в шаблоне Singleton (что плохо), а затем используете UIManagedDocument
в этом единственном образце (хуже).
UIManagedDocument
предназначен для приложений на основе документов. Вы, вероятно, нарушаете некоторые "автоматизированные" функции внутри этого класса, которые легко очистить, если вместо этого вы построите стандартный стек Core Data.
Вы можете отключить ведение журнала, добавив вакуумную опцию к NSPersistentStoreCoordinator
или переключитесь на стандартный стек основных данных.
Это, вероятно, из-за нового режима журнала SQLite, используемого в iOS 7. Если вы установите его в старом режиме, как показано в ответе на следующий вопрос SO, вы должны увидеть свои данные снова.