问题
I'm using UIManagedDocument
to reading and writing to CoreData
. I have Document
class. This is a document from some tutorial:
.h
#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
Then in ViewController
i have NSURLConnection
:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
DataParser *parser = [[DataParser alloc] init];
[parser startParsingData:self.myMutableData withContext:self.moc];
}
and i open the document here:
-(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];
}];
}
}
Then i try to parse data:
-(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];
}
ant try to load it in core data after XML
parsing:
-(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";
}];
}
}
And i see the logs:
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.
So i assume that this should be in sqlite file, but when I try to read it is completely empty. awl
file have some bigger size, but persistentStore have 0 rows. Why?
回答1:
What happens when you launch the app a second time, can you see the data in your app?
In iOS 7, SQLite now has journaling turned on. I wonder if the journalling is causing a confusion (data is there but not in the sqlite file yet).
I would also question why you are using a UIManagedDocument
. It appears you are using Core Data in a Singleton pattern (which is bad) and then using UIManagedDocument
in that singleton pattern (worse).
UIManagedDocument
is intended for document based apps. You are probably running foul of some of the "automated" features inside of that class that would be easily cleared up if you built a standard Core Data stack instead.
You might consider turning Journaling off, adding a vacuum option to your NSPersistentStoreCoordinator
or switch to a standard Core Data stack.
回答2:
This is likely because of a new SQLite journal mode used in iOS 7. If you set it to the old mode as shown in the answer to the following SO question you should see your data again.
How to disable WAL journal mode
来源:https://stackoverflow.com/questions/21336404/coredata-uimanageddocument-and-empty-persistent-store