Replacing UISaveVideoAtPathToSavedPhotosAlbum #selector videoSaved function - ios

Xcode 7
Swift 2
Objective C
I have changed some Objective C code, and I do not know Objective C syntax at all. I have replaced the following code that was saving videos to the camera roll:
if ( UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(newPath))
// Copy it to the camera roll.
UISaveVideoAtPathToSavedPhotosAlbum(newPath, self, #selector(videoSaved:didFinishSavingWithError:contextInfo:), (__bridge void *)(AvailableVideos[0]));
else
{
[self ErrorOnDownloadOrSave];
return;
}
With code that is saving the video to the Data Container Document Directory of my app:
NSString *tempFilePath = [downloadURL path];
NSError * error = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:#"/Videos"];
//NSString *newPath = [[tempFilePath stringByDeletingLastPathComponent] stringByAppendingPathComponent:AvailableVideos[0]];
NSString *newPath = [dataPath stringByAppendingPathComponent:AvailableVideos[0]];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:dataPath])
[fileManager createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error]; //Create folder
//copying temp video to Documents Directory
if ([fileManager fileExistsAtPath:newPath] == YES)
[fileManager removeItemAtPath:newPath error:&error];
[fileManager copyItemAtPath:tempFilePath toPath:newPath error:&error];
In the Objective C code that is saving to the iOS Camera Roll there is an Objective C "function" that is called when the "videoSaved" event is complete:
-(void)videoSaved:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
//implementation
}
I need to figure out how to call this "function", "videoSaved" after this code:
//copying temp video to Documents Directory
if ([fileManager fileExistsAtPath:newPath] == YES)
[fileManager removeItemAtPath:newPath error:&error];
[fileManager copyItemAtPath:tempFilePath toPath:newPath error:&error];
I realize the videoSaved function is a special signature for UISaveVideoAtPathToSavedPhotosAlbum but I am just so unfamiliar with Objective C that I do not know how to write a new function that I can call, and pass the my error object and maintain the implementation of videoSaved.

