i'm working on an iPhone application which retrieve sqlite database from server through json/rest api. And user can add rows to its tables locally and can update it locally. Now, as i added some rows to tables in local database, i want to sync/insert only those new rows to server database from my local updated db. Please help if somebody knows about that api method(json/rest) or If there is any tutorial related to it please help.
问题:
回答1:
When you say you are retrieving the "sqlite" database, do you mean a "json" representation of all the tables and their rows? I'm assuming you're not actually sending the "sqlite" db file.
For sending and retrieving json via http you can use NSURLConnection and NSURLRequest for simplicity, because they are built in. If you want to enforce a mapping to core data, you can use the RestKit framework for both the connection and data handling.
Here is an example implementation of the former solution - it assumes you are ARC, you will need to add the appropriate retain and release statements otherwise.
1) declare the class you're using as the appropriate delegate
@interface ClassName : NSObject <NSURLConnectionDelegate>
2) declare a responseData object that will be used to receive data
//interface
@property (nonatomic, strong) NSMutableData *responseData;
//implementation
@synthesize responseData;
3) create the function that sends the json request
- (void)sendRequest
{
responseData = [NSMutableData data];
//whatever your server address is
NSURL *url = [NSURL URLWithString:@"http://www.resturl.com/whatever"];
//just sample data - create this dictionary with what you want to send
NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
[params setObject:@"SomeValue" forKey:@"SomeKey"];
NSError *jsonError;
//NSJSONSerialization is Apple's new json serialization class so we can use it to convert to and from json and foundation objects
NSData *requestdata = [NSJSONSerialization dataWithJSONObject:params options:0 error:&jsonError];
NSMutableURLRequest *request;
request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
[request setValue:[NSString stringWithFormat:@"%d", [requestdata length]] forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:requestdata];
//this kicks off the request asynchronously
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
//if you'd rather send a synchronous request, you can use the static NSURLConnection function
//sendSynchronousRequest:returningResponse:error:
}
4)implement the delegate functions to receive our data
//any time a piece of data is received we will append it to the responseData object
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.responseData appendData:data];
}
//some sort of error, you can print the error or put in some other handling here, possibly even try again but you will risk an infinite loop then unless you impose some sort of limit
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
// Clear the activeDownload property to allow later attempts
self.responseData = nil;
}
//connection has finished, thse requestData object should contain the entirety of the response at this point
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSError *jsonError;
NSDictionary *responseDict =
[NSJSONSerialization JSONObjectWithData:responseData
options:NSJSONWritingPrettyPrinted
error:&jsonError];
if(responseDict)
{
NSLog(@"%@", responseDict);
}
else
{
NSLog(@"%@", [jsonError description]);
}
//clear out our response buffer for future requests
self.responseData = nil;
}
If you want to update the remote database with some new information, just keep track of the new rows locally (rather than just merging them with the full dataset) and send a new request containing only those rows to an endpoint that will add them. That is the simplest way to do this without enforcing an actual mapping.