merging two data objects - iphone

I have to merge two data objects and later separate them.Can anybody suggest me the way to go about it.It's urgent!!!!!!
please respond fast....
Thanks

Have a look at NSMutableData. Specifically, look at the appendData: and appendBytes:Length methods.
You can 'merge' two NSData objects by appending them to an empty NSMutableData object. You can then probably retrieve the data using getBytes:range: and reconstruct your NSData object with dataWithBytes:Length:.
Have a look at this article for working with mutable binary data (includes sample code).

Related

How to use my Class with PList in objective-c?

I have a Class for handling my data in my project, and now I need to store the data.
I'd like to use a Plist but I'm a bit unsure of how to start.
My class is pretty simple - 6 pieces of data, flat (no hierarchy).
I want my app to start with no data, so can I assume that I should create the PList programmatically once the User creates their first piece of data? (That is, don't create a .plist file in 'Supporting Files' prior to distribution?)
Then, when the app starts the next time, read the data and create an NSMUtableArray array of Class instances?
To create a property list, all you need to do is use appropriate types (i.e. those that support the property list format: NSData, NSString, NSDictionary, NSNumber, NSDate, NSArray), store them in a single container, and tell the containing object to write itself to a file. To read the data, you can initialize that same type using a path. For example:
// writing some data to a property list
NSString *somePath = ... // replace ... with the path where you want to store the plist file
NSMutableDictionary myDict = [NSMutableDictionary dictionary];
[myDict setObject:#"Caleb" forKey:#"name"];
[myDict setObject:[NSNumber numberWithInt:240] forKey:#"cholesterolOrIQ"];
[myDict writeToFile:somePath atomically:YES];
// reading the file again
NSDictionary *readDict = [NSDictionary dictionaryWithContentsOfFile:somePath];
The simplest way is to simple save an NSArray or NSDictionary to disk. Caleb's answer goes into detail there so I won't repeat it, other than to say you might have to convert a non-compatible object like NSColor to an property list object like NSData. It's up to you to do this each time you save or load your data.
NSKeyedArchiver and NSKeyedUnarchiver give you a little more control over the process, but work pretty much the same way. You provide (or get back) a plist compatible root object (usually an NSDictionary) that contains your data. I recommend creating a dictionary that includes your data structure as well as an arbitrary number (your app's build number is a good choice) to use as a version indicator. This way if you ever update your data model you can easily determine if you need to do anything to convert it to the new version.
If you're putting your own objects into the data file, look into NSCoding. The protocol gives you two methods using NSKeyedArchiver and NSKeyedUnarchiver to save and restore your data. This is by far the most straightforward approach if your data model consists of anything more than a few simple strings and numbers, since you're dealing with your own native objects. In your case, you would have your data class implement NSCoding and use the NSKeyedArchiver and NSKeyedUnarchiver methods to encode your six instance variables. When it's time to save or load, pack the instance of your class into an NSDictionary (along with a versioning number as I mentioned above) and call NSKeyedArchiver's archiveRootObject:toFile:. Your save an load methods deal only with your own data object, which makes things easy for you. The common pitfall to watch out for here is if your custom data object contains other custom object. This is fine, but you have to make sure every object that's going to be saved has its own NSCoding implementation.
Two things you can do:
Use NSUserDefaults:
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/Reference/Reference.html
The objectForKey method is the one you want to use to store your class. But, as pointed out in the comments, this shouldn't really be used for storing lots of user data; it's best for saving preferences.
For storing more data, you might want to look at Core Data. It's more complex, but should be better suited to your needs. Here's a tutorial on it:
http://mobile.tutsplus.com/tutorials/iphone/iphone-core-data/
Neither of these seems best for your simple application, but I leave this answer up since it gives alternatives for saving data to the iPhone.

Adding Instance Variable to NSData

So, I understand that Categories in Objective-C can be used to add methods to classes without the need for subclassing. I also understand that these Categories cannot be used to add instance variables to classes.
I did a little bit of reading about Class Extensions, which can be used to add instance variables, but I don't understand how I can use Class Extensions to modify an existing class such as NSData.
My problem is the following:
I have a Core Data Model that contains a NSURL and NSData. The NSData displays the data for the NSURL. When a view needs to display the data, I do the following check:
--- If [NSData bytes] > 0, display the NSData.
--- Otherwise, fetch the data at NSURL and display the data when it returns
Simple enough. However, I run into problems when the NSURL is updated. So, if I modify the NSURL path with a new image, because [NSData bytes] is already greater than 0, I don't make the additional call to fetch the new image.
What I would like to do is add an instance variable to NSData called URLKey that would hold information about where the data comes from. I can't subclass NSData because I'm using CoreData.
Does anyone know some simple solutions for this? Perhaps there's a gap in my understanding of Class Extensions, or maybe there's just no simple way.
Class Extensions should be used on classes you implement yourself as a way of keeping ivars and some properties hidden from the header File, that should contain only stuff that should be visible outside the class (and ivars are't that kind of stuff).
Categories are used on classes already implemented, as a way of adding additional functionality. They are usually needed when you want to add a general kind of behavior to a known Class. E.g. adding a method to NSString +(NSString*)reversedString; that returns a reversed instance so you can then use it like this:
NSString *someString = #"string";
NSString *reverse = [someString reversedString];
NSLog(#"%#", someString); //this would output "gnirts"
.
Regarding your particular problem, I can assure you that your CoreDataModel does not contain NSURL or NSData. The supported types are primitives, strings, binary Data and transformables. So, if you want to, you can subclass NSData or NSURL and then use it with CoreData by setting the type to "transformable". And after you have done this, you can then subclass NSData as you wish and use class extensions in the process, or just use a category to add the methods you require to the class.
Quote from Apple about transformable attributes:
The idea behind transformable attributes is that you access an
attribute as a non-standard type, but behind the scenes Core Data uses
an instance of NSValueTransformer to convert the attribute to and from
an instance of NSData. Core Data then stores the data instance to the
persistent store.

Is it possible to store an NSMutableArray together with all its contents into a file and restore it later from there?

Some kind of serialization available in iPhone OS? Is that practically possible or should I quickly forget about that?
I am making a tiny app that stores some inputs in an NSMutableArray. When the user leaves, the inputs should stay alive until he/she returns to continue adding or removing stuff to/from that array.
When the app quits, there must be some way to store all the stuff in the array in a file. Or must I iterate over it, rip everything out and write it i.e. comma-separated somewhere, then the next time go in again, read the stuff in, and iterate over the lines in the file to make an array with that data? That would be hard like a brick. How to?
The easy way, since you already have an NSArray object is to write the array to disk using
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)flag
and read it back in with:
- (id)initWithContentsOfFile:(NSString *)aPath
or
+ (id)arrayWithContentsOfFile:(NSString *)aPath
You can also use NSCoder.
You can probably search sof for the right code.
So long as the objects in the array implement NSCoding (NSString and NSValue do; if you're storing your own objects it's relatively straightforward), you can use:
[NSKeyedArchiver archiveRootObject: array toFile: filePath];
to save and:
array = [NSKeyedUnarchiver unarchiveObjectWithFile: filePath];
to load.
You can similarly load/save to NSData.
The iPhone SDK is designed to store data using SQLite tables.
You can use NSPropertyListSeralization, since NSArray is a type of property list. You can find more information here.

Separate NSData into smaller NSMutableData objects

I am unsure of how to separate a NSData object into smaller parts so that I can send it over bluetooth. I believe it is a method similar to this:
- (void)getBytes:(void *)buffer range:(NSRange)range
I do not know what to pass in for the buffer. Do I just pass in a NSMutableData object to hold the bytes that I pull out of the original NSData?
Thanks
You can use the -subdataWithRange: method.

Saving an NSMutableArray to Core Data

I want to add an NSMutableArray of NSStrings to one of my Entities in my core data model. The problem is that this isn't a supported type in Core Data.
I tried making a tranformable attribute, but the problem is that I see no way of turning a NSMutableArray to NSData, and then going from NSData, back to an NSMutableArray. Does anyone have an idea as to how this issue can be solved?
(I know I can archive the array, but I don't want to do that, I want it to be present in my model).
You could have a binary data attribute in your modeled object, archive the array to data, and hand it off to the object.
But I think the better way would be to have a to-many relationship, instead of using an array directly.
****Edit: Here's how to archive the array into NSData so that it can be used in your managed object***
NSData *arrayData = [NSKeyedArchiver archivedDataWithRootObject:[NSArray arrayWithObjects:#"1",#"2", nil]];
Basically, any class you have which conforms to the NSCoding protocol can be archived in this way. NSArray/NSMutableArray already conform to it. They tell all of their objects to archive themselves, so they must conform too. And all of those objects' members must conform, etc. It's like a tree.
Since your array conforms, and it's an array of NSString (which also conforms), then you're golden.