According to NSFileManager documentation, the method copyItemAtPath returns BOOL.
YES if the item was copied successfully or the file manager’s delegate stopped the operation deliberately. Returns NO if an error occurred.
So you can do something like :
if ([fileManager copyItemAtPath:tempFilePath toPath:newPath error:&error]) {
//saved
NSLog(#"video saved");
} else {
//error
NSLog(#"error occured : %#", error);
}

Related

How to import sqlite file into app's document directory in ios?

I want to export my whole database from my app via email and on other device when i download that database file, it can be open directly in app and replace my existing database file with that database file.
I have exported my database file(.sqlite) via mail and i want to import that file from mail into my app. I have also implement the functionality which the file from mail can directly open in my app. But i want to import that database file directly from mail. So how can i do that?
Or Can i replace that file with my app database?
I think you are looking for below method,
- (BOOL)replaceItemAtURL:(NSURL *)originalItemURL withItemAtURL:(NSURL *)newItemURL backupItemName:(nullable NSString *)backupItemName options:(NSFileManagerItemReplacementOptions)options resultingItemURL:(NSURL * _Nullable * _Nullable)resultingURL error:(NSError **)error NS_AVAILABLE(10_6, 4_0);
you can call this method with NSFileManager's instance or object. You can pass source and destination path as fileUrl ([NSURL fileURLWithPath:#"path string"];) and it will replace data at destination path!
Couldn't understand your problem completely but here is a code that can give any clue how to replace your existing file in documents directory:
//Reference the path to the documents directory.
NSString *documentDir =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
//Get the path of old file.
NSString *filePath = [documentDir stringByAppendingPathComponent:#"File.sqlite"];
if([[NSFileManager defaultManager] fileExistsAtPath: filePath])
{
[fileManager removeItemAtPath:filePath error:&error] //Delete old file
}
//Copy New File.sqlite from Resource Bundle.
NSString *resourcePath = [[NSBundle mainBundle] pathForResource:#"File" ofType:#"sqlite"];
[fileManager copyItemAtPath:resourcePath toPath:filePath error:&error];
This link is helps to all your questions in SQLITE,
Like Copy Sqlite File in to Docs directory,
and also Select queries, Insert, Delete, Update varius types of recotds etc.. etc...
Checkout + (NSString*) copyDBFile method in this link for ur requirement
SQLite Programing : Initial Steps - By iOSCodeGUIDE
//Commen method for DAtaBase Copy
+ (NSString*) copyDBFile
{
NSString *docsDirectoryPath;
NSArray *dirPaths;
NSString *databasePath;
NSFileManager *fileManager = [NSFileManager defaultManager];
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDirectoryPath = [dirPaths objectAtIndex:0];
// Build the path to the database file
databasePath = [[NSString alloc] initWithString: [docsDirectoryPath stringByAppendingPathComponent: #"SqliteTable.db"]];
BOOL isSuccess = [fileManager fileExistsAtPath: databasePath ];
if (!isSuccess)
{
NSError *error;
NSString *defaultDBPath=[[NSBundle mainBundle]pathForResource:#"SqliteTable" ofType:#"db"];
// NSLog(#"path :%#", defaultDBPath);
isSuccess = [fileManager copyItemAtPath:defaultDBPath toPath:databasePath error:&error];
if (! isSuccess)
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
NSLog(#"%#",databasePath);
return databasePath;
}
You should use iOS share extensions to first import the database file from mail app. Here is a tutorial that you can refer to.
// Returns the persistent store coordinator for the application.
// If the coordinator doesn't already exist, it is created and the application's store added to it.
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil)
{
return _persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"yourSqlite.sqlite"];
NSString *sourcePath = [[NSBundle mainBundle] pathForResource:#"yourSqlite.sqlite" ofType:nil];
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSError *error = nil;
if (![[NSFileManager defaultManager] fileExistsAtPath:[documentsDirectory stringByAppendingPathComponent:#"yourSqlite.sqlite"] ]) {
if([[NSFileManager defaultManager] copyItemAtPath:sourcePath toPath:[documentsDirectory stringByAppendingPathComponent:#"yourSqlite.sqlite"] error:&error]){
NSLog(#"Default file successfully copied over.");
} else {
NSLog(#"Error description-%# \n", [error localizedDescription]);
NSLog(#"Error reason-%#", [error localizedFailureReason]);
}
}
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
{
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}

How to rename files/folders from document folder programmatically in iOS

I am working on functionality to save video files in document folder of application in iOS.
How to rename some files programmatically?
try this code :
NSError * err = NULL;
NSFileManager * fm = [[NSFileManager alloc] init];
BOOL result = [fm moveItemAtPath:#"/tmp/test.tt" toPath:#"/tmp/dstpath.tt" error:&err];
if(!result)
NSLog(#"Error: %#", err);
other wise use this method to rename file
- (void)renameFileWithName:(NSString *)srcName toName:(NSString *)dstName
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePathSrc = [documentsDirectory stringByAppendingPathComponent:srcName];
NSString *filePathDst = [documentsDirectory stringByAppendingPathComponent:dstName];
NSFileManager *manager = [NSFileManager defaultManager];
if ([manager fileExistsAtPath:filePathSrc]) {
NSError *error = nil;
[manager moveItemAtPath:filePathSrc toPath:filePathDst error:&error];
if (error) {
NSLog(#"There is an Error: %#", error);
}
} else {
NSLog(#"File %# doesn't exists", srcName);
}
}
There is no Direct API to rename the file . Though when you move the file from one place to another place, if that file in destination path not exists then iOS will create the file in the given name. For file you can just give the New name of your file, how it should be displayed/referenced.
you could check this answer. Good luck!

NSFileManager moving a file shows error

I am trying to create two log files and replace content in the second file with the content in the first file.
My code for creating log in AppDelegate
NSArray *paths3 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory3 = [paths3 objectAtIndex:0];
logPath3 = [documentsDirectory3 stringByAppendingPathComponent:#"console4.log"];
if(![[NSFileManager defaultManager] fileExistsAtPath:logPath3])
[[NSFileManager defaultManager] createFileAtPath:logPath3 contents:[NSData data] attributes:nil];
NSLog(#"path %#",logPath3);
freopen([logPath3 cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
NSArray *paths2 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory2 = [paths2 objectAtIndex:0];
logPath2 = [documentsDirectory2 stringByAppendingPathComponent:#"console3.log"];
if(![[NSFileManager defaultManager] fileExistsAtPath:logPath2])
[[NSFileManager defaultManager] createFileAtPath:logPath2 contents:[NSData data] attributes:nil];
NSLog(#"path %#",logPath2);
freopen([logPath2 cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
_isFileOneCreated =YES;
code to move content
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
NSError * err;
if ([filemgr moveItemAtPath:
logPath2 toPath:
logPath3 error: &err])
NSLog (#"Day 3 Move successful");
else
NSLog (#"Day 3 Move failed %#",[err localizedDescription]);
But i get an error 516.
(Cocoa error 516.)" UserInfo=0x16dba220 {NSSourceFilePathErrorKey=/var/mobile/Containers/Data/Application/274E9843-2C8E-45F3-BD41-EA392F50C7AC/Documents/console3.log, NSUserStringVariant=(
Move
), NSFilePath=/var/mobile/Containers/Data/Application/274E9843-2C8E-45F3-BD41-EA392F50C7AC/Documents/console3.log, NSDestinationFilePath=/var/mobile/Containers/Data/Application/274E9843-2C8E-45F3-BD41-EA392F50C7AC/Documents/console4.log, NSUnderlyingError=0x16da63f0 "The operation couldn’t be completed. File exists"}
Help me solve my issue
moveItemAtPath does not allow you to overwrite the file with same name. See this Question Thread.
All you need to do is delete the file at target location before you overwrite with new one. Use the below code. This will do the trick but i advice you to take precaution to have the backup of your file just in case move doesn't work for some unknown reason.
NSFileManager *filemgr = [NSFileManager defaultManager];
NSError * err;
[filemgr removeItemAtPath:logPath3 error:&err];
if ([filemgr moveItemAtPath:logPath3 toPath:logPath2 error: &err])
NSLog (#"Day 3 Move successful");
else
NSLog (#"Day 3 Move failed %#",[err localizedDescription]);

Get File from Directory into NSData

I try to get my file in my self created Directory in the Documents Directory into a NSData Object like this:
NSString *path = [documentsDirectory stringByAppendingFormat:#"%#%#",#"/",fileName];
NSError* errorr = nil;
NSData *fileData = [NSData dataWithContentsOfFile:path options: 0 error: &errorr];
if (fileData == nil)
{
NSLog(#"Failed to read file, error %#", errorr);
}
else
{
}
But i always get this error:
Failed to read file, error Error Domain=NSCocoaErrorDomain Code=257 "The operation couldn’t be completed. (Cocoa error 257.)" UserInfo=0x156be110 {NSFilePath=/var/mobile/Applications/679253E3-652C-45EE-B589-609E52E4E3B0/Documents/upload/test.xml, NSUnderlyingError=0x156ba7f0 "The operation couldn’t be completed. Permission denied"}
So if i check if the file is readable:
if ([[NSFileManager defaultManager] isReadableFileAtPath: path] == YES)
NSLog (#"File is readable");
else
NSLog (#"File is read only");
i get the result that the file is readable, so why do i get the error if i want to parse that file into NSData?!
UPDATE: i created my file like this:
NSString *filePath = [self dataFilePath:fileName];
[xmlData writeToFile:filePath atomically:YES];
- (NSString *)dataFilePath: (NSString *) path {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"upload"];
NSError *error = nil;
if (![[NSFileManager defaultManager] fileExistsAtPath:documentsDirectory])
[[NSFileManager defaultManager] createDirectoryAtPath:documentsDirectory withIntermediateDirectories:NO attributes:nil error:&error];
NSString *documentsPath = [documentsDirectory
stringByAppendingPathComponent:path];
return documentsPath;
}
UPDATE2: After creating the file, i move it into another Directory with this function:
- (void)moveXmlFilesToUploadDirectory
{
#try {
//Check if FILES_DIR exists
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [[paths objectAtIndex:0] stringByAppendingPathComponent:FILES_DIR];//filesDir
NSString *uploadDirectory = [[paths objectAtIndex:0] stringByAppendingPathComponent:UPLOAD_DIR];//filesDir
if ([[NSFileManager defaultManager] fileExistsAtPath:documentsDirectory])
{
NSString *extension = #"xml";
NSArray *contents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:NULL];
NSEnumerator *e = [contents objectEnumerator];
NSString *filename;
while ((filename = [e nextObject])) {
if ([[filename pathExtension] isEqualToString:extension]) {
[[NSFileManager defaultManager] moveItemAtPath:documentsDirectory toPath:[uploadDirectory stringByAppendingPathComponent:filename] error:NULL];
}
}
}
}
#catch (NSException *exception) {
}
#finally {
}
}
Maybe the Problem is after moving the file! Cause if i try to get my file into a NSData before i move it, everything works...
It seems that you try to copy the whole directory to a destination meant to be a file. The result is that the filepath is a directory path in the end so you can't open it like a file which leads to the permission error message.
You should update your copy code to
while ((filename = [e nextObject])) {
if ([[filename pathExtension] isEqualToString:extension]) {
[[NSFileManager defaultManager] moveItemAtPath:[documentsDirectory stringByAppendingPathComponent: filename] toPath:[uploadDirectory stringByAppendingPathComponent:filename] error:NULL];
}
}
to copy every file individually. That will create than the actual file at the destination path intend of a directory.
The chances are high that you don't have the right permissions for that file. Please check the permissions and add read access for the current user or "everyone". You can set the read permissions for your user by the info dialog (cmd + i) or in the terminal with chmod u+r test.xml. Eventually you have to set the owner before with
sudo chown yourusername test.xml
Hope that makes sense.

How do i create a file in the default documents directory in an iOS app

I'm writing an app that needs to store some persistence information in file but i'm having trouble debugging the createFileAtPath:contents:attributes: function of NSFileManager, i have reduced the problem to the below piece of code.
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
NSString * fileName = #"newfile.txt";
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent: fileName];
NSLog(#"full path name: %#", filePath);
// check if file exists
if ([filemgr fileExistsAtPath: filePath] == YES){
NSLog(#"File exists");
}else {
NSLog (#"File not found, file will be created");
if (![filemgr createFileAtPath:filePath contents:nil attributes:nil]){
NSLog(#"Create file returned NO");
}
}
Since the function doesn't take an NSError object i'm having trouble finding out why exactly it is returning false.
From other examples i have seen here Write a file on iOS and here How to programmatically create an empty .m4a file of a certain length under iOS using CoreAudio on device? it should be ok to pass nil to both the contents and attributes parameters. I've tried specifying both parameters and receive the same result.
I'm thinking this may be a permissions issue but i'm unsure if the below code is the correct way to check permissions on a directory.
if ([filemgr isWritableFileAtPath:documentsDirectory] == YES){
NSLog (#"File is readable and writable");
}
// Following Code will create Directory in DocumentsDirectory
NSString *docDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *dirName = [docDir stringByAppendingPathComponent:#"MyDir"];
BOOL isDir
NSFileManager *fm = [NSFileManager defaultManager];
if(![fm fileExistsAtPath:dirName isDirectory:&isDir])
{
if([fm createDirectoryAtPath:dirName withIntermediateDirectories:YES attributes:nil error:nil])
NSLog(#"Directory Created");
else
NSLog(#"Directory Creation Failed");
}
else
NSLog(#"Directory Already Exist");
swift5
guard let docdir = NSSearchPathForDirectoriesInDomains(.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first else {
preconditionFailure()
}
let path = (docdir as NSString).appendingPathComponent(yourfilename + "." + yourfilenameExtension)

Resources