How to backup and restore sqlite3 file from iOS app - ios

I plan to develop a Point of Sales system, and intend to use sqlite3 as the database. After few days research, I can't find any tutorial or example on backup or restore sqlite3 database. The solution I can accept is either upload to cloud or dropbox.

Try this answer.
Creating Backup & Restoring file using Dropbox
Follow the steps that appears in Dropbox integration for your iOS App.
First, Get your local db path as given below:
NSArray *docsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath = [docsDirectory objectAtIndex:0];
databasePath = [docPath stringByAppendingPathComponent:#"filename.sqlite"];
NSLog(#"db path -> %#",databasePath);
Then Upload that file to dropbox as following:
NSString *fileName = #"filename.sqlite";
NSString *destDir = #"/";
if (appDelegateObj.parentRevId == nil)
{
//Uploads a fresh file.
[appDelegateObj.restClientObj uploadFile:fileName toPath:destDir withParentRev:nil fromPath:databasePath];
}
else
{
// Uploads a file with already existing file
[appDelegateObj.restClientObj uploadFile:fileName toPath:destDir withParentRev:appDelegateObj.parentRevId fromPath:databasePath];
}
Here, parentRevId is for identifier of existing file.
You can get the parentRevId from Dropbox delegate method.
And then Restore the dropbox file to your local db path as following:
if (appDelegateObj.parentRevId == NULL) // No such File found
{
[SVProgressHUD showErrorWithStatus:#"No Data in Dropbox" maskType:SVProgressHUDMaskTypeBlack]; // Activity Indicator
}
else
{
NSString *destDir = #"/filename.sqlite";
[appDelegateObj.restClientObj loadFile:destDir intoPath:databasePath];
}
restClientObj is the object of DBRestClient (Dropbox)

Related

Is document directory path constant for iOS device?

I am saving video/image in document directory.Now once the image is saved in document directory I want to save its reference in my local database.So I am thinking I can save URL of the image in the local database.
So is it constant throughout my app?
It's not constant, i have observed every time you launch the app it'll be different, but your data is moved to this new path. You can save your file name in your database, and dynamically append this file name to NSDocument directory.
- (NSString *)documentsFilePath:(NSString *)fileName {
NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = [dirPaths firstObject];
NSString *filePath = [docsDir stringByAppendingPathComponent:fileName];
return filePath;
}
- (void)storeFile:(NSString *)fileName {
NSString *filePath = [self documentsFilePath:fileName];
// create if needed
if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
// Write your data to file system here...
}
}
- (void)deleteFile:(NSString *)fileName {
NSString *filePath = [self documentsFilePath:fileName];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
NSError *deleteErr = nil;
[[NSFileManager defaultManager] removeItemAtPath:filePath error:&deleteErr];
if (deleteErr) {
NSLog(#"Can't delete %#: %#", filePath, deleteErr);
}
}
}
Please handle nil checks and store only filename in DB
No, it's not constant. Whenever your app reinstall or updated on device the document directory will change, because when app installed on device os made an directory for app with some random id and each install this random it get changed by OS.
So, you need to make it dynamic own your own, like store the file name only and append the document directory path while using it.
I would suggest only saving the filename or subdirectory/filename (if you have a subdirectory) in the database and then only attaching that to the NSDocumentDirectory.
This will ensure that you always know where the file is...
NSDocumentDirectory is however consistent accross updates, so the files should remain in the document directory even if you update...

What is the hexadecimal part in the Documents folder's path?

I have a file located in my app's Documents folder. When the app is terminated I save the file's URL in the AppDelegate's applicationWillTerminate method:
// archiver init code
[archiver encodeObject:file.URL forKey:kFileURL];
// finish encoding and write data to file system
But when trying to restore the file on the next app launch the file manager cannot locate the file: After calling
NSURL *fileURL = [unarchiver decodeObjectForKey:kFileURL];
NSString *filePath = fileURL.path;
the method
[[NSFileManager defaultManager] fileExists:filePath];
returns NO.
I tried to find the reason for this and I discovered that the path to the Documents folder changes with every app launch. The part that changes is the hexadecimal folder in the middle. Here are two examples:
/private/var/mobile/Applications/04083A4A-87AC-4E3C-8BA1-F002B97AE304/Documents/...
/private/var/mobile/Applications/65D136BA-42C3-887A-B947-7FE396978153/Documents/...
I always thought that the hexadecimal part is some sort of ID unique to every app. But as it changes: What exactly is that number?
And how can I relocate my file then after terminating and relaunching my app?
You should just get the directory for the document folder and then load your file.
+ (NSString *)documentDataPath
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
if ([paths count] == 0) {
return nil;
}
NSString *directory = [paths objectAtIndex:0];
if (directory == nil) {
NSLog(#"NSDocumentDirectory not found!");
}
return directory;
}

email attachment not opening after ISO8 upgrade

I have have a app working great in ISO7 which has a Public.filename-extension in the info.plist to associate sqlite files, a week ago I could email a sqlite file to the users of the app, they could select the file use the "open in" option to update the app data. Since the upgrade to ISO8 the sqlite file is still associated and give the "Open in" option but when selected it fires up the app, but the data is not updated anymore, anyone else had this problem ?
I fixed the issue by not saving to the NSBundle mainBundle
- (void)handleOpenURL:(NSURL *)url
{
NSData *dbFile = [[NSData alloc] initWithContentsOfURL:url];
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSError *writeError = nil;
NSString *filePathx = [documentsPath stringByAppendingPathComponent:databaseName];
[dbFile writeToFile:filePathx atomically:YES];
if (writeError) {
NSLog(#"Error writing file: %#", writeError);
}
[self refresh];
}

How to add existing files from ios app to dropbox server using sync api?

All the documents from dropbox and other tutorials are talking about create the new files and sync with dropbox using sync api.
I have some files my app document directory and I'd like to sync them with dropbox server.
Here is what I did.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"emmy.txt"];
DBPath *newPath = [[DBPath root] childPath:path];
DBFile *file = [[DBFilesystem sharedFilesystem] createFile:newPath error:nil];
//[file writeString:str error:nil];
DBFileStatus *status = file.status;
if (!status.cached) {
[file addObserver:self block:^() {
}];
}
The file created on dropbox but it is empty. The file in my app has content.
How can I upload the existing files to dropbox in my app using dropbox sync api?
I think you want writeContentsOfFile.

Dropbox API iOS isn't uploading files

I am added dropbox support to my app, everything works perfect, the authentication, the login/out, but I can't upload files. I am using
NSArray *p = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* docDir = [p objectAtIndex:0];
NSString *localPath = docDir;
NSString *filename = #"Documents";
NSString *destDir = #"/";
[[self restClient] uploadFile:filename toPath:destDir
withParentRev:nil fromPath:localPath];
to upload my applications /Document directory to Dropbox, but nothing is uploaded. I don't get any error message. The directory Apps/My-Applications-Name is created, but with no content inside.
Anyone know why?
I also have this two delegate methods, but I still don't get a log. I also have <DBRestClientDelegate> behind the #interface … ():
- (void)restClient:(DBRestClient*)client uploadedFile:(NSString*)destPath
from:(NSString*)srcPath metadata:(DBMetadata*)metadata {
NSLog(#"File uploaded successfully to path: %#", metadata.path);
}
- (void)restClient:(DBRestClient*)client uploadFileFailedWithError:(NSError*)error {
NSLog(#"File upload failed with error - %#", error);
}
It sounds like Documents is a directory, but uploadFile is used to upload a file. I don't think there's a method in the Core API to upload the contents of a folder, so you'll have to walk through the folder and upload each file individually.
Did you implement the Dropbox delegate methods? Uploadcompleted and uploadfailedwitherror? You also need to specify in your app delegate that you are the Dropbox delegate in order to implement those methods. Make sure your local path is correct, your upload path is.
Add DBRestClientDelegate to your app delegate or whatever class uploads
NSArray *p = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentDirectory = [p objectAtIndex:0];
NSString *filename = #"png.png";
NSString *destDir = #"/";
[[self restClient] uploadFile:filename
toPath:destDir
withParentRev:nil
fromPath:[documentDirectory stringByAppendingPathComponent:filename] ];
the "fromPath" must be the FULL PATH of the source file. The API Document is WRONG.
Did you check that you're making setting the delegate from the main thread? Otherwise, your thread likely doesn't have a runloop and the delegate callbacks will never be called.
UPDATE my problem was ARC destroying the DBRestClient object before the upload was complete.

Resources