Can't copy database file using copyItemAtPath with cocoa error 4 - iphone

I want to copy the database file from bundle to user document.
My code is below:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *userPath = [documentsDir stringByAppendingPathComponent:#"db.sql"];
NSString *srcPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"db.sql"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSLog(#"Bundle database exists: %i",[fileManager fileExistsAtPath:srcPath]);
NSLog(#"User Document folder database exists: %i",[fileManager fileExistsAtPath:userPath]);
BOOL find = [fileManager fileExistsAtPath:userPath];
BOOL copySuccess = FALSE;
NSError *error;
if (!find) {
NSLog(#"don't have writable copy, need to create one");
copySuccess = [fileManager copyItemAtPath:srcPath toPath:userPath error:&error];
}
if (!copySuccess) {
NSLog(#"Failed with message: '%#'.",[error localizedDescription]);
}
and the result is always saying:
Bundle database exists: 1 User Document folder database exists: 0
don't have writable copy, need to create one Failed with message: 'The
operation couldn’t be completed. (Cocoa error 4.)'.
Please suggest, thanks.

Your code for determining your user's Documents Directory is incorrect.
Using your code, I put together a quick and dirty sample that works. For your application, you probably want to create some utils class that contains the static function 'applicationDocumentsDirectory' so that other classes in your project can call it, if needed.
Header File:
#import <UIKit/UIKit.h>
#interface TST_ViewController : UIViewController
+ (NSString *) applicationDocumentsDirectory;
#end
Implementation File:
#import "TST_ViewController.h"
#interface TST_ViewController ()
#end
#implementation TST_ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString *dbFilename = #"db.sql";
NSString *userPath = [[TST_ViewController applicationDocumentsDirectory] stringByAppendingPathComponent:dbFilename];
NSString *srcPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:dbFilename];
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL foundInBundle = [fileManager fileExistsAtPath:srcPath];
BOOL foundInUserPath = [fileManager fileExistsAtPath:userPath];
BOOL copySuccess = FALSE;
NSError *error;
if(foundInBundle) {
if (!foundInUserPath) {
NSLog(#"Don't have a writable copy, so need to create one...");
copySuccess = [fileManager copyItemAtPath:srcPath toPath:userPath error:&error];
}
if (!copySuccess) {
NSLog(#"Failed with message: '%#'.",[error localizedDescription]);
}
} else {
// handle error in the event the file is not included in the bundle
}
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
+ (NSString *) applicationDocumentsDirectory
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
return basePath;
}
#end

Related

can't create sqlite3 database in ios

Create Database Code
This code is correct. i used that code to create a database it's successful run and created a database but i test my application so i remove or delete my simulator app and again run my application then i see database is not created.
Please tell me what is the actual problem i face.
ClsUpdateNetworkViewController.h
#import <UIKit/UIKit.h>
#import "Person.h"
#import <sqlite3.h>
#interface ClsUpdateNetworkViewController : UIViewController{
UITextField *name;
UITextField *phone;
NSString *databasePath;
sqlite3 *contactDB;
int rowcount;
}
#property (nonatomic, strong) Person *person;
#property (nonatomic, strong) NSString *firstName;
#property (nonatomic, strong) NSString *lastName;
#property (nonatomic, strong) NSString *fullName;
#property (nonatomic, strong) NSString *phoneNumber;
#property (nonatomic, strong) NSString *workEmail;
#end
ClsUpdateNetworkViewController.m
#import "ClsUpdateNetworkViewController.h"
#import "ClsMainPageAppDelegate.h"
#import "ClsAddressBookViewController.h"
#interface ClsUpdateNetworkViewController ()
#end
#implementation ClsUpdateNetworkViewController
#synthesize person,firstName,lastName,fullName,phoneNumber,workEmail;
#synthesize name,phone;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self createDatabase];
}
-(void) createDatabase
{
NSString *docsDir;
NSArray *dirPaths;
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
// Build the path to the database file
databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: #"contacts.db"]];
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: databasePath ] == NO)
{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
char *errMsg;
const char *sql_stmt = "CREATE TABLE IF NOT EXISTS CONTACTS (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, PHONE TEXT)";
if (sqlite3_exec(contactDB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
{
NSLog(#"Failed to create table");
}
sqlite3_close(contactDB);
}
else
{
NSLog(#"Failed to open/create database");
}
}
}
i test or debug my application
Code is not going inside this condition.
if ([filemgr fileExistsAtPath: databasePath ] == NO)
{
// inside code is not executed.
}
Call this Function at didFinishLaunchingWithOptions:
-(void)createdb
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dbPath = [documentsDirectory stringByAppendingPathComponent:#"emp.sqlite"];
NSURL *dbURL = [NSURL fileURLWithPath:dbPath];
// copy a database from the bundle if not present
// on disk
NSFileManager *fm = [NSFileManager defaultManager];
if (![fm fileExistsAtPath:dbPath])
{
NSURL *bundlePath = [[NSBundle mainBundle] URLForResource:#"emp" withExtension:#"sqlite"];
NSError *error = nil;
if (!bundlePath || ![fm copyItemAtURL:bundlePath toURL:dbURL error:&error]) {
NSLog(#"error copying database from bundle: %#", error);
}
}
else
{
NSLog(#"Success in Copy file");
}
}
hi try this to create database only just add this code to your file
NSString *databaseName=#"Database.sqlite";
-(void)createDatabaseIfNeeded
{
// NSLog(#"Virtual database is created...");
NSFileManager *fileManager=[[NSFileManager defaultManager]autorelease];
NSError *error;
NSArray *paths= NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path=[paths objectAtIndex:0];
NSString *finalPath=[path stringByAppendingPathComponent:databaseName];
// NSLog(#"Database Path is:--> %#",finalPath);
NSString *bundlePath=[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];
success = [fileManager fileExistsAtPath:finalPath];
if(success)
{
if(sqlite3_open([finalPath UTF8String],&database)!=SQLITE_OK)
{
sqlite3_close(database);
}
return;
}
success=[fileManager copyItemAtPath:bundlePath toPath:finalPath error:&error];
if(!success)
{
NSAssert1(0,#"Failed to create writable database file with message '%#' .",[error localizedDescription]);
}
else//First Time Loaded Application....
{
if(sqlite3_open([finalPath UTF8String],&database)!=SQLITE_OK)
{
sqlite3_close(database);
}
}
}
How it worked for me is this
//-----------------------------------------------------------------------------------------------------//
#pragma mark - Shared Instance
//-----------------------------------------------------------------------------------------------------//
+ (SQLConnector *)database
{
static SQLConnector *_sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedClient = [[SQLConnector alloc]init];
});
return _sharedClient;
}
//-----------------------------------------------------------------------------------------------------//
#pragma mark - Initialization Methods
//-----------------------------------------------------------------------------------------------------//
- (id)init {
if ((self = [super init]))
{
_databaseName = DB_NAME;
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
_databasePath = [documentsDir stringByAppendingPathComponent:_databaseName];
NSLog(#"%#",_databasePath);
if (sqlite3_open([[self dbPath] UTF8String], &_database) != SQLITE_OK)
{
[[[UIAlertView alloc]initWithTitle:#"Missing"
message:#"Database file not found"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil]show];
}
}
return self;
}
- (NSString *)dbPath
{
[self checkAndCreateDatabase];
return _databasePath;
}
-(void) checkAndCreateDatabase
{
// Check if the SQL database has already been saved to the users phone, if not then copy it over
BOOL success;
// Create a FileManager object, we will use this to check the status
// of the database and to copy it over if required
NSFileManager *fileManager = [NSFileManager defaultManager];
// Check if the database has already been created in the users filesystem
success = [fileManager fileExistsAtPath:_databasePath];
// If the database already exists then return without doing anything
if(success) return;
// If not then proceed to copy the database from the application to the users filesystem
// Get the path to the database in the application package
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:_databaseName];
// Copy the database from the package to the users filesystem
[fileManager copyItemAtPath:databasePathFromApp toPath:_databasePath error:nil];
}
//-----------------------------------------------------------------------------------------------------//
#pragma mark - Helper methods
//-----------------------------------------------------------------------------------------------------//
-(BOOL)dbOpenedSuccessfully
{
if(sqlite3_open([[self dbPath] UTF8String], &_database) == SQLITE_OK)
{
return YES;
}
else
{
[[[UIAlertView alloc]initWithTitle:#"Error"
message:#"Error on opening the DB"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil]show];
return NO;
}
}
//-----------------------------------------------------------------------------------------------------//
#pragma mark - Query
//-----------------------------------------------------------------------------------------------------//
- (void) executeQuery:(NSString *)strQuery
{
char *error = NULL;
if([self dbOpenedSuccessfully])
{
NSLog(#"%#",strQuery);
sqlite3_exec(_database, [strQuery UTF8String], NULL, NULL,&error);
if (error!=nil) {
NSLog(#"%s",error);
}
sqlite3_close(_database);
}
}

iOS 6: SQLite db doesn't work

I always use this code to open a sqlite db in my iPhone application, but now with iOS6 this code doesn't work. The function: sqlite3_prepare_v2 fails but I don't understand why!
I also don't understand why if I try to change the name: "gamer.sqlite" of sqlite db with another name of an not existent file, the function: 'sqlite3_open' return again SQLITE_OK value.
This is my code:
-(NSMutableArray*)view_table
{
const char *sql;
NSMutableArray *content=[[NSMutableArray alloc] initWithObjects:nil];
[self msgbox:#"eseguo"];
/*elementi da visualizzare nella tabella*/
if(sqlite3_open([databasePath UTF8String],&database)==SQLITE_OK)
{
[self msgbox:#"opened"];
sql = "SELECT * FROM list_gamer";
if (sqlite3_prepare_v2(database,sql, -1, &selectstmt, NULL) == SQLITE_OK)
{
[self msgbox:#"query eseguita"];
while(sqlite3_step(selectstmt) == SQLITE_ROW)
{
[content addObject:[NSString stringWithFormat:#"%s",sqlite3_column_text(selectstmt,0)]];
}
}
}
return content;
}
- (void)viewDidLoad{
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [[documentsDir stringByAppendingPathComponent:#"gamer.sqlite"] copy];
if(![[NSFileManager defaultManager] fileExistsAtPath:databasePath])
{
NSFileManager *fileManager = [NSFileManager defaultManager];
int success = [fileManager fileExistsAtPath:databasePath];
if(success)
{
[fileManager removeItemAtPath:databasePath error:nil];
return;
}
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"gamer.sqlite"];
// Copy the database from the package to the users filesystem
[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDir = [documentPaths objectAtIndex:0];
}
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning{
[super didReceiveMemoryWarning];
}
-(IBAction)start_game:(id)sender{
self.view=frmgame;
[self view_table];
}
Not exactly a direct answer but i personally really love using fmbd to help manage sqlite & error.
Fmdb is an Objective-C wrapper around SQLite: http://sqlite.org/
https://github.com/ccgus/fmdb

File search with specific Extension Objective c

I am working on some file manipulation in iPhone project. Where i need to search files of specific extension. One option is to manually process each file & directory to find.
My Question is, Is there any simple way to do that ?
Thanks
see using NSFileManager you can get the files and bellow the condition with you can get file with particular extension, Its work in Document Directory ..
-(NSArray *)findFiles:(NSString *)extension
{
NSMutableArray *matches = [[NSMutableArray alloc]init];
NSFileManager *manager = [NSFileManager defaultManager];
NSString *item;
NSArray *contents = [manager contentsOfDirectoryAtPath:[NSHomeDirectory() stringByAppendingPathComponent:#"Documents"] error:nil];
for (item in contents)
{
if ([[item pathExtension]isEqualToString:extension])
{
[matches addObject:item];
}
}
return matches;
}
use this array with your searched files.. get the return in NSArray type so use NSArray object to store this data...
i hope this helpful to you...
I have not found any thing which i could say is simple to do that & and finally i have to write my own code to do this. I am posting this here because maybe someone find this help full.
-(void)search{
#autoreleasepool {
NSString *baseDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSFileManager *defFM = [NSFileManager defaultManager];
BOOL isDir = YES;
NSArray *fileTypes = [[NSArray alloc] initWithObjects:#"mp3",#"mp4",#"avi",nil];
NSMutableArray *mediaFiles = [self searchfiles:baseDir ofTypes:fileTypes];
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [docDir stringByAppendingPathComponent:#"playlist.plist"];
if(![defFM fileExistsAtPath:filePath isDirectory:&isDir]){
[defFM createFileAtPath:filePath contents:nil attributes:nil];
}
NSMutableDictionary *playlistDict = [[NSMutableDictionary alloc]init];
for(NSString *path in mediaFiles){
NSLog(#"%#",path);
[playlistDict setValue:[NSNumber numberWithBool:YES] forKey:path];
}
[playlistDict writeToFile:filePath atomically:YES];
[[NSNotificationCenter defaultCenter] postNotificationName:#"refreshplaylist" object:nil];
}
}
Now the recursive Method
-(NSMutableArray*)searchfiles:(NSString*)basePath ofTypes:(NSArray*)fileTypes{
NSMutableArray *files = [[[NSMutableArray alloc]init] autorelease];
NSFileManager *defFM = [NSFileManager defaultManager];
NSError *error = nil;
NSArray *dirPath = [defFM contentsOfDirectoryAtPath:basePath error:&error];
for(NSString *path in dirPath){
BOOL isDir;
path = [basePath stringByAppendingPathComponent:path];
if([defFM fileExistsAtPath:path isDirectory:&isDir] && isDir){
[files addObjectsFromArray:[self searchfiles:path ofType:fileTypes]];
}
}
NSArray *mediaFiles = [dirPath pathsMatchingExtensions:fileTypes];
for(NSString *fileName in mediaFiles){
fileName = [basePath stringByAppendingPathComponent:fileName];
[files addObject:fileName];
}
return files;
}
What you need is a recursive method so that you can process sub-directories. The first of the following methods is public; the other private. Imagine they are implemented as static methods of a class called CocoaUtil:
CocoaUtil.h:
#interface CocoaUtil : NSObject
+ (NSArray *)findFilesWithExtension:(NSString *)extension
inFolder:(NSString *)folder;
#end
CocoaUtil.m:
// Private Methods
#interface CocoaUtil ()
+ (NSArray *)_findFilesWithExtension:(NSString *)extension
inFolder:(NSString *)folder
andSubFolder:(NSString *)subFolder;
#end
#implementation CocoaUtil
+ (NSArray *)findFilesWithExtension:(NSString *)extension
inFolder:(NSString *)folder
{
return [CocoaUtil _findFilesWithExtension:extension
inFolder:folder
andSubFolder:nil];
}
+ (NSArray *)_findFilesWithExtension:(NSString *)extension
inFolder:(NSString *)folder
andSubFolder:(NSString *)subFolder
{
NSMutableArray *found = [NSMutableArray array];
NSString *fullPath = (subFolder != nil) ? [folder stringByAppendingPathComponent:subFolder] : folder;
NSFileManager *fileman = [NSFileManager defaultManager];
NSError *error;
NSArray *contents = [fileman contentsOfDirectoryAtPath:fullPath error:&error];
if (contents == nil)
{
NSLog(#"Failed to find files in folder '%#': %#", fullPath, [error localizedDescription]);
return nil;
}
for (NSString *file in contents)
{
NSString *subSubFolder = subFolder != nil ? [subFolder stringByAppendingPathComponent:file] : file;
fullPath = [folder stringByAppendingPathComponent:subSubFolder];
NSError *error = nil;
NSDictionary *attributes = [fileman attributesOfItemAtPath:fullPath error:&error];
if (attributes == nil)
{
NSLog(#"Failed to get attributes of file '%#': %#", fullPath, [error localizedDescription]);
continue;
}
NSString *type = [attributes objectForKey:NSFileType];
if (type == NSFileTypeDirectory)
{
NSArray *subContents = [CocoaUtil _findFilesWithExtension:extension inFolder:folder andSubFolder:subSubFolder];
if (subContents == nil)
return nil;
[found addObjectsFromArray:subContents];
}
else if (type == NSFileTypeRegular)
{
// Note: case sensitive comparison!
if ([[fullPath pathExtension] isEqualToString:extension])
{
[found addObject:fullPath];
}
}
}
return found;
}
#end
This will return an array containing the full path to every file with the specified file extension. Note that [NSString pathExtension] does not return the . of the file extension so be sure not to pass that in the extension parameter.
Yes we have direct method for NSArray below helps you
NSMutableArray *arrayFiles = [[NSMutableArray alloc] initWithObjects:#"a.png", #"a.jpg", #"a.pdf", #"h.png", #"f.png", nil];
NSLog(#"pathsMatchingExtensions----%#",[arrayFiles pathsMatchingExtensions:[NSArray arrayWithObjects:#"png", nil]]);
//my output is
"a.png",
"h.png",
"f.png"
Like this way you can find your specific file extension
NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
NSFileManager *manager = [NSFileManager defaultManager];
NSDirectoryEnumerator *direnum = [manager enumeratorAtPath:bundleRoot];
NSString *filename;
while ((filename = [direnum nextObject] )) {
if ([filename hasSuffix:#".doc"]) { //change the suffix to what you are looking for
[arrayListofFileName addObject:[filename stringByDeletingPathExtension]];
}
}
Use below code
NSArray *myFiles = [myBundle pathsForResourcesOfType:#"Your File extension"
inDirectory:nil];

How can I use iCloud to synchronize a .zip file between my apps?

Is it possible to upload a .zip file to iCloud, and then have it be synchronized across all of a user's iOS devices?
If so, how would I go about doing this?
If there is any File size limit, then also mention max. file size allowed.
This is how I synchronized zip files with iCloud .
Steps:
1) http://transoceanic.blogspot.in/2011/07/compressuncompress-files-on.html
. Refer this link to download zip api which is having code for zipping and unzipping folder.
2) Now all you need to play with NSData.
3) "MyDocument.h" file
#import <UIKit/UIKit.h>
#interface MyDocument : UIDocument
#property (strong) NSData *zipDataContent;
#end
4)
#import "MyDocument.h"
#implementation MyDocument
#synthesize zipDataContent;
// Called whenever the application reads data from the file system
- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError **)outError
{
self.zipDataContent = [[NSData alloc] initWithBytes:[contents bytes] length:[contents length]];
[[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 self.zipDataContent;
}
#end
5) Now somewhere in your app you need to zip folder and sync with icloud.
-(BOOL)zipFolder:(NSString *)toCompress zipFilePath:(NSString *)zipFilePath
{
BOOL isDir=NO;
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *pathToCompress = [documentsDirectory stringByAppendingPathComponent:toCompress];
NSArray *subpaths;
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:pathToCompress isDirectory:&isDir] && isDir){
subpaths = [fileManager subpathsAtPath:pathToCompress];
} else if ([fileManager fileExistsAtPath:pathToCompress]) {
subpaths = [NSArray arrayWithObject:pathToCompress];
}
zipFilePath = [documentsDirectory stringByAppendingPathComponent:zipFilePath];
//NSLog(#"%#",zipFilePath);
ZipArchive *za = [[ZipArchive alloc] init];
[za CreateZipFile2:zipFilePath];
if (isDir) {
for(NSString *path in subpaths){
NSString *fullPath = [pathToCompress stringByAppendingPathComponent:path];
if([fileManager fileExistsAtPath:fullPath isDirectory:&isDir] && !isDir){
[za addFileToZip:fullPath newname:path];
}
}
} else {
[za addFileToZip:pathToCompress newname:toCompress];
}
BOOL successCompressing = [za CloseZipFile2];
if(successCompressing)
return YES;
else
return NO;
}
-(IBAction) iCloudSyncing:(id)sender
{
//***** PARSE ZIP FILE : Pictures *****
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
if([self zipFolder:#"Pictures" zipFilePath:#"iCloudPictures"])
NSLog(#"Picture Folder is zipped");
ubiq = [[NSFileManager defaultManager]URLForUbiquityContainerIdentifier:nil];
ubiquitousPackage = [[ubiq URLByAppendingPathComponent:#"Documents"] URLByAppendingPathComponent:#"iCloudPictures.zip"];
mydoc = [[MyDocument alloc] initWithFileURL:ubiquitousPackage];
NSString *zipFilePath = [documentsDirectory stringByAppendingPathComponent:#"iCloudPictures"];
NSURL *u = [[NSURL alloc] initFileURLWithPath:zipFilePath];
NSData *data = [[NSData alloc] initWithContentsOfURL:u];
// NSLog(#"%# %#",zipFilePath,data);
mydoc.zipDataContent = data;
[mydoc saveToURL:[mydoc fileURL] forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success)
{
if (success)
{
NSLog(#"PictureZip: Synced with icloud");
}
else
NSLog(#"PictureZip: Syncing FAILED with icloud");
}];
}
6) You can unzip data received from iCloud like this.
- (void)loadData:(NSMetadataQuery *)queryData {
for (NSMetadataItem *item in [queryData results])
{
NSString *filename = [item valueForAttribute:NSMetadataItemDisplayNameKey];
NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
MyDocument *doc = [[MyDocument alloc] initWithFileURL:url];
if([filename isEqualToString:#"iCloudPictures"])
{
[doc openWithCompletionHandler:^(BOOL success) {
if (success) {
NSLog(#"Pictures : Success to open from iCloud");
NSData *file = [NSData dataWithContentsOfURL:url];
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *zipFolder = [documentsDirectory stringByAppendingPathComponent:#"Pics.zip"];
[[NSFileManager defaultManager] createFileAtPath:zipFolder contents:file attributes:nil];
//NSLog(#"zipFilePath : %#",zipFolder);
NSString *outputFolder = [documentsDirectory stringByAppendingPathComponent:#"Pictures"];//iCloudPics
ZipArchive* za = [[ZipArchive alloc] init];
if( [za UnzipOpenFile: zipFolder] ) {
if( [za UnzipFileTo:outputFolder overWrite:YES] != NO ) {
NSLog(#"Pics : unzip successfully");
}
[za UnzipCloseFile];
}
[za release];
NSError *err;
NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:outputFolder error:&err];
if (files == nil) {
NSLog(#"EMPTY Folder: %#",outputFolder);
}
// Add all sbzs to a list
for (NSString *file in files) {
//if ([file.pathExtension compare:#".jpeg" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
NSLog(#" Pictures %#",file);
// NSFileManager *fm = [NSFileManager defaultManager];
// NSDictionary *attributes = [fm fileAttributesAtPath:[NSString stringWithFormat:#"%#/%#",documentsDirectory,file] traverseLink:NO];
//
// NSNumber* fileSize = [attributes objectForKey:NSFileSize];
// int e = [fileSize intValue]; //Size in bytes
// NSLog(#"%#__%d",file,e);
}
}
else
{
NSLog(#"Pictures : failed to open from iCloud");
[self hideProcessingView];
}
}];
}
}
}
In order to enabling Document storage in iCloud your "document" needs to be encapsulated in a UIDocument object.
Because UIDocument links to a file URL, you can easily create a UIDocument pointing to file://myzipfile.zip and then upload a zip document to iCloud.
I hope this helps
Probably this tutorial can help you more:
http://www.raywenderlich.com/6015/beginning-icloud-in-ios-5-tutorial-part-1

Help: List contents of iPhone application bundle subpath?

I am trying to get a listing of the directories contained within a subpath of my application bundle. I've done some searching and this is what I have come up with
- (void) contents {
NSArray *contents = [[NSBundle mainBundle] pathsForResourcesOfType:nil
inDirectory:#"DataDir"];
if (contents = nil) {
NSLog(#"Failed: path doesn't exist or error!");
} else {
NSString *bundlePathName = [[NSBundle mainBundle] bundlePath];
NSString *dataPathName = [bundlePathName stringByAppendingPathComponent:
#"DataDir"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSMutableArray *directories = [[NSMutableArray alloc] init];
for (NSString *entityName in contents) {
NSString *fullEntityName = [dataPathName
stringByAppendingPathComponent:entityName];
NSLog(#"entity = %#", fullEntityName);
BOOL isDir = NO;
[fileManager fileExistsAtPath:fullEntityName isDirectory:(&isDir)];
if (isDir) {
[directories addObject:fullEntityName];
NSLog(#" is a directory");
} else {
NSLog(#" is not a directory");
}
}
NSLog(#"Directories = %#", directories);
[directories release];
}
}
As you can see I am trying to get a listing of directories in the app bundle's DataDir subpath. The problem is that I get no strings in my contents NSArray.
note:
- I am using the simulator
- When I manually look in the .app file I can see DataDir and the contents therein
- The contents of DataDir are png files and directories that contain png files
- The application logic needs to discover the contents of DataDir at runtime
- I have also tried using
NSArray *contents = [fileManager contentsOfDirectoryAtPath:DataDirPathName error:nil];
and I still get no entries in my contents array
Any suggestions/alternative approaches?
Thanks.
I'm not sure what I was doing wrong yesterday but I have this code working:
NSString *bundlePathName = [[NSBundle mainBundle] bundlePath];
NSString *dataPathName = [bundlePathName stringByAppendingPathComponent:#"DataDir"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:dataPathName]) {
NSLog(#"%# exists", dataPathName);
BOOL isDir = NO;
[fileManager fileExistsAtPath:dataPathName isDirectory:(&isDir)];
if (isDir == YES) {
NSLog(#"%# is a directory", dataPathName);
NSArray *contents;
contents = [fileManager contentsOfDirectoryAtPath:dataPathName error:nil];
for (NSString *entity in contents) {
NSLog(#"%# is within", entity);
}
} else {
NSLog(#"%# is not a directory", dataPathName);
}
} else {
NSLog(#"%# does not exist", dataPathName);
}