Inputing a JSON file into Core Data using the following code I found on cimgf.com:
NSString *filePathGPS = [[NSBundle mainBundle] pathForResource:#"gps_6kb" ofType:#"json"];
if (filePathGPS) {
NSString *contentOfFile = [NSString stringWithContentsOfFile:filePathGPS encoding:NSUTF8StringEncoding error:nil];
NSDictionary *jsonDict = [contentOfFile objectFromJSONString];
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *areaName = [NSEntityDescription
insertNewObjectForEntityForName:#"Area"
inManagedObjectContext:context];
NSDictionary *attributes = [[areaName entity] attributesByName];
for (NSString *attribute in attributes) {
for (NSDictionary * tempDict in jsonDict) {
NSLog(#"Attribute = %#", attribute);
id value = [tempDict objectForKey:attribute];
NSLog(#"Value = %#", value);
if (value == nil) {
continue;
}
[areaName setValue:value forKey:attribute];
}
}
NSError *error = nil;
if (![context save:&error]) {
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
}
}
I get the following error:
2013-01-12 12:11:09.548 SuperGatherData[1194:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unacceptable type of value for attribute: property = "area2"; desired type = NSString; given type = NSNull; value = <null>.'
I get why the error is occurring, because some of the values in the file are null and not strings. Here's a sample of the JSON data:
{
"area1": "International",
"area2": null,
"area3": null,
"area4": null,
"area5": null,
"latitude": "-25.2447",
"longtitude": "133.9453",
},
{
"area1": "Alaska",
"area2": "Anchorage & South Central Alaska ",
"area3": null,
"area4": null,
"area5": null,
"latitude": "61.2134",
"longtitude": "-149.8672",
},
{
"area1": "Alabama",
"area2": null,
"area3": null,
"area4": null,
"area5": null,
"latitude": "34.4112",
"longtitude": "-85.5737",
},
and realize I need to do something with the typecasting of attribute in the following line:
for (NSString *attribute in attributes) {
I just have no idea what that fix is. I'm new to Objective-C and haven't dealt with strongly typed languages before.
if (value == nil) should be if ([value isEqual:[NSNull null]]) instead - most JSON parsers represent an explicit null value by NSNull, since one can't store nil in an NSDictionary nor in an NSArray.
Related
I am designing a phonegap ios app, where captured image from camera are saved in device and image name is saved in sqlite DB. The saved images are then showed in application by fetching image's name.
My case is, the image is captured by camera(using cordova plugin), the captured image is saved in device and image name in sqlite db by using custom plugin. After that the image is shown by fetching it from sqlite db using a function in custom plugin.The process of capturing image, saving it to sqlite DB and show it in application, is a sequence process(execute step by step via callbacks). The problem is the native function doesn't return callback(success or error) to js.
I have used the same native function to fetch image in other place, and it is working over there. The function only fails to return callback after capturing image using cordova plugin.
Does cordova camera plugin has such bug?
P.S i am testing in ios 8.1 and my camera plugin is the latest one.
Link for CDVCamera.m
-(void)ActionSelectQuery:(CDVInvokedUrlCommand*)command{
#try{
CDVPluginResult *pluginResult = nil;
NSDictionary *pluginParams = [command.arguments objectAtIndex:0];
NSString *query = [pluginParams objectForKey:#"message"]; //"SELECT * FROM Attachments WHERE FileName NOT like '%Images%' AND Type = 'AttachmentFile' AND Id = 2";
SqliteHelper *sqlitehelper = [[SqliteHelper alloc]init];
NSMutableArray * returnedArray = [sqlitehelper selectQueryRaw:query];
if ([returnedArray count] > 0) {
NSString * jsonValue = #"[";
int count = [returnedArray count];
for (int i = 0; i < count ; i++) {
if (i == (count - 1)) {
jsonValue = [jsonValue stringByAppendingFormat:#"%#]", [returnedArray objectAtIndex:i]];
}else{
jsonValue = [jsonValue stringByAppendingFormat:#"%#,", [returnedArray objectAtIndex:i]];
}
}
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:jsonValue];
}
else{
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:#"[]"]; // error callback
}
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
#catch (NSException *exception) {
NSLog(#"sqlite exception reason:%#",[exception reason]);
}
}
selectQueryRaw function:
-(NSMutableArray *)selectQueryRaw: (NSString*)selectQuery{
NSMutableDictionary *storedValues = [[NSMutableDictionary alloc]init];
NSMutableArray *arrayToReturn = [[NSMutableArray alloc]init];
#try {
dbpath = [dbFullPath UTF8String];
if (sqlite3_open(dbpath, &testDb) == SQLITE_OK) {
sqlite3_stmt *selectStatement;
if(sqlite3_prepare_v2(testDb, [selectQuery UTF8String], -1, &selectStatement, NULL) == SQLITE_OK){
while (sqlite3_step(selectStatement) == SQLITE_ROW) {
NSInteger dataCount = sqlite3_data_count(selectStatement);
for (int i = 0; i < dataCount; i++) {
char *key = "";
char *value = "";
key = (char *)sqlite3_column_name(selectStatement, i);
value = (char *)sqlite3_column_text(selectStatement, i);
NSString *testValue = [NSString stringWithFormat:#"%s", value];
if ([testValue isEqualToString:#"(null)"]) {
testValue=#"";
}
[storedValues setObject:testValue forKey:[NSString stringWithFormat:#"%s", key]];
}
NSData *dataFromDict = [NSJSONSerialization dataWithJSONObject:storedValues
options:0
error:nil];
NSString *eachRowValue = [[NSString alloc]initWithData:dataFromDict encoding:NSUTF8StringEncoding];
[arrayToReturn addObject:eachRowValue];
}
return arrayToReturn;
}
}else{
NSLog(#"error");
return NULL;
}
}
#catch (NSException *exception) {
NSLog(#"%#", [exception reason]);
return NULL;
}
}
js Portion:
obj.executeSelectQuery(query, function (attachmentObj) {
//this plugin call doesn't get any callbacks from native
},function(){
alert("fail");
});
plugin call:
executeSelectQuery: function(query, successCallback, errorCallback){
cordova.exec(
successCallback, // success callback function
errorCallback, // error callback function
'TestClass', // mapped to our native class
'ActionSelectQuery', // with this action name
[{ // and this array of custom arguments to create our entry
"message": query
}]
);
}
I am creating an iOS application that can retrieve informations of certificate(.cer) present in keychain.
Reference links:
Link1, Link2
Below is the code:
const char *certLabelString = "Certificates";
CFStringRef certLabel = CFStringCreateWithCString(
NULL, certLabelString,
kCFStringEncodingUTF8);
const void *keys[] = { kSecClass, kSecAttrLabel, kSecReturnAttributes };
const void *values[] = { kSecClassCertificate, certLabel, kCFBooleanTrue };
CFDictionaryRef dict = CFDictionaryCreate(NULL, keys,
values, 3,
NULL, NULL)
if ((SecItemCopyMatching(dict, &myCertData)) == errSecSuccess){
NSLog(#"Certificate found");
CFDictionaryRef dictCertificateRef = (CFDictionaryRef)myCertData;
NSDictionary *dictCertificate = (__bridge NSDictionary *)dictCertificateRef;
NSLog(#"%#",dictCertificate);
}
Output:
I got the certificates data but I can see serial number or issuer name in encoded form.
Like this:
issr = <310b3009 06035504 06130255 53311330 11060355 040a0c0a 4170706c 6520496e 632e312c 302a0603 55040b0c 23417070 6c652057 6f726c64 77696465 20446576 656c6f70 65722052 656c6174 696f6e73 31443042 06035504 030c3b41 70706c65 20576f72 6c647769 64652044 6576656c 6f706572 2052656c 6174696f 6e732043 65727469 66696361 74696f6e 20417574 686f7269 7479>;
Can some one please tell how to decode this information?
I would also be interested in knowing this. So far, poking around the cert, I did the following:
id data = [keychainDictionary objectForKey:#"issr"];
You can then set a breakpoint at this line, and as you step over it, select the "data" variable in the debug window left panel. Select "watch memory of *data", and you will see a bunch of garbage with real strings from that data. I don't know how to proceed from there.
Complete method that gets all keychain items and loads them in the table view:
-(void)loadDataSource
{
//enumerate all items in keychain http://stackoverflow.com/questions/10966969/enumerate-all-keychain-items-in-my-ios-application
NSMutableDictionary *query = [NSMutableDictionary dictionaryWithObjectsAndKeys:
(__bridge id)kCFBooleanTrue, (__bridge id)kSecReturnAttributes,
(__bridge id)kSecMatchLimitAll, (__bridge id)kSecMatchLimit,
nil];
NSArray *secItemClasses = [NSArray arrayWithObjects:
(__bridge id)kSecClassGenericPassword,
(__bridge id)kSecClassInternetPassword,
(__bridge id)kSecClassCertificate,
(__bridge id)kSecClassKey,
(__bridge id)kSecClassIdentity,
nil];
NSMutableArray* results = [NSMutableArray array];
for(int i = 0; i < (int)secItemClasses.count;i++)
{
[results addObject:[NSMutableArray array]];
}
for (id secItemClass in secItemClasses) {
[query setObject:secItemClass forKey:(__bridge id)kSecClass];
CFTypeRef result = NULL;
SecItemCopyMatching((__bridge CFDictionaryRef)query, &result);
// NSLog(#"%#", (__bridge id)result);
if (result != NULL)
{
NSMutableArray* thisSection = results[[secItemClasses indexOfObject:secItemClass]];
[thisSection addObject:(__bridge id)result];
// [results addObject:(__bridge id)result];
CFRelease(result);
}
for(NSArray* object in results[[secItemClasses indexOfObject:secItemClass]])
{
DLog(#"object is of class: %#",[[object class] description]);
for (NSDictionary* innerObject in object)
{
DLog(#"object is of class: %#",[[innerObject class] description]);
}
}
}
self.datasource = results;
[self.tableView reloadData];
}
//this is the description, you can assign it to a text label in a table view cell
-(NSMutableString*)descriptionForObject:(NSDictionary*)object
{
NSMutableString* string = [[NSMutableString alloc] initWithCapacity:1024];
// https://developer.apple.com/library/mac/documentation/security/Reference/keychainservices/Reference/reference.html
//search for kSecAlias for a list of codes
if(object[#"labl"] != nil)
{
[string appendString:[NSString stringWithFormat:#"Label: %#\n",object[#"labl"]]];
}
[string appendString:[NSString stringWithFormat:#"Created at: %#\n",object[#"cdat"]]];
if(object[#"agrp"] != nil)
{
[string appendString:[NSString stringWithFormat:#"Belongs to application: %#\n",object[#"agrp"]]];
}
for(NSString* key in #[#"issr",#"subj"])
{
id data = [object objectForKey:key];
#try {
if([data isKindOfClass:[NSData class]]==NO)
{
continue;
}
NSString* stringAscii = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSCharacterSet* alphaNumeric = [NSCharacterSet characterSetWithCharactersInString:#"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.#"];
NSCharacterSet *doNotWant = [alphaNumeric invertedSet];
NSString* cleanedUpString = [[stringAscii componentsSeparatedByCharactersInSet: doNotWant] componentsJoinedByString: #" "];
if(cleanedUpString.length>0)
{
DLog(#" %# Cleaned up: %#",key,cleanedUpString);
[string appendString:[NSString stringWithFormat:#" %# Cleaned up: %#",key,cleanedUpString]];
}
}
#catch (NSException *exception) {
}
#finally {
}
}
// [string appendString:[NSString stringWithFormat:#"Complete description:(%#)\n", [object description]]];
return string;
}
I am using following code to fetch the connected WIFI with my ios device.
I want to know what data does SSIDDATA contains and how to read this data.
-(id)fetchSSIDInfo
{
NSArray *ifs = (__bridge NSArray *)(CNCopySupportedInterfaces());
NSLog(#"%s: Supported interfaces: %#", __func__, ifs);
id info = nil;
for (NSString *ifnam in ifs) {
info = (__bridge id)(CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam));
NSLog(#"%s: %# => %#", __func__, ifnam, info);
if (info && [info count]) {
break;
}
}
return info;
}
SSIDDATA is the hex representation of the SSID. Nothing else, as far as i know.
Im having an issue deleting all the rows in a sqlite table I created, I can delete from this table based on a condition, (name, date etc) however when I try to delete all the contents in the table it fails: Here is what I've tried:
-(void) deleteFromDB{
NSLog(#"delete from DB method being called");
NSString * deleteQuery = #"DELETE * FROM CLUB";
[self deleteData:deleteQuery];
}
-(void)deleteData:(NSString *)deleteQuery{
char *error;
NSLog(#"Enter deleteData");
if (sqlite3_exec(clubDB, [deleteQuery UTF8String], NULL, NULL, &error)==SQLITE_OK) {
NSLog(#"CLUB info deleted");
}else{
NSLog(#"Failed");
NSLog(#"Failed with %s", error);
}
}
I get an output of failed.
NSError *error = nil;
if (![context save:&error]) {
NSLog(#"Can't Delete! %# %#", error, [error localizedDescription]);
return;
}
cant delete is never printed
The error message is:
X”¿
*Update**
clubDB is of type sqlite3 (declared in .h as sqlite3*clubDB
error string updated above
**Update2*****
Here is the code for opeing/creating the database:
-(void) createOrOpenDB{
NSArray * path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * docPath = [path objectAtIndex:0];
dbPathString = [docPath stringByAppendingPathComponent:#"club.db"];
NSLog(#"path = %#",dbPathString);
char*error;
NSFileManager*fileManager = [NSFileManager defaultManager];
if(![fileManager fileExistsAtPath:dbPathString]){
const char * dbPath = [dbPathString UTF8String];
//create db here
if (sqlite3_open(dbPath, &clubDB)==SQLITE_OK) {
NSLog(#"success");
const char *sql_stmt = "CREATE TABLE IF NOT EXISTS CLUB (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, SUBJECT TEXT)";
sqlite3_exec(clubDB, sql_stmt, NULL, NULL, &error);
sqlite3_close(clubDB);
}
}
}
Your delete statement isn't valid SQL. To delete everything from CLUB it would be:
delete from CLUB
You don't need the star as it obviously affects the whole record.
I want one application that has sqlite DB.
in my sqlite DB exist 5 records that any record has 2 column. (Name,ID,key)
one of all ID is NULL and I want get this. (ID is INTEGER variable)
this is my code but when run it application is crashed.
do
{
sqlite3 *database2;
if(sqlite3_open([[self dataFilePath] UTF8String], &database2) == SQLITE_OK)
{
NSString *sqlStatement_userInfo2 =[NSString stringWithFormat:#"Select * from table1 where Name = %# and ID = %#",p,p2];
sqlite3_stmt *compiledStatement2;
if(sqlite3_prepare_v2(database2, [sqlStatement_userInfo2 UTF8String], -1, &compiledStatement2, NULL) == SQLITE_OK)
{
// Loop through the results and add them to the feeds array
while(sqlite3_step(compiledStatement2) == SQLITE_ROW)
{
NSMutableDictionary *_dataDictionary=[[NSMutableDictionary alloc] init];
// Init the Data Dictionary
childID = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement2, 1)];
childName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement2, 0)];
b = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement2, 2) ];
p = childID;
p2 = b;
[_dataDictionary setObject:[NSString stringWithFormat:#"%#",childName] forKey:#"Name"];
[array addObject:_dataDictionary];
}
}
else
{
NSLog(#"No Data Found");
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement2);
}
sqlite3_close(database2);
} while (b != NULL);
this code not work and I get this error :
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[NSString stringWithUTF8String:]: NULL cString'
*** First throw call stack:
(0x2092012 0x119fe7e 0x2091deb 0xb97480 0x35b7 0x2e08 0x1c8817 0x1c8882 0x1c8b2a 0x1dfef5 0x1dffdb 0x1e0286 0x1e0381 0x1e0eab 0x1e0fc9 0x1e1055 0x2e63ab 0x13792d 0x11b36b0 0x268efc0 0x268333c 0x268eeaf 0x1d68cd 0x11f1a6 0x11dcbf 0x11dbd9 0x11ce34 0x11cc6e 0x11da29 0x120922 0x1cafec 0x117bc4 0x117dbf 0x117f55 0x120f67 0xe4fcc 0xe5fab 0xf7315 0xf824b 0xe9cf8 0x1feddf9 0x1fedad0 0x2007bf5 0x2007962 0x2038bb6 0x2037f44 0x2037e1b 0xe57da 0xe765c 0x2b6d 0x2a95)
libc++abi.dylib: terminate called throwing an exception
(lldb)
You need to add a check as to whether sqlite3_column_text(compiledStatement2, 1) returns a NULL byte before you try to create the NSString with it.
if ID is integer then use this :
if( [ NSString stringWithFormat:#"%#", sqlite3_column_int(compiledStatement2, 1)]==nil)
{
childID = #"0";
}
else
{
childID = [ NSString stringWithFormat:#"%#", sqlite3_column_int(compiledStatement2, 1)];
}