I'm storing files in my application sandbox in a way that masks the original name of the file.
For example I have a file called abc.png which is stored in the sandbox as obfuscated.png.
When I do an open in of this file in another application using a UIDocumentInteractionController I'd like to have the other file open the file with the filename abc.png
Currently the other app opens the file as obfuscated.png.
I have tried changing the name property of the UIDocumentInteractionController in documentInteractionControllerWillPresentOptionsMenu as well as willBeginSendingToApplication, however in both cases the receiving application does not get the correct filename - it continues to show the obfuscated filename.
Apart from creating a copy of the file with the unobfuscated name, is there a way to make the receiving application use the desired filename?
Instead of a copy try:
NSError *error = nil;
[[NSFileManager defaultManager] linkItemAtPath:obfuscatedFilePath toPath:abcFilePath error:&error];
This will create a hard link to the file. Symbolic links will not work.
Related
Is there a test way to prove I have access to a file?
I'm using
if ([[NSFileManager defaultManager] fileExistsAtPath:[url path]]){
long long fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:url.absoluteString error:nil][NSFileSize] longLongValue];
NSLog(#"sik: %lld", fileSize); }
I have the if returning positive and I can see the fileSize, but I want to be sure I have access to the file, I was thinking on sending the file to firebase to prove I have access to it, what another way can I prove I have access to the file?
This is inside a share extension, that wants to attach some MS word file, I can see the file exists, and the size, but have some problems accessing the path from react native... so for the moment I just want to prove iOS have access to it... Thanks!
Because of iOS apps being sandboxed by default, if you can see the file, you have access to it.
What you could do is load the file into a variable and then inspect its contents, if you’re really uncertain.
After I created a Objective-c class in my project based on JosephH example. I imported it in my bridging header file.
I was actually able to make it work using a .pdf file in the main bundle
NSString *file = [[NSBundle mainBundle] pathForResource:#"hello-world" ofType:#"pdf"];.
which returns:
"/var/containers/Bundle/Application/63F34E6B-75A7-4CC0-9149-9DF2861DF3A2/sempre-editora.app/hello-world.pdf"
It did render everything all right, zooming and everything. but when I try to render a file in my "Documents" folder it just doesn't work. I even tried to just put this "hello-world.pdf" file inside my "Documents" to try it out and it still doesn't work.
This is the path of my documents file:
"/var/mobile/Containers/Data/Application/AF776E50-FAAC-4274-824F-4F9634E072F6/Documents/70-10"
What could be the problem? I'm sure this is the correct path for my file, and it actually exists, the framework doesn't throw any error but I just get a gray background.
I thought it could be because my file doesn't have an extension but when I add a .pdf to my file and try to render it, it crashes.
After some tests I realised that when the PDF has two pages, and I go to the second page, it actually renders the pdf.
I have a problem reading a Strings file created dynamically inside my app's document directory.
Basically, I create and read my file using:
[[NSFileManager defaultManager] createFileAtPath:filePath contents:fileData attributes:nil];
NSLog(#"%#", [targetBundle localizedStringForKey:#"MY_STRING" value:#"#" table:#"test"]);
The file is created in the document directory, and the targetBundle also points to this directory.
The above code works very well when the strings file already exists in the document directory when the app runs.
So, if I delete the Strings file from the document directory, the NSLog displays: #.
When I run again the application (the file already exists), NSLog displays MY_LABEL's value.
I guess that the bundle loads its resources once at the launch, but how can I be sure to read my new file even if it has just been created?
Thank you for your help,
Julian
I didn't find how to reload a bundle but I fixed this problem by creating an empty file with the same name BEFORE the creation of the bundle.
With that, the bundle "knows" the file and if the file dynamically changes, the content is up-to-date (because the file is read at runtime).
I'm looking for a better way to download a bunch of files from my iCloud container to my sandbox. This is what I currently use:
for (FileAttachments *fileLink in items) {
NSURL *cloudFileURL = [fileLink urlForCloudAttachmentWithName];
NSURL *fileURL = [backupCloudLocalDirectoryURL URLByAppendingPathComponent: fileLink.fileName];
NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
[fileCoordinator coordinateReadingItemAtURL:fileURL options:NSFileCoordinatorReadingWithoutChanges error:&error
byAccessor:^(NSURL *newURL) {
NSError *blockError = nil;
[fileManager copyItemAtURL:cloudFileURL toURL:fileURL error:&blockError];
}];
}
}
Is there any problem with making a copy of the iCloud item this way? In production, I have some users complaining that all their files weren't downloaded. Is it better to use NSFileManager's startDownloadingUbiquitousItemAtURL:error instead? If so, why?
Thanks.
It's still not completely clear to me from comments how you're discovering the URLs, however some important details that affect your situation are:
Using coordinateReadingItemAtURL:block: has nothing to do with downloading files from iCloud. The purpose of NSFileCoordinator is to coordinate among readers and writers of a file so that, for example, you don't get two threads trying to write to the same file at the same time. You use file coordinators with iCloud because the iCloud system needs to read and write files and so does your app. Using a coordinator avoids corrupting the file, but again, has nothing to do with downloading the file.
To download a file from iCloud you need to use startDownloadingUbiquitousItemAtURL:error: and then wait until the file downloads. The normal flow here is:
a. Use NSMetadataQuery to find files that exist in the iCloud account
b. Use startDownloadingUbiquitousItemAtURL:error: to make sure they're available on the local device.
The reason you need to use this call is simply because that's how iCloud works on iOS. Files don't download until you ask them to download, and this is how you ask. [On OS X it's different, everything automatically downloads.]
You cannot simply copy from an iCloud URL to another location unless you already know that the file has been downloaded. The file-copy operation does not download the file, so if the file isn't available locally, the copy will fail.
You must use a metadata query to identify the files and their download status then, if they have not been downloaded initiate the download, and using the metadata query determine when the download is complete and then copy the file from the ubiquity container to the apps sandbox directory using a file coordinator. If you try copying the file while it's partially downloaded you may get some strange results.
I had the same problem with you.
My case is that: When network disconnects, iCloud service copy file from iCloud container to sandbox. When this line executes, it can not go into the block to copy file. This is the reason why this file can not be copied.
fileCoordinator coordinateReadingItemAtURL:fileURL options:NSFileCoordinatorReadingWithoutChanges error:&error byAccessor:^(NSURL *newURL)
My solution is: Before copying file from iCLoud container to sandbox, you must check network. If it is not available, don't execute this code (return method). If network connects, execute fileCoordinator and copy.
More info: When copy file from ICloud container to sandbox, method fileManager copyItemAtURL:toURL:error: is OK because I implement this method and it's good.
Hope this works.
I've created 2 test applications:
In the one the documents are included into the bundle and can be opened by using the quick look controller.
In the other app, the documents are downloaded. When I try to open the files the quick-look controller simply shows a message saying an error occurred. Strangely it will open downloaded PDF documents without any problems.
I suspect it has something to do with headers and mime-types, but I'm not sure on this. Would anyone know what the reason could be that downloaded .doc or .docx documents won't open and local documents will?
It turned out to be a problem with saving the downloaded files. At first I was writing the data to a filepath URL. This saved the data to the right location, but the type of file wasn't recognized anymore.
The solution was to use the default FileManager to save the file.
[[NSFileManager defaultManager] createFileAtPath:filePath contents:data attributes:nil];