Check if file is saved in documents directory - ios

In my application, when I press on a button, I download a file from the internet, and then I read it. The only thing is that the file takes about five seconds to load, depending on the speed of the network, but since the file gets bigger and bigger, the time needed increases. If i save the file and after run the code to read it, the code runs but the file is not their, because it doen't wait the file to load. So I added an NSTimer of 6 seconds and it works. But if the file gets bigger I would need to change it. Is there a code to run the code to read the file, once the load is completed??
Thanks for the help
Since I use dropbox I can use this code (just found out):
- (void)restClient:(DBRestClient*)client loadedFile:(NSString*)localPath {
}
but it runs every time a file is downloaded, and I would like to run it for every 2 files loaded...

- (void)restClient:(DBRestClient*)client loadedFile:(NSString*)localPath {
NSLog(#"%#",localPath); //just to see the console log of what this method spits out
NSString *documents = ***DOC_DIRECTORY_METHOD***;
NSString *expectedFilePath = [documents stringByAppendingPathComponent:#"myDownloadedFile"];
if ([localPath isEqualToString:expectedFilePath]) {
//insert my read file method here
}
}
I don't know what the variable localPath will output, either the full path or just the name of the file. You might have to tweak this.
Good luck.

Related

Dropbox SDK bug

I was found something strange when I using Dropbox SDK 1.3.14
And here is how the bug happen , I put a dictionary tree like
/Comic/Author - Comic name (ex.浦澤直樹 - Monster)/Volume1/0.jpg , 1.jpg , ...)
And I want download the jpg to iOS app,And also create the same dictionary tree as Dropbox
So I create a dictionary tree in Document , It looks like
/var/mobile/Containers/Data/Application/12711FE6...290C7EAF50/Documents/Dropbox/Comic/浦澤直樹 - Monster/Volume1
Than I try to download the first page of comic
But it shows an error tell me the dictionary is not exist .
I use NSFileManager to check , It did exist .
Finally I find the problem
At this callback
- (void)restClient:(DBRestClient *)client loadedMetadata:(DBMetadata *)metadata {
for (DBMetadata *file in metadata.contents) {
NSLog(#"File Path : %#",file.path);
}
}
Path will print like this
1./Comic
2./Comic/浦澤直樹 - Monster
3./Comic/浦澤直樹 - Monster/Volume1
4./Comic/浦澤直樹 - monster/Volume1/0.jpg
Now at the last file path , it gives me a different path name
I don't know why , but if I use this path to check is the parent dictionary is ready , It will return false.
So I never can download the file to specified path success
I was wonder does anyone got same issue like me ?
Dropbox itself is case-insensitive, with attempts to be case-preserving. However, due to various specifics, the API can't always return the expected case for every path component. So, for any file or folder metadata, the filename/last path component should have the preserved case, but other path components are not guaranteed to.
We realize this is non-ideal of course and are looking into ways to improve it, but I don't have a solution to offer right now.
If you need the preserved casing, you'll need to build it up from the last component in each parent entry.

Steps to get the list of pdf files from FTP in IOS

I'm new to IOS Development. This is the first time i'm hearing about FTP in IOS .I'm not getting, How to proceed further . I got this code https://developer.apple.com/library/ios/samplecode/SimpleFTPSample/Introduction/Intro.html .
But i didn't understand from this code .
I need to list the pdf files and folders from FTP . First i don't know how to establish the connection to FTP . Can any one please help me with steps.
I fyou look in ListController.m, listOrCancelAction is called when you click on List button.
In turn if you put a break point in startReceive you would see that
CFReadStreamCreateWithFTPURL is opening a "Open a CFFTPStream for the URL" with a specified URL.
I suggest you put a couple more break points and step through the code?
NSStreamDelegate is being used as callbacks when something is happening in particular
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
is called when connection is open or data is received.
Hope this is enough to get you started.
entryToAdd = [self entryByReencodingNameInEntry:(__bridge NSDictionary *) thisEntry encoding:NSUTF8StringEncoding];
in parseListData will have file name in kCFFTPResourceName which of course you can parse to find out if it is a PDF file. You may look at kCFFTPResourceType to see if you can use to determine file type, not sure.

(IOS) Cordova Camera Plugin Referring to deleted images

I'm building a cordova app (primarily for IOS & Android) in which the user can take an image, retake (, etc.) it and save it locally.
I'm currently struggling with the cordova cameraPlugin. So, here a short description of the problem.
When the user takes an image, it's saved locally in the apps temp folder and the user is able to view in in the UIWebView. On retaking, the image will be deleted from the temp folder and should not be available any longer (in RAM and local FS).
It works as long as the user doesn't retakes the image 2 or more times, if he does instead of the last image the first image will be referenced/rendered in WebView. After reopening the app, the image is displayed correctly.
An Example:
The user takes the first image. ==> cdv_photo_001.png
The second. ==> cdv_photo_002.png and the first one will be deleted (which seems to work correctly)
And the third. ==> cdv_photo_001.png and the second image will be deleted.
The third image will look the same as the deleted first one. This happens with every image after the third one.
It works fine after restarting the app
I've already tried to disable the App-Cache, delete the app cache before updating the image, refreshing the page and looking for answers online.
I'm getting an error when opening the camera UI, but I could not find a solution for it either.
Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before
snapshotting or snapshot after screen updates.
The code for the camera Call:
function getPhoto() {
navigator.camera.getPicture(getPhotoOnSuccess, getPhotoOnFail, {
quality: 25,
destinationType: Camera.DestinationType.FILE_URL,
correctOrientation: true,
encodingType: Camera.EncodingType.PNG
});
}
In getPhotoOnSuccess I'm basically saving the image path to a db and appending it with jQuery to the view.
And the code to delete the image: (sidenote I`m new to Objective C)
- (void) deleteImageByPath:(NSString *)imagePath withSelector:(SEL)selector{
NSError *error = nil;
NSFileManager *mgr = [NSFileManager defaultManager];
NSString *tempFolder = NSTemporaryDirectory();
if([mgr removeItemAtPath: imagePath error:&error] == NO) {
NSLog(#"File deleted");
}
//The files can be edited as well, so there can be two files in different directories
if(error != nil){
NSString *imgEl = tempFolder;
imgEl = [imgEl stringByAppendingPathComponent:imagePath.lastPathComponent];
if(![mgr removeItemAtPath:imgEl error:&error]){
NSLog(#"Old element couln't be deleted.");
}
}
[self performSelector:selector withObject:error];
}
The file is not in the directory anymore after deleting it, so I guess it works.
An important detail could be, that I wrote my own IOS cordova plugin, because the method for the file system access provided by cordova sucks.
So thats it.
The specific question is: Why and how is this happening and is there a chance to change this behavior? If yes, how should I proceed?
By the way, I`m using cordova 3.1.0 and the build target is IOS 7.
Thanks in advance.
Ok folks, I finally got it.
The whole problem was not related to my code or any of the cordova code.
So why did it happen? ==> I don't exactly know that, for it seems that this bug or whatever you might call it, has occurred to many people.
And they all tried to delete or deactivate the cache as I did, some of their problems are very close to my own but most aren't, so it took a while til I found a solution.
I read this thread and tried to append a timestamp to the image path and it worked!
My conclusion to this it, that there might be a problem with the UIWebView and the cache management.
Or it might proof as a general WebView problem, I will be able to check that in a few days on an Adroid device.

Does NSFileWrapper load everything into memory?

Lets say I have an NSFileWrapper directory. This directory is made up of several levels of directories and files. Some of the files are large. Are all these files loaded into memory, or are they lazily loaded?
If they are loaded into memory, are there any alternatives to NSFileWrapper with similar functionality that won't load files into memory? Something I can hook into UIDocument?
This is for a document based application, which uses UIDocument's that are synced with iCloud. A document can have images and videos embedded inside it. Each image/video has a preview image (thumbnail) that is shown in an HTML document. The full size images or videos shouldn't be loaded into memory, but rather loaded on demand.
I also need a way to add a resource without loading it into memory. Something like "initWithAsset:(ALAsset *)" would be ideal.
I've made an app a while ago that generates a video. This video was then saved to a specific file format using a UIDocument subclass.
The only way to make the app not run out of memory while executing contentsForType:error: was to output the video to a file in the tmp dir and init the filewrapper with the url to the video with NSFileWrapperReadingWithoutMapping-option to prevent it from loading the video to memory and just copy in the file.
- (id)contentsForType:(NSString *)typeName error:(NSError **)outError {
if (self.fileWrapper == nil) {
self.fileWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
}
if (self.videoURL != nil) {
NSError *fileReadError;
NSFileWrapper *videoFileWrapper = [[NSFileWrapper alloc] initWithURL:self.videoURL options:NSFileWrapperReadingWithoutMapping error:&fileReadError];
if(fileReadError){
NSLog(#"File read error: %#", [fileReadError localizedDescription]);
}else {
[videoFileWrapper setPreferredFilename:#"video.mov"];
[self.fileWrapper addFileWrapper:videoFileWrapper];
}
}
//...
}
It's not totally clear from the documentation, but I'm 99% positive that NSFileWrapper will memory-map everything. The main use case for NSFileWrapper is to embed files inside documents, where you'd presumably need access to said file at all times.
What are you trying to use the file wrapper for? I assume if you're mapping an entire directory it's not necessarily to embed media inside a document, but perhaps I'm mistaken. If you maybe talk a bit more about your use case, as that will influence what alternatives you might go for.

How to slow down UIDocument's initial loadFromContents:ofType:error:?

When I drag a file package from Finder into the iTunes.app file sharing pane, my UIDocument class is trying to read in the associated file wrappers, and it appears my code to read it is executing faster than iTunes.app can copy the contents over. The initial file wrappers array contains only one of the two files inside the wrapper.
So how do I "slow" my code down?
I ran a test using performSelector:withObject:AfterDelay:1.0f, and that worked fine, but that feels really risky: What if a really large file is dragged in to iTunes (by really large I mean one that exceeds my delay)? What if multiple files are all dropped on at the same time?
I looked at somehow discerning that the file is ready to be read, but Apple's NSFileManager documentation says
"It's far better to attempt an operation (such as loading a file or
creating a directory), check for errors, and handle those errors
gracefully than it is to try to figure out ahead of time whether the
operation will succeed."
But where the timing problem comes up is during the decoding of the constituent file wrappers, so how to handle it "gracefully" is eluding me.
My package file has two data files within it (at this early stage, but the design is because there will be more): data.dat and info.dat. When I first got code working to the point where I could drag a file into iTunes.app and notice it in my view controller, data.dat was always decoding fine, but info.dat was not found. Once the file is inside my local documents folder, the view controller presents all the data as expected (i.e. info.dat is inside the file wrapper and correctly formed). Suspecting this to be a timing issue, I renamed the filename constants and on-disk files to zdata.dat and ainfo.dat -- sure enough: ainfo.dat loads and my UIDocument subclass complains that zdata.dat wasn't found.
I use lazy loading, but the view controller has an immediate interest in the info.dat contents, so lazy loading isn't lazy enough for iTunes to get through copying!
From my UIDocument subclass implementation:
- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError *__autoreleasing *)outError
{
self.fileWrapper = (NSFileWrapper *)contents;
// Lazy load everything!
_data = nil;
_metadata = nil;
return YES;
}
- (id)decodeObjectFromWrapperWithPreferredFilename:(NSString *)preferredFilename
{
NSFileWrapper *fw = [self.fileWrapper.fileWrappers objectForKey:preferredFilename];
if (!fw) {
NSLog(#"Unexpected error: Couldn't find %# in the file wrapper for %#", preferredFilename, self.fileURL);
return nil;
}
NSData *data = [fw regularFileContents];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
return [unarchiver decodeObjectForKey:#"data"];
}
- (GSBMetadata *)metadata
{
if (_metadata == nil) {
if (self.fileWrapper != nil) {
// NSLog(#"Loading metadata for %#...",self.fileURL);
_metadata = [self decodeObjectFromWrapperWithPreferredFilename:kGSBMetadataFileName];
} else {
_metadata = [[GSBMetadata alloc] init];
}
}
return _metadata;
}
The problem is discovered in decodeObjectFromWrapperWithPreferredFilename: when the check is made to ensure that the expected file wrapper is present. Normally this would be the case if the file was corrupt, or perhaps version 2 of the app used a different file format. But gracefully handling those circumstances fall under the heading of "paranoid programming expected that sort of thing" and not under the heading of "just wait a second and all your data will be available to you."

Resources