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, вы должны увидеть свои данные снова.

Как отключить режим журнала WAL

Другие вопросы по тегам