Getting writeToFile:atomically: URL saved to - iphone

I'm saving some NSData with writeToFile:atomically: and then want to use that file very shortly afterwards. What is the easiest way to get the NSURL of the file I just saved?

[NSData writeToFile: atomically:] has a path parameter.
Just make the path parameter into a file URL and save that as an instance variable or property and you'll be all set.
Or even better, use [NSData writeToURL: atomically:] (i.e. convert your path into a URL to start with) and save that as a property or instance variable to be used later on.
You can convert a path into a file URL via [[NSURL alloc] initFileURLWithPath:].
And lastly, the real answer to the question you're trying to ask is: no, you can not divine the path or URL from an arbitrary "NSData" object. You'll have to save that information separately or alongside your data in order to keep track of where it came from.

Related

Specify file offset when creating NSData with contentsOfFile arguments

I am trying to implement a file uploader using NSURLSession.
The file to be uploaded is specified as:
var data: NSData = NSData(contentsOfFile: path)
Suppose, the upload fails for some reason & assuming that I can get an offset to resume upload from.
Is it possible to specify in NSData that we have to start from a given offset (something like do a seek before doing the upload)?
There's a class named NSFileHandle. Personally I never used it but it seems like it does what you need. It has seekToFileOffset method and availableData property so I think you can try it

Extracting array of images from url

