Updating sqlite database without XML

前端 未结 4 923
梦如初夏
梦如初夏 2020-12-11 05:00

My app requires data from a sqlite database. It will ship with a version of this database, but I need to update it on a regular basis (most likely once a month). Typically

相关标签:
4条回答
  • 2020-12-11 05:37

    I think your problem stems from requiring authentication with your server.

    I recommend the popular AFNetworking library for help with making HTTP calls. You'd subclass AFHTTPClient in order to provide your authentication details, as in this answer.

    Then in your case, you can use AFXMLRequestOperation to download your XML directly. You may then write it to disk. Note you will need to read over the iOS Data Storage Guidelines to see if the Documents folder is appropriate for your use (which I don't think it is; Caches would probably be better).

    Now, the reason your ExampleDelegate code (which looks like it came from here) doesn't work is that ExampleDelegateSuccess and ExampleDelegateFailure are block types, so you can't pass your NSData and NSError * pointers. You need to provide block objects that conform to the signature of the respective types.

    For example:

    ExampleDelegate *download = [[ExampleDelegate alloc] init];
    [download fetchURL:url 
              withCompletion:^(NSData *thedata) {
        NSLog(@"Success! Data length: %d", theData.length);
    
        // Delete old database
        NSError *error;
    
        // You need to declare 'app' here so you can use it in the line below.
        NSURL *destination = [app applicationDocumentsDirectory];
        destination = [destination URLByAppendingPathComponent:@"myDatabase"];
        destination = [destination URLByAppendingPathExtension:@"sqlite"];
        NSLog(@"destination = %@",destination);
        [[NSFileManager defaultManager] removeItemAtPath:[destination path] error:&error];
    
        // Save into correct location
        BOOL success = [fileData writeToURL:destination atomically:YES];
        NSLog(@"File written successfully? %d", success);
    } 
              failure:^(NSError *theError){ 
        NSLog(@"Failure: %@", [theError localizedDescription]}
    ];
    

    The blocks will provide you with the NSData and NSError instances as required, so you don't need to declare your own. You can learn more about blocks here.

    Hope that helps :D

    0 讨论(0)
  • 2020-12-11 05:39

    I ultimately ended up using AFNetworking to solve my problem, as suggested by @silver_belt. I was able to do it without subclassing AFHTTPClient though (see my answer here, which I posted as a follow up to this question).

    In the end, I just had to #include "AFHTTPRequestOperation.h" in my view controller's .h file, then in the .m I used

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"ftp://myUsername:myPassword@www.mysite.net/myfile.sqlite"]];
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    NSURL *path = [[[app applicationDocumentsDirectory] URLByAppendingPathComponent:@"myfile"] URLByAppendingPathExtension:@"sqlite"];
    operation.outputStream = [NSOutputStream outputStreamWithURL:path append:NO];
    
    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
        {
            NSLog(@"Successfully downloaded file to path: %@",path);
        }
                                     failure:^(AFHTTPRequestOperation *operation, NSError *error)
        {
            NSLog(@"Error in AFHTTPRequestOperation in clickedButtonAtIndex on FlightInfoController.m");
            NSLog(@"%@",error.description);
        }];
    
    [operation start];
    

    when I actually wanted to start my download. Hope this will make it easier for anyone looking to do this in the future!

    0 讨论(0)
  • 2020-12-11 05:41

    We have large databases that we regularly update. I'm not sure how "large" is large, but we are updating megabytes of data. We Update ours as JSON data. JSON is a little less overhead than XML, and there are lots of readily available libraries (like JSONKit). Some of our users have poor data connections, and sometimes difficulties ensue.

    We have been testing different ways of updating. One method breaks the data into multiple JSON files. Each of the files are downloaded separately, and they are then stored separately. One advantage over using multiple files, is that if one fails, you only need to resend that particular file.

    Also, we use multiple threads to process up to 5 requests/downloads at a time. This requires much more management, but helps us give a better experience to the user. AFHTTPClient is really good at dealing with this stuff. I'd hate to not use it.

    0 讨论(0)
  • 2020-12-11 05:51

    Is it a completely new / distinct database each time, or is an updated version of the same database?

    If the latter, have you considered sending only the changes (either via an explicit list of adds/updates/deletes, or using something like Zumero to automate the updates)?

    0 讨论(0)
提交回复
热议问题