Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/95.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios NSFileCoordinator在sandbox Mac App Store应用程序中正确使用sqlite日志文件_Ios_Objective C_Cocoa_Sqlite_Nsfilecoordinator - Fatal编程技术网

Ios NSFileCoordinator在sandbox Mac App Store应用程序中正确使用sqlite日志文件

Ios NSFileCoordinator在sandbox Mac App Store应用程序中正确使用sqlite日志文件,ios,objective-c,cocoa,sqlite,nsfilecoordinator,Ios,Objective C,Cocoa,Sqlite,Nsfilecoordinator,由于sqlite执行事务的方式(使用wal或日志文件),我在将sqlite代码移植到应用商店时遇到了很多麻烦。苹果文档中的相关部分是: 您的应用程序需要能够打开或保存多个具有相同名称和不同扩展名的相关文件(例如,自动打开与电影文件同名的字幕文件,或允许使用SQLite日志文件)。要访问该辅助文件,请创建符合NSFilePresenter协议的类。此对象应提供主文件的URL作为其primaryPresentedItemURL属性,并应提供辅助文件的URL作为其presentedItemURL属性。

由于sqlite执行事务的方式(使用wal或日志文件),我在将sqlite代码移植到应用商店时遇到了很多麻烦。苹果文档中的相关部分是:

您的应用程序需要能够打开或保存多个具有相同名称和不同扩展名的相关文件(例如,自动打开与电影文件同名的字幕文件,或允许使用SQLite日志文件)。要访问该辅助文件,请创建符合NSFilePresenter协议的类。此对象应提供主文件的URL作为其primaryPresentedItemURL属性,并应提供辅助文件的URL作为其presentedItemURL属性。用户打开主文件后,file presenter对象应调用NSFileCoordinator类上的addFilePresenter:class方法来注册自身

Apple DTS为我提供了以下代码:

- (void)openSQLiteFileAtURL:(NSURL *)fileURL { 
    NSFileCoordinator *fc = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
    [fc coordinateReadingItemAtURL:fileURL options:0 error:NULL byAccessor:^(NSURL *newURL) {
        sqlite3 *db = NULL;
        char *zErrMsg = 0;

        [SQLiteRelatedItemPresenter addPresentersForURL:newURL];

        int rc = sqlite3_open_v2([[newURL path] fileSystemRepresentation], &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);

        NSLog(@"open %@ = %d", [newURL path], rc);

        rc = sqlite3_exec(db, "CREATE TABLE foo (col1 INTEGER);", callback, 0, &zErrMsg);
        if( rc!=SQLITE_OK ){
            NSLog(@"SQL error: %s\n", zErrMsg);
            sqlite3_free(zErrMsg);
        }

        // more sqlite code here

        sqlite3_close(db);

        }];
        return;
}
其中SQLiteRelatedItemPresenter是:

@interface SQLiteRelatedItemPresenter : NSObject <NSFilePresenter>
{
    NSURL *primaryPresentedItemURL;
    NSURL *presentedItemURL;
}

static NSOperationQueue *_presentedItemOperationQueue;

@implementation SQLiteRelatedItemPresenter

+ (void) initialize {
    [super initialize];
    if (_presentedItemOperationQueue == nil) {
        _presentedItemOperationQueue = [[NSOperationQueue alloc] init];
    }
}

+ (void)addPresentersForURL:(NSURL *)databaseURL {
    SQLiteRelatedItemPresenter *p1, *p2, *p3, *p4;

    p1 =[[SQLiteRelatedItemPresenter alloc] initWithFileURL:databaseURL prefix:nil suffix:@"-wal"];
    [NSFileCoordinator addFilePresenter:p1];
    p2 = [[SQLiteRelatedItemPresenter alloc] initWithFileURL:databaseURL prefix:nil suffix:@"-shm"];
    [NSFileCoordinator addFilePresenter:p2];
    p3 = [[SQLiteRelatedItemPresenter alloc] initWithFileURL:databaseURL prefix:nil suffix:@"-journal"];
    [NSFileCoordinator addFilePresenter:p3];
    p4 = [[SQLiteRelatedItemPresenter alloc] initWithFileURL:databaseURL prefix:@"." suffix:@"-conch"];
    [NSFileCoordinator addFilePresenter:p4];

    // +filePresenters will only return once the asynchronously added file presenters are done being registered
    [NSFileCoordinator filePresenters];
}

- initWithFileURL:(NSURL *)fileURL prefix:(NSString *)prefix suffix:(NSString *)suffix {
    self = [super init];
    if (self) {
        primaryPresentedItemURL = fileURL;
        NSString *path = [fileURL path];
        if (prefix) {
            NSString *name = [path lastPathComponent];
            NSString *dir = [path stringByDeletingLastPathComponent];
            path = [dir stringByAppendingPathComponent:[prefix stringByAppendingString:name]];
        }
        if (suffix) {
            path = [path stringByAppendingString:suffix];
        }
        presentedItemURL = [NSURL fileURLWithPath:path];
    }
    return self;
}

- (NSURL *)presentedItemURL {
    return presentedItemURL;
}

- (NSOperationQueue *)presentedItemOperationQueue {
    return _presentedItemOperationQueue;
}

- (NSURL *)primaryPresentedItemURL {
    return primaryPresentedItemURL;
}

看起来addPresentersForURL应该只调用一次(在OpenSqliteFileAtrol中),但由于沙盒权限错误,我无法拥有一个正常工作的应用程序。。。有什么帮助吗?

你有没有得到这个问题的答案?似乎与iOS开发人员相关现在我们将支持多个进程访问同一个SQLITE数据库进行扩展。@Ethan,MacOS X的概念是NSFilePresenter的主文件和辅助文件。在这种情况下,SQLite数据库可能是主数据库,但辅助数据库是日志文件。iOS没有主文件和辅助文件的概念,每个文件都需要自己的文件呈现程序来工作……或者将SQLite文件放在自己的目录中,并将呈现程序与目录一起使用。无论哪种方式,您都需要使用NSFileCoordinator和NSFilePresenter。否则糟糕的事情就会发生,不管是否有多个进程。
- openSQLiteFileAtURL:(NSURL *)databaseURL; // just open the db
- executeSQLStatement:(NSString *)sql; //perform read/write operations into the sqlite db previously opened in the openSQLiteFileAtURL method
- closeSQLite(); //close db method.