iPhone:Convert NSMutableArray to NSData with stored & retrieved issue - iphone

I am facing a problem, that is to convert NSMutableArray into NSData and stored & retrieved that array into rootviewcontroller so please give me idea. Here is the code I'm working with:
appDelegate = (FindNearMeAppDelegate *)[[UIApplication sharedApplication]delegate];
appDelegate.isCategoryCell = TRUE;
appDelegate.isButton = NO;
NSString *categoryStr = categoryName.text;
NSLog(#"Category Name:--->%#",categoryStr);
appDelegate.categoryData = [NSMutableDictionary dictionaryWithObjectsAndKeys:
categoryStr, #"name",image ,#"image", nil];
[appDelegate.categories addObject:appDelegate.categoryData];
NSLog(#"Category Data:--->%#",appDelegate.categories);
I am initialize nsmutablearray (appDelegate.categories) and nsmutabledictionary in appdelegate.
Thanks in advance.

From what I understand, you want to save your images and retrieve them. You can convert your image to NSData using one of the 2 methods, UIImagePNGRepresentation or UIImageJPEGRepresentation depending on the type of the image. You can then save this data-
NSData* imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:imagePath atomically:YES]; //imagePath is where you want to save it. Most likely it contains the value of the name key in your dictionary.

Related

NSArray to NSData for Core Data

I need to save array in core data, so i read that I can use NSData for it. So I think that I have problem with archiving.
NSMutableArray *newArray = [[NSMutableArray alloc]init];
NSData *newData = [NSKeyedArchiver archivedDataWithRootObject:newArray];
[myEntity setValue:newData forKey:#"nameOfMyData"];
And then I try to pick my array in another VIewController for filling
NSData *newdata = [NSData dataWithData:self.myEntity.nameOfMyData];
NSMutableArray *photoArray = [[NSMutableArray alloc]init];
photoArray = [NSKeyedUnarchiver unarchiveObjectWithData:newdata];
I have no crash, but in command line appear next:
[NSKeyedUnarchiver initForReadingWithData:]: data is empty;
did you forget to send - finishEncoding to the NSKeyedArchiver?
And when i try to add object to my array, it does not add
[photoArray addObject:myImage];
So myImage is creating and with it I have no trouble, but in debugger always write for photoArray:
photoArray = (NSMutableArray*) 0x00000000 0 objects
It should work. But when unarchiving the array rather use:
NSData *newdata = [NSData dataWithData:self.myEntity.nameOfMyData];
NSMutableArray *photoArray = [NSMutableArray arrayWithArray: [NSKeyedUnarchiver unarchiveObjectWithData:newdata]];
You either have objects in your array that dont conform to NSCoding protocol or you do not save your core data context (or saving is unsuccessful).
After archiving with
NSData *newData = [NSKeyedArchiver archivedDataWithRootObject:newArray];
what do you see when you check newData for nil? I suppose it is nil.

store image array in nsuserdefault

I have created an ios application where i need to store image array into nsuserdefaults. When restart the app again the storing image need to show in a scroll view. How can i store image array and get the array from nsuserdefault . Thank in advance.
try this
NSData *dataVal = [NSKeyedArchiver archivedDataWithRootObject:val];
[defaults setObject:dataVal forKey:keyName];
[defaults synchronize];
Try This
for(int val=0;val<[imageArray count];val++){
// imageArray is an Array which contains the Image Names
// See below converting the
NSData *imgData = UIImagePNGRepresentation([UIImage imageNamed:[NSString stringWithFormat:#"#%d",[imageArray objectAtIndex]val]]);
//add this `imgData` into dataArray(Which is An NSmutableArray don't forget to Allocate it)
[dataArray addObject:imgData];
//then Store this Array to NSuserDefaults
[[NSUserDefaults standardUserDefaults] setObject:dataArray forKey:#"key"];
}
// the Get the Stored Data Array from NSuserDefaults.
NSMutableArray* storedDataArray=[[NSMutableArray alloc] initWithArray:[[NSUserDefaults standardUserDefaults]objectForKey:#"key"]];
//`storedDataArray` array contains the ImageData(NSData)
//Use it As you want
NSData *imgData = UIImageJPEGRepresentation(YOURIMAGE,1.0);
// Now store the NSData in the defaults for a key
then load it like this
UIImage *image = [UIImage imageWithData:[defaults objectForKey:#"Image"]];

Why NSMutableDictionary don't want write to file?

- (void)viewDidLoad
{
[super viewDidLoad];
if ([[NSFileManager defaultManager] fileExistsAtPath:pathString])
{
infoDict = [[NSMutableDictionary alloc] initWithContentsOfFile:pathString];
}
else
{
infoDict = [[NSMutableDictionary alloc]initWithObjects:[NSArray arrayWithObjects:#"BeginFrame",#"EndFrame", nil] forKeys:[NSArray arrayWithObjects:[NSNumber numberWithBool:YES],[NSNumber numberWithBool:YES], nil]];
if ([infoDict writeToFile:pathString atomically:YES])
{
NSLog(#"Created");
}
else
{
NSLog(#"Is not created");
NSLog(#"Path %#",pathString);
}
}
This is my code. I check if file is created, if not - I create a NSMutableDictionary and I write it to file at path, but writeToFile method returns NO. Where is problem? If I create this file with NSFileManager it works, but doesn't when I want to write a dictionary.
writeToFile:atomically only works if the dictionary you call it on is a valid property list object (see docs).
For a NSDictionary to be a valid property list object, among other things, its keys must be strings, but in your example the keys are NSNumber instances.
You can not control the content you are going to write sometimes. For example, you can't avoid a null value when you are going to write a JSON object that is gotten from a server.
NSData is compatible with these "invalid" values, so converting NSArray or NSDictionary to NSData is an ideal way in these cases.
write:
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:jsonObject];
[data writeToFile:path atomically:YES];
read:
NSData *data = [NSData dataWithContentsOfFile:path];
NSDictionary *jsonObject = [NSKeyedUnarchiver unarchiveObjectWithData:data];

To add UIImage directly to file

I want to add my UIImage directly into the file instead of converting into UIImagePNGRepresentation or UIImageJPGRepresentation(as it takes time) like:-
UIImage *im = [UIImage imageWithCGImage:ref];
[array addObject:im];
NSData *data = [array objectAtIndex:i];
[data writeToFile:path atomically:YES];
But it is showing error.
So there is any way that i can do it.
Thanks in Advance.
your use of the array only obfuscates that you are basically doing:
NSData *data = im;
Which cannot possibly work because im is a UIImage, and not an NSData nor a subclass.
What you want to do is to create a new NSData and initialize it with the content of the image. Since you got a CGImageRef, I suggest using it directly, without using a UIImage in between.
CGDataProviderRef imageDataProvider = CGImageGetDataProvider(ref);
CFDataRef imageData = CGDataProviderCopyData(imageDataProvider);
NSData *data = (NSData*) imageData;
Note that it is OK to cast the CFDataRef to NSData* because CFData is “toll-free bridged” with its Cocoa Foundation counterpart, NSData.
I hope that helps.
(don't forget to release data when done)

How to convert NSArray to NSData?

Can anyone tell me how to convert an NSArray to an NSData? I have an NSArray. I need to send it to an NSInputStream. In order to do that I need to convert the NSArray to an NSData.
Please help me, I'm stuck here.
Use NSKeyedArchiver (which is the last sentence of the post Garrett links):
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:array];
Note that all the objects in array must conform to the NSCoding protocol. If these are custom objects, then that means you need to read up on Encoding and Decoding Objects.
Note that this will create a fairly hard-to-read property list format, but can handle a very wide range of objects. If you have a very simple array (strings for instance), you may want to use NSPropertyListSerialization, which creates a bit simpler property list:
NSString *error;
NSData *data = [NSPropertyListSerialization dataFromPropertyList:array format:NSPropertyListBinaryFormat_v1_0 errorDescription:&error];
There's also an XML format constant you can pass if you'd rather it be readable on the wire.
On a somewhat related note, here's how you would convert the NSData back to an NSArray:
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:data]
I used this code.
NSError *error;
NSMutableData *jsonData = [[NSJSONSerialization dataWithJSONObject:yourDemoArray
options:0 // Pass 0 if you don't care about the readability of the generated string
error:&error] copy];
Swift :
let data = NSKeyedArchiver.archivedData(withRootObject: jsonArray)
print(data)
You can do this-
NSArray *array= [NSArray array];
NSData *dataArray = [NSKeyedArchiver archivedDataWithRootObject:array];
In iOS 9+ use this please:
NSArray *array = [[NSArray alloc] init];
NSData *data = [NSPropertyListSerialization dataWithPropertyList:array format:NSPropertyListBinaryFormat_v1_0 options:0 error:nil];
The older version of this was deprecated in iOS 8.
Swift 5
let data = try! NSKeyedArchiver.archivedData(withRootObject: array, requiringSecureCoding: true)