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 :)
Related
I'm using NSCoding to manage a custom object with a few different fields, one of them images. I'm only targeting iOS 5.0+ and have switched to ARC. I have everything working but am focused on performance--I haven't seen a question like this asked, so here it goes:
I transform the UIImage into NSData and add it to the main NSCoding file (a plist, if it matters) for storage on the disk. If there is more than one image, the image names become sequential (e.g. image1, image2, image3.) I then use the image both in a UITableView (as a resized thumbnail) and in a detail view. The negative side to this is that the plist balloons in size, which means slow initial load times when I use it because it's loading all of the NSData at once.
What is the best way to eliminate this problem and only force the loading of one image at a time?
What I've thought of:
I write the NSData to the disk, add an array to the plist, and add only a reference to the filename of each image to the array. I suppose I'd then reference the image filename at specified position, find it on the disk, and use it?
Any and all thoughts would be most welcome. I'm more stuck on the conceptual implementation than anything else and, funnily enough, this is not an oft-discussed topic.
Thanks,
EDIT:
As requested below, here's an example of taking an image and turning it into NSData:
UIImage *originalImage;
NSData *imageData = UIImagePNGRepresentation(originalImage);
//I save it all to the app's document directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//I am using the images in a tableView and thus found it easiest to append the row number to each image filename.
//'y' below is just an integer that corresponds to the number of items in the master array
NSString *fileName = [NSString stringWithFormat:#"image%d.png",y];
documentsDirectory = [documentsDirectory stringByAppendingPathComponent:fileName];
[imageData writeToFile:documentsDirectory atomically:YES];
// NSLog(#"The filename is %#", fileName);
//newObject is an instance of my NSCoding object
[newObject setImageName: fileName];
Your suggestion is sound. Imagine a relational database. I would never save the images in one field as a blob. A filesystem is a very good place to save binary date in large amounts. It also gives you easy ways to duplicate files and so on.
So saving a reference in your plist will make parsing really fast and lazy loading an easy task to process images only when you need them.
iOS Programming: The Big Nerd Ranch Guide has a perfect example of this solution in chapter 14 of the 3rd Edition. Just download the code that is accessible from their site for a completed solution.
iOS Programming 3rd edition
Download Solutions
I am wanting to write my own logs to a text file on my iPhone. I wrote up a quick method that writes a string to a file. Right now it saves it into the Documents directory, which, if on the device is going to be a pain to get off, since I can't just browse to it. Is there a better way to quickly get this file off the device after I have written to it?
/**
* Logs a string to file
*
* #version $Revision: 0.1
*/
+ (void)logWithString:(NSString *)string {
// Create the file
NSError *error;
// Directory
NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"log.txt"];
// Get the file contents
NSData *localData = [NSData dataWithContentsOfFile:filePath];
if (localData) {
NSString *logString = [[NSString alloc] initWithData:localData encoding:NSUTF8StringEncoding];
string = [logString stringByAppendingFormat:#"%#\n", string];
[logString release];
}
// Write to the file
[string writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error];
}//end
Add Application supports iTunes file sharing to your application target's build info in Xcode:
Then, you can easily browse, retrieve and delete any files created by the app from iTunes, right under Devices > Your device > Apps > File Sharing:
You may have to capture what number of logs you have created so far and create a new name for each log biased on that.
So you might save your last made logs name as a string in NSUserDefaults and get the number off the end of that and add one onto that captured int ready for the next name.
So if you have #"Log4" you can get the 4 out of that and make it 5 so that the next log is named "Log5"
Just my 2 cents :P
With regard to the 'How to get the file' part of the question
iExplorer, previously iPhone Explorer allows you to view your apps, including their documents folder without jailbreaking your devices.
In my experience (albeit of an older version), getting the files from the phone can be a little temporamental (i.e. I drag a file onto my desktop and although it creates the file, it doesn't write any of the data), you can get the files from your device.
My app parses an xml file from my server, but I want to store parsed xml file and next start of my app, controller initially should load stored xml file, then controller should parse it again to check that there may be an update I did on xml file, if there is, new elements parsed should also be stored again.
I am referring to those app such as magazines, newspaper apps. When you open those kind of apps, it loads stored data that was downloaded previous session. Yet, after it loads, it starts to update the data, and it stores new update again.
Where do I start? What do you guys suggest?
Thanks in advance...
You can use CoreData or SQLite (use Objective-C wrapper FMDB https://github.com/ccgus/fmdb) to persist your XML. Then update the database everytime you see a unique id. Depends on how your XML data is.
It's actually quite easy to store to the documents directory. For example:
NSData *data; //this is your xml file
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docs = [paths objectAtIndex:0];
NSString *filename = [NSString stringWithFormat:#"test.xml"];
NSString *path = [docs stringByAppendingPathComponent:filename];
[data writeToFile:path atomically:YES];
Then to retrieve it later, you can get the path like above, but retrieve the file instead of writing it:
NSData *data = [NSData dataWithContentsOfFile:path];
either CoreData or SQLite can do the trick
Hi all i am trying to save image in the bundle which i have currently on my view,but the problem is that i can only save one image,if i want to save the another image it replaces the old.I am not getting how to save the multiple images in the bundle then.
Here is my code.
- (void)writeImageToDocuments:(UIImage*)image
{
NSData *png = UIImagePNGRepresentation(image);
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSError *error = nil;
[png writeToFile:[documentsDirectory stringByAppendingPathComponent:#"image.png"] options:NSAtomicWrite error:&error];
}
Please Help me out, how to save multiple images, files e.t.c in bundle
Thanks in advance
You're not saving into a bundle, you're saving into your app's documents directory. There's no bundle aspect to it.
You're using the filename #"image.png" for every file that you save. Hence each new write overwrites the old one. In fact, you write each file twice. To save multiple files, use different file names.
It's also bad form to pass a numeric constant as the 'options:' parameter of NSData writeToFile:options:error: (or indeed, any similar case). The value '3' includes an undefined flag, so you should expect undefined behaviour and Apple can legitimately decline to approve your application. Probably you want to keep the NSAtomicWrite line and kill the one after it.
If you're just looking to find the first unused image.png filename, the simplest solution would be something like:
int imageNumber = 0;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *pathToFile;
do
{
// increment the image we're considering
imageNumber++;
// get the new path to the file
pathToFile = [documentsDirectory stringByAppendingPathComponent:
[NSString stringWithFormat:
#"image%d.png", imageNumber]];
}
while([fileManager fileExistsAtPath:pathToFile]);
/* so, we loop for as long as we keep coming up with names that already exist */
[png writeToFile:pathToFile options:NSAtomicWrite error:&error];
There's one potential downside to that; all the filenames you try are in the autorelease pool. So they'll remain in memory at least until this particular method exits. If you end up trying thousands of them, that could become a problem — but it's not directly relevant to the answer.
Assuming you always add new files but never remove files then this problem is something you could better solve with a binary search.
File names searched will be image1.png, image2.png, etc.
I am writing an application that stores the movies in the photo roll into the local documents folder for the app. I can play remote movies using the MPMoviePlayer, however trying to play a movie stored in the documents folder for the app always returns MPMovieLoadStateUnknown.
The notifications are all getting sent and received from the default notification center (MPMoviePlayerLoadStateDidChangeNotification, MPMoviePlayerPlaybackDidFinishNotification).
An alert box shows up shortly after getting the loadStateUnknown message in the console, saying that the movie could not be played and the app then receives the movie playback completed notification.
I think that it may be a case that the filename (MPMoviePlayer can only take a URL as the asset location) cannot be found. Has anyone dealt with this issue or similar?
Given that none of the other answers seem to resolve the problem, I'm inclined to think that the problem might be with the Documents file path you are producing.
You should be using the following method to generate the path to the application's documents folder:
NSString *userDocumentsPath = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
if ([paths count] > 0)
{
userDocumentsPath = [paths objectAtIndex:0];
}
have you tried converting the local file path to a url
[NSURL URLWithString: [NSString stringWithFormat:#"file:/%#//",filePath]];
if there are spaces in you file path, you will have to convert them prior to creating the URL
filePath = [filePath stringByReplacingOccurrencesOfString:#"/" withString:#"//"];
filePath = [filePath stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
The Core Data template converts a file path to a URL like this:
NSURL *storeUrl = [NSURL fileURLWithPath:whatever];
That seems to do all of the correct space escaping and stuff because I'm using this to load a file with a space in the path.
I am not sure if this will help you.
In this tutorial there are some code lines which probably will bring you on the right path:
// Unless state is unknown, start playback
if ([mp loadState] != MPMovieLoadStateUnknown)
...
You will find this snippet in following method:
- (void) moviePlayerLoadStateChanged:(NSNotification*)notification
here is the link to the tutorial:
Tutorial
Hopefully this will help you...