将sqlite数据库与iCloud同步

时间:2012-03-31 05:42:35

标签: ios5

我有我的sqlite数据库。现在我想与icloud同步。我读博客说不支持sqlite与icloud同步。要么去核心数据,要么“做核心数据到底做什么”。

现在我不可能去核心数据。所以像第二个选项“做类似于CoreData同步sqlite DB的方式:发送”事务日志“改为iCloud,并构建每个本地sqlite文件。”

请有人可以共享sqlite的“事务日志”的任何示例代码,或者可以逐步详细地expalin我需要做什么?

1 个答案:

答案 0 :(得分:18)

1)我按照这个链接创建了xml。你可以从它的github下载相应的api.Link是 - http://arashpayan.com/blog/2009/01/14/apxml-nsxmldocument-substitute-for-iphoneipod-touch/

2)点击按钮:

-(IBAction) btniCloudPressed:(id)sender
{
    // create the document with it’s root element
    APDocument *doc = [[APDocument alloc] initWithRootElement:[APElement elementWithName:@"Properties"]];
    APElement *rootElement = [doc rootElement]; // retrieves same element we created the line above

    NSMutableArray *addrList = [[NSMutableArray alloc] init];
    NSString *select_query;
    const char *select_stmt;
    sqlite3_stmt *compiled_stmt;
    if (sqlite3_open([[app getDBPath] UTF8String], &dbconn) == SQLITE_OK)
    {
        select_query = [NSString stringWithFormat:@"SELECT * FROM Properties"];
        select_stmt = [select_query UTF8String];
        if(sqlite3_prepare_v2(dbconn, select_stmt, -1, &compiled_stmt, NULL) == SQLITE_OK) 
        {
            while(sqlite3_step(compiled_stmt) == SQLITE_ROW) 
            {
                NSString *addr = [NSString stringWithFormat:@"%@",[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiled_stmt,0)]];
                addr = [NSString stringWithFormat:@"%@#%@",addr,[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiled_stmt,1)]];
                addr = [NSString stringWithFormat:@"%@#%@",addr,[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiled_stmt,2)]];
                addr = [NSString stringWithFormat:@"%@#%@",addr,[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiled_stmt,3)]];
                addr = [NSString stringWithFormat:@"%@#%@",addr,[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiled_stmt,4)]];
                addr = [NSString stringWithFormat:@"%@#%@",addr,[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiled_stmt,5)]];
                addr = [NSString stringWithFormat:@"%@#%@",addr,[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiled_stmt,6)]];
                addr = [NSString stringWithFormat:@"%@#%@",addr,[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiled_stmt,7)]];

                //NSLog(@"%@",addr);
                [addrList addObject:addr];
            }
            sqlite3_finalize(compiled_stmt);
        }
        else 
        {
            NSLog(@"Error while creating detail view statement. '%s'", sqlite3_errmsg(dbconn));
        }

    }

    for(int i =0 ; i < [addrList count]; i++)
    {
        NSArray *addr = [[NSArray alloc] initWithArray:[[addrList objectAtIndex:i] componentsSeparatedByString:@"#"]];

        APElement *property = [APElement elementWithName:@"Property"];
        [property addAttributeNamed:@"id" withValue:[addr objectAtIndex:0]];
        [property addAttributeNamed:@"street" withValue:[addr objectAtIndex:1]];
        [property addAttributeNamed:@"city" withValue:[addr objectAtIndex:2]];
        [property addAttributeNamed:@"state" withValue:[addr objectAtIndex:3]];
        [property addAttributeNamed:@"zip" withValue:[addr objectAtIndex:4]];
        [property addAttributeNamed:@"status" withValue:[addr objectAtIndex:5]];
        [property addAttributeNamed:@"lastupdated" withValue:[addr objectAtIndex:6]];
        [property addAttributeNamed:@"deleted" withValue:[addr objectAtIndex:7]];
        [rootElement addChild:property];
        [property release];

        APElement *fullscore = [APElement elementWithName:@"FullScoreReport"];
        [property addChild:fullscore];
        [fullscore release];
        select_query = [NSString stringWithFormat:@"SELECT AnsNo,Answer,AnswerScore,MaxScore,AnsIndex FROM FullScoreReport WHERE Addr_ID = %@",[addr objectAtIndex:0]];
        select_stmt = [select_query UTF8String];
        if(sqlite3_prepare_v2(dbconn, select_stmt, -1, &compiled_stmt, NULL) == SQLITE_OK) 
        {
            while(sqlite3_step(compiled_stmt) == SQLITE_ROW) 
            {
                APElement *answer = [APElement elementWithName:@"Answer"];
                [answer addAttributeNamed:@"AnsNo" withValue:[NSString stringWithFormat:@"%@",[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiled_stmt,0)]]];
                [answer addAttributeNamed:@"Answer" withValue:[NSString stringWithFormat:@"%@",[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiled_stmt,1)]]];
                [answer addAttributeNamed:@"AnswerScore" withValue:[NSString stringWithFormat:@"%@",[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiled_stmt,2)]]];
                [answer addAttributeNamed:@"MaxScore" withValue:[NSString stringWithFormat:@"%@",[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiled_stmt,3)]]];
                [answer addAttributeNamed:@"AnsIndex" withValue:[NSString stringWithFormat:@"%@",[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiled_stmt,4)]]];
                [fullscore addChild:answer];
                [answer release];
            }
            sqlite3_finalize(compiled_stmt);
        }
    }
    sqlite3_close(dbconn);


    NSString *prettyXML = [doc prettyXML];
    NSLog(@"\n\n%@",prettyXML);


    //***** PARSE XML FILE *****
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Properties.xml" ];
    NSData *file = [NSData dataWithBytes:[prettyXML UTF8String] length:strlen([prettyXML UTF8String])];
    [file writeToFile:path atomically:YES];


    NSString *fileName = [NSString stringWithFormat:@"Properties.xml"];
    NSURL *ubiq = [[NSFileManager defaultManager]URLForUbiquityContainerIdentifier:nil];
    NSURL *ubiquitousPackage = [[ubiq URLByAppendingPathComponent:@"Documents"]  URLByAppendingPathComponent:fileName];


    MyDocument *mydoc = [[MyDocument alloc] initWithFileURL:ubiquitousPackage];
    mydoc.xmlContent = prettyXML;
    [mydoc saveToURL:[mydoc fileURL]forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) 
     {

         if (success) 
         {
             NSLog(@"XML: Synced with icloud");
             UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"iCloud Syncing" message:@"Successfully synced with iCloud." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
             [alert show];
             [alert release];



         }
         else
             NSLog(@"XML: Syncing FAILED with icloud");


     }];

}

