How to save & retrieve NSdata into sqlite through FMDB - ios

How can I save NSData into sqlite, I am using FMDB wrapper for saving data.
Below is the code which I have tried so far
For saving
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:model.expertArray];;
NSString *query = [NSString stringWithFormat:#"insert into save_article values ('%#','%#','%#','%#','%#','%#')",
model.Id, model.title, model.earliestKnownDate, data, model.excerpt,model.image_url];
For Retriving
while([results next]) {
NSData *data = [results dataForColumn:#"experts"];
NSMutableArray *photoArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
I have tried both datatype blob & text but no luck so far, can anybody guide me how to do it?

Below is the Snippet for all who may face the same issue while inserting NSData to Sqlite using FMDB.
In my Case I wanted to store NSArray in Sqlite So i first convert the NSArray into NSData & then store it in Sqlite.
Converting NSArray into NSData
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:YourNSarray];;
Saving NSData into Sqlite
[database executeQuery:#"insert into save_article values (?,?,?,?,?,?)", model.Id, model.title, model.earliestKnownDate, data, model.excerpt,model.image_url];
Note:- Don't build a query using stringWithFormat[below is the code which you should not use]:. Thanks to #rmaddy & #hotlicks for pointing me to this :)
NSString *query = [NSString stringWithFormat:#"insert into user values ('%#', %d)",
#"brandontreb", 25];
[database executeUpdate:query];
and now the last step i.e retrieving NSData back to NSArray
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:[database dataForColumn:#"yourcololumname"]];
Hope this will help the needy & beginner :)

Don't build a query using stringWithFormat:. This is a bad idea for several reasons.
Use the executeQuery method where you put a ? for each value to be bound to the query.
Something like this:
[database executeQuery:#"insert into save_article values (?,?,?,?,?,?)", model.Id, model.title, model.earliestKnownDate, data, model.excerpt,model.image_url];

Related

got some static data,not much,how should I store them

I got some static data, not too much, maybe 50-60 counts, which is necessary for view's content, so I have to preload them into my app. The data is not plain, not appropriate for property list,and it is too small so I'm not sure if core data is fit. Any suggestion?
I think you can convert them into NSData then save into a file.
For example:
//Write
NSArray * array = #[#"1",#"2",#"3",#"4"];
NSData * data = [NSKeyedArchiver archivedDataWithRootObject:array];
[data writeToFile:yourpath atomically:YES];
//Read
NSData * data = [NSData dataWithContentsOfFile:writeToFile:yourpath];
NSArray * array = [NSKeyedUnarchiver unarchiveObjectWithData:data];

Searching data from txt file in iOS

I have a .txt file in which some data is present, when I stored it in an array I got 50000 words. I want to search the data from text file according to user input and show it on UITableview cell, how is it possible ?
Can any body help me?
Here is my code to read data from .txt file in viewDidLoad:
NSString *filepath = [[NSBundle mainBundle] pathForResource:#"myList" ofType:#"txt"];
NSError *error;
NSString *fileContents = [NSString stringWithContentsOfFile:filepath encoding:NSUTF8StringEncoding error:&error];
if (error)
NSLog(#"Error reading file: %#", error.localizedDescription);
// maybe for debugging...
NSLog(#"contents: %#", fileContents);
NSArray *listArray = [fileContents componentsSeparatedByString:#"\n"];
NSLog(#"items = %d", [listArray count]);
You should use fast enumeration using block. Those are fastest of all for loop iteration. But changing the value in that array at time of enumeration could cause a crash.
Here is a link of how to use block enumeration
Here is a link of how it performance wise.
Hope this helps you!!

How can I read excel file by using objective-c iOS?

I need to pull out the excel file to interface that user can only read the information in file.
what is the solution to implement it?
The most easy way to solve this is first, convert the Excel file to CSV format, which stands for Comma Seperated Value. Meaning it's formatted like: cell 1,cell 2,cell 3. And a new line for each row.
The second is to read the file into a String which can be done in two ways, depending if you have it local or not. Let's say you have it on a server.
NSURL *url = [NSURL urlWithString:#"http://urltoyour.excel/file.csv"];
NSData *data = [NSData dataWithContentOfURL:url];
NSString *string = [NSString stringWithData:data];
Then you can easily convert this to arrays using
NSArray *lines = [string componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
Now you have each excel line in that array. Now for each line you probably want the columns in an array too, you can do that using:
NSMutableArray *finalArray = [NSMutableArray new];
for (NSString *line in lines) {
NSArray *array = [line componentsSeperatedByString:#","];
[finalArray addObject:array];
}
Good luck and let me know if that works out for you!

How to update the existing .plist?

How to update the existing plist with info? I have simple dictionary with strings. Here is my save method:
#define DOCUMENTS [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]
- (IBAction)saveData:(id)sender {
NSMutableDictionary *data = [NSMutableDictionarydictionaryWithObjects:#[self.textFieldOne.text, self.textFieldTwo.text, self.textFieldThree.text] forKeys:#[#"Key1", #"Key2", #"Key3"]];
NSError *error = nil;
NSData *dataToPlist = [NSPropertyListSerialization dataWithPropertyList:data format:NSPropertyListXMLFormat_v1_0 options:0 error:&error];
NSString *path = [DOCUMENTS stringByAppendingPathComponent:#"userData.plist"];
[dataToPlist writeToFile:path atomically:YES];
}
So, it's OK when I call this method from Class 1, but when I want to update this plist with other info from Class 2 – it overwrites old info with new info. What I should do to update the existing plist with new info from other classes?
You need to load the existing plist into an NSDictionary or NSArray (as appropriate), then update the data with the additional data, and finally write out the updated data to the plist file.
Basically the existing one you have to read into dictionary using dictionarywithcontentsfile method and then on the basis of your requirement use setobjecwt method into dictionary and then write to plist. So that old value will be retain there and you can updates new as well.

Can I Archive NSData objects inside another NSData without corrupting data?

I have two NSData objects I want to store within a third NSData object. The idea is I want to make it easy when I later decode the larger object, to get at the two smaller objects independently of one another, without worrying about their relative sizes or datatypes.
It appears the best way to do this is to use NSKeyedArchiver to create a sort of root-level key-value structure within the larger NSData object, in which I can store the two smaller objects within separate keys. That's what I've attempted to do here:
NSData *data1Before = [#"abcdefgh" dataUsingEncoding:NSUTF8StringEncoding];
NSData *data2Before = [#"ijklmnop" dataUsingEncoding:NSUTF8StringEncoding];
NSMutableData *allData = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:allData];
[archiver encodeObject:data1Before forKey:#"key1"];
[archiver encodeObject:data2Before forKey:#"key2"];
[archiver finishEncoding];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:allData];
NSData *data1After = [unarchiver decodeObjectForKey:#"key1"];
NSData *data2After = [unarchiver decodeObjectForKey:#"key2"];
[unarchiver finishDecoding];
NSString *string1After = [NSString stringWithUTF8String:[data1After bytes]];
NSString *string2After = [NSString stringWithUTF8String:[data2After bytes]];
NSLog(#"after1: %#",string1After);
NSLog(#"after2: %#",string2After);
The problem is, when you run this code over and over, you get all sorts of different results coming from the NSLog statements- someetimes special characters get appended to the end of the strings, sometimes they're just NULL.
It appears this corruption has something to do with this "double-encoding" process I'm using. When I modify the code so that the NSKeyedArchiver just calls encodeObject directly on NSStrings, rather than on NSData objects, I can later use decodeObjectForKey and get at those strings without any problems- no corruption at all.
Is there a better way of doing this than using NSKeyedArchiver? Or am I using it incorrectly?
Thanks to rmaddy for his answer above- I just needed to replace this:
[NSString stringWithUTF8String:[data1After bytes]];
with this:
[[NSString alloc] initWithData:data1After encoding: NSUTF8StringEncoding];
and that fixed it.

Resources