After doing some research I am a little confused. I can grab a single image from a url if I know the exact directory for example,
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://www.myUrl.com/pic/workaholics.png"]]];
UIImageView *view1 = [[UIImageView alloc] initWithImage:image];
[self.view addSubview:view1];
This of coarse works fine, but what if you didn't know the exact path. In Linux you could always do some sort of recursive search but with iOS I can't figure it out. For example, in the "pic" directory that I specified in the latter case what if there was other directories called pic1,pic2,pic3 etc and each directory had an arbitrary number of png's. What I am having a hard time wrapping my head around is how can I recursively search the "pic" directory to extract all directories contents that match .png. I would of coarse then store this is NSData and convert to a string and then store the contents in an array. I'm very much confused at this point. Any help would be greatly appreciated.
Your difficulty here will be getting a directory listing from a web server - since you are retrieving the images over the web. Many web servers will not provide a directory listing as a security measure against hacking attempts.
if you control the web server, you can reconfigure it to provide a directory listing - then make an NSData object from the directory level URL (http://www.myUrl.com/pic/) - and parse this to pull out all the files within the directory. You can then request each individual picture and add it to an array yourself.
if you don't control the web server, but can write to the directory, you could achieve a similar implementation by creating a manifest file (XML-plist would be a good format) which lists the filenames contained in the directory. You'd need to update the manifest any time you added a new picture to the directory though.
otherwise - you have to do some pretty dirty/hacky things, like assuming there are no more than n pictures, all pictures have the filename "pic_m.png" and then iterating through a loop from 0 to n attempting to retrieve each file until you hit a failure.
UIImage needs an explicit thing (URL or filepath) to get its data from.
One potential solution is to implement searching for your .png files via NSFileManager's enumeratorAtPath: method. The reference guide I've linked to even has a code fragment you can use to to create UIImages (just switch the #"doc" to #png and instead of doing scanDocument, do your UIImage * image = ... thing).
I'll leave it as an exercise to figure out how to do it recursively, but I hope my answer helps you out!
NSURL *url = [NSURL
URLWithString:#”www.ArticleDean.com\images\sample.jpg”];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [[UIImage alloc] intiWithData:data];
try this one

how to rename image captured in objective c?

In my application I need to capture image as well as save it on local library and on server using FTP. Now I need to follow a format for image name while saving it on the server. I am able to capture and save the image on local library. But I am unable to find any method to change the name of the Image. Suppose I need to rename it as Productname-UserId.png Is there any way? Kindly help.
Thank you.
UIImagePNGRepresentation(UIImage*) is likely what you're looking for. You can save a UIImage as a PNG file in the Application Documents folder, then upload that to a server. The code to do this is quite trivial, so if you could post the code you're trying to use, that would be helpful to understanding, and recommending a solution for you.
Here's a short clipping from my code that does exactly this:
UIImage * image; // Some image you want to send
NSString * docDirWithSlash = [[self applicationDocumentsDirectory] stringByAppendingString:#"/"];
NSString * pngFile = [docDirWithSlash stringByAppendingString:file]; // <-- Change the string "file" to reflect the name you want.
[UIImagePNGRepresentation(image) writeToFile:pngFile atomically:YES];
// Send pngFile to the server here
Where applicationDocumentsDirectory looks like this:
- (NSString *) applicationDocumentsDirectory
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
return documentsDirectoryPath;
}
The real question here is where do you want the file name to be specific? On the device or on the server. In case of device use Charles answer, otherwise you should look at http protocol(file upload part). Actually it doesn't matter what name the file have on you local device, as when you send it to the server over http, you can provide any name. The tricky part here is that the server you are uploading to should take that parameter into account when saving that file. So if you are uploading to a server that you don't have hand on and it does some self naming convention - you probably stuck. If it's yours - look at how you're saving files on the server side and if you are taking in account that "filename" parameter...P.S. And don't forget to pass that argument to the upload request :)

NSURL into NSData (Cocoa error 256.)

I need to serialize my NSURL.
object is type of NSManagedObject.
NSURL *objectURIRepresentation = [[object objectID] URIRepresentation];
NSError *error = nil;
NSData *objectIDData = [NSData dataWithContentsOfURL:objectURIRepresentation options:NSDataReadingMapped error:&error];
I get error: (Cocoa error 256.).
Any ideas? Something tells me, using dataWithContentsOfURL: is not good idea.
Update
One more question which is put as a comment mistakenly:
What is the difference between [NSData dataWithContentsOfURL:uri]; and [NSKeyedArchiver archivedDataWithRootObject:uri];?
Thanks.
Firstly, your code does not attempt to serialize a NSURL object, it attempts to create a data object out of the data at the URL returned as the URI of a managed object.
Secondly, that is never going to work.
[NSData dataWithContentsOfURL:] will try to read a file at a particular URL. The URI of a managed object represents an object stored in pieces with many others inside a persistent file like a SQLite database.
The URI only allows a managed object context to identify a particular object in its own store. The URI is gibberish to anything else other than the context.
NSManagedObject does not implement the NSCoder protocol so managed objects cannot be serialized. I'm not sure what you want to do here but you can't do it this way.
As mentioned here Cocoa error 256 core data
error code 256 can occur when an unknown error is occurred in reading the resource or the path has some encoded characters in it.
What it seems to me is you are trying to get the data from NSManagedObject. Hence as #fluchtpunkt suggested you should look for http://cocoawithlove.com/2008/08/safely-fetching-nsmanagedobject-by-uri.html
Now coming to your second question [NSData dataWithContentsOfURL:uri]; returns data for a web url or a local resource in your documents directory. While [NSKeyedArchiver archivedDataWithRootObject:uri]; returns the NSData object containing the encoded form of the object graph whose root object is given.
try to add "Http://" before in the link

Store preferences in a file and import values to initialize variables

I want to store the content of some variables in a file. The user nor the application should change the value. It would be great if the user cannot read the content of this file. On startup the application reads the file and initialize some (global?) variables with the content.
The file should contain some values like server URL and so on. This could change, but I only want to manage a preference file rather than updating the source code. On an update for example only the preference file will get exchanged.
How can I manage that?
NSUserDefaults is not intended for such issues I think. Should I use a a plist or a normal txt file?
How would the access to the content of the file look like?
Cheers
Sounds to me like NSUserDefaults is exactly what you need. It will let you store URLs (as strings) and other basic types of variables.
Why do you think NSUserDefaults is not the right solution here?
Give it a try! It's easy to use and reliable.
Use a plist. You can load it with -[NSDictionary initWithContentsOfFile:] (you can save a dictionary to a plist just as easily with -[NSDictionary writeToFile:atomically:], though it doesn't sound like you need to do that).
So the solution I'll use is that I load a plist file as default value for my NSUserDefaults:
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Settings" ofType:#"plist"];
NSDictionary *settingsDict = [NSDictionary dictionaryWithContentsOfFile:filePath];
[[NSUserDefaults standardUserDefaults] registerDefaults:settingsDict];
NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
NSString *serverURL = [settings stringForKey:#"ServerURL"];
NSLog(#"%#", serverURL);
Taken from iPhone App : Where do I put a config file?
So I'll use both plists and NSUserDefaults. settings I'll define as global variable in the main.m. One problem remains:
How to differentiate between user defaults and system defaults?