3)MyDocument.h文件

#import <UIKit/UIKit.h>

@interface MyDocument : UIDocument
    @property (strong) NSString *xmlContent;
@end

4)MyDocument.m文件

#import "MyDocument.h"

@implementation MyDocument
@synthesize xmlContent,zipDataContent;

// Called whenever the application reads data from the file system
- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError **)outError
{
    // NSLog(@"* ---> typename: %@",typeName);
                self.xmlContent = [[NSString alloc] 
                               initWithBytes:[contents bytes] 
                               length:[contents length] 
                               encoding:NSUTF8StringEncoding]; 

    [[NSNotificationCenter defaultCenter] postNotificationName:@"noteModified" object:self];
    return YES;     
}

// Called whenever the application (auto)saves the content of a note
- (id)contentsForType:(NSString *)typeName error:(NSError **)outError 
{

        return [NSData dataWithBytes:[self.xmlContent UTF8String] length:[self.xmlContent length]];

}

@end

5)现在在你的appdelegate

- (void)loadData:(NSMetadataQuery *)queryData
 {


    for (NSMetadataItem *item in [queryData results]) 
    {    
        NSString *filename = [item valueForAttribute:NSMetadataItemDisplayNameKey];
        NSNumber *filesize = [item valueForAttribute:NSMetadataItemFSSizeKey]; 
        NSDate *updated = [item valueForAttribute:NSMetadataItemFSContentChangeDateKey];
        NSLog(@"%@ (%@ bytes, updated %@) ", filename, filesize, updated);

        NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
        MyDocument *doc = [[MyDocument alloc] initWithFileURL:url];
        if([filename isEqualToString:@"Properties"])
        {
            [doc openWithCompletionHandler:^(BOOL success) {
                if (success) {
                    NSLog(@"XML: Success to open from iCloud");
                    NSData *file = [NSData dataWithContentsOfURL:url];
                    //NSString *xmlFile = [[NSString alloc] initWithData:file encoding:NSASCIIStringEncoding];
                    //NSLog(@"%@",xmlFile);

                    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:file];
                    [parser setDelegate:self];
                    [parser parse];
                    //We hold here until the parser finishes execution
                    [parser release];
                }
                else 
                {
                    NSLog(@"XML: failed to open from iCloud");
                 }
            }]; 
        }
}
}

6)现在在解析器方法中获取数据并根据需要在数据库中插入/更新。

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)nameSpaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqual:@"Property"])
    {
        NSLog(@"Property attributes : %@|%@|%@|%@|%@|%@|%@|%@", [attributeDict objectForKey:@"id"],[attributeDict objectForKey:@"street"], [attributeDict objectForKey:@"city"], [attributeDict objectForKey:@"state"],[attributeDict objectForKey:@"zip"],[attributeDict objectForKey:@"status"],[attributeDict objectForKey:@"lastupdated"],[attributeDict objectForKey:@"deleted"]);
}
//like this way fetch all data and insert in db
}