Objective-C - Serialize/De-serialize multiple arrays to/from a local file - ios

I've read some SO posts here and there on how to write arrays to file but I'm having issues trying to figure out how to write (serialize) multiple arrays to a single file then read back later. Based on what I've read so far I think the easiest way might be to use
[array writeToFile:filePath atomically:YES];
but what's the best way to handle writing multiple arrays to a file? My understanding is that each time you use the above method that it will re-write the entire file.
I have 8 arrays I need to serialize, and I would like to use newline (\n) to separate each array onto a new line in the file. Can anyone provide guidance/psuedo code/Objective-c code for accomplishing this?

You can put all your arrays in to another array and save that array.
NSArray *arrayToSave = #[array1, array2, array3];
[arrayToSave writeToFile:filePath atomically:YES];

Put all the arrays into an NSDictionary, write the dictionary.

Methods like NSArray's writeToFile:atomically: method create property lists, which are specific kind of file unique to Cocoa/Cocoa touch. On recent platforms those methods create XML property lists.
You won't get an array per line with newline characters between them with property lists. The file will have XML tags in it, and newlines added for visual clarity. The newlines are not meaningful in the data format however.
If you want a particular byte format for your data, you'll need to write your own methods for serializing your arrays.
What makes you think you need newlines between the arrays?

Related

Decoding only part of a JSON using Codable protocol

I have a JSON which contains an array of dictionaries and I decode it, using Swift's JSONDecoder class.
I wonder, is it possible to make the class to decode only some dictionaries, not all, for example (maybe based on some criteria)? I guess, this might be useful if the array contains many dictionaries, but you don't want all of them but only a single one.
If you know how to do this, I would appreciate your help.
Technically one can write an init(from:) method that manually gets the container for the decoder and then get the "nested" container (e.g., nestedUnkeyedContainer), and manually decode the items within that collection, only adding the ones you want. See Encoding and Decoding Custom Types for an introduction to writing init(from:) methods.
But I would discourage you from doing that. It's going to be much simpler and logical to parse the whole JSON and then filter the resulting collection to distill it down to the ones you want.
Unless you have a lot of records (e.g. millions?) where the parsing overhead becomes observable, I would suggest performing a decode the entire JSON and then filter your array. This will require far less code and is the more logical approach.
And if you had that many records, before I contemplated the init(from:) kludge, I would reconsider using JSON at all. I'd use CoreData or SQLite or something like that which is better suited for dynamic filtering of data as it is being extracted.

How to parse a JSON file line by line in objective c

I am working with very large JSON files, so I do not want to read the entire file and then iterate and parse each data entry.
Instead, I would like to iterate on the JSON file itself (for example: line-by-line/one object at a time).
I thought about holding the next line location as part of the current line data, so the JSON is a semi linked list, but I did not manage to extract a specific line from the JSON file.
Am I missing an easier way to achieve that? Is it even possible to extract and parse a specific line from a JSON file?
Thanks a lot!
JSON is not a line oriented format, so the idea of parsing "line by line" doesn't really make sense.
That said, there is at least one event-driven JSON parser for iOS that I know of, https://github.com/stig/json-framework. The built-in parser NSJSONSerialization only works on entire files.

best way to serialize native C array

I'm currently using NSCoding to serialize a tree of objects, but 1 of them contains as data member a native C float array with 1,000,000 entries, so in order to serialize it using encodeFloat:forKey: for each array entry, I need to apply 1,000,000 useless keys , that might be very slow. what the prefered way to handle this?
for each array entry, I need to apply 1,000,000 useless keys
No, you definitely do not need separate keys for each element. A C array is a contiguous block of memory, so you can simply create a NSData object from that block and store that as Hot Licks suggested. Or, since a million floats will require a fair bit of storage, you might compress the data before storing it. And in fact, you don't really even need NSData -- you can encode a range of bytes directly with -encodeBytes:length:forKey:.

iOS: Read in XLS

I'm trying to figure out how to read in the contents of an XLS document and I'm able to get the bytes just fine, but I don't have any clue where to go from here. Trying [[NSString alloc] initWithBytes:data.bytes length:data.length encoding:NSUTF8StringEncoding] and [NSString stringWithUTF8String:data.bytes] both don't get me anywhere (null). What are you supposed to do to read in the contents of an XLS file?
Trying to combine two answer.
"There is no innate ability to read Excel data into a Foundation container, like an NSArray or NSDictionary. You could, however, convert the file (with Excel) to a comma-separated-value (CSV) file and then parse each line's cells on the iPhone using the NSString instance method -componentsSeparatedByString:."
"A comma-separated values (CSV) file stores tabular data (numbers and text) in plain-text form. Plain text means that the file is a sequence of characters, with no data that has to be interpreted instead, as binary numbers. A CSV file consists of any number of records, separated by line breaks of some kind; each record consists of fields, separated by some other character or string, most commonly a literal TAB or comma. Usually, all records have an identical sequence of fields"
--
How to read cell data from an Excel document with objective-c
objective-c loading data from excel
Even though saving your Excel file to CSV is the easier answer, sometimes that's not really what you're looking for, so I created QZXLSReader. It's a drag-and-drop solution so it's a lot easier to use. I don't think it's as feature complete, but it worked for me.
It's basically a library that can open XLS files and parse them into Obj-C classes. Once you have the classes, it's very easy to send them to Core Data or a dictionary or what have you.
I hope it helps!

Best practice to store un-mutable data on iOS

I am looking to create a navigation based reference app for the iOS.
I have considered the following ways to store the data:
hard coding
plist file
some kind of comma delimited file
The data structure that I will be using has a bunch of strings, an array, and a reference to a picture.
What do you think the best way to store this data is without getting into CoreData?
Thanks
Also I dont think it would be more than 500 entries.
Well, this is not a "best-practice" problem for any case.
The data structure that I will be using has a bunch of strings, an array, and a reference to a picture.
What do you think the best way to store this data is without getting into CoreData?
For your needs, I suggest you look into NSKeyedArchiver.
NSString, NSArray, and UIImage all know how to encode and decode themselves. Just use an NSKeyedArchiver. Note that the objects in your collections (e.g. NSArray) must adopt #protocol NSCoding.
If you need to open this on a mac, then convert the UIImage to NSData using a proper image file format representation (e.g. PNG or JPEG) because UIImage is not available.
In detail:
hard coding
That could mean a number of things.
plist file
You're working with large non-plist types. That would mean you would need to convert to and from UIImage<->NSData unnecessarily, which would add a lot of overhead -- memory, CPU, and potentially file size. All these types can encode themselves better than (or as good as) a plist representation.
some kind of comma delimited file
Your image will not allow that to happen (reliably).

Resources