Objective-c read image from sqlite - ios

NSData *imageData = UIImageJPEGRepresentation(PhotoImage, 100);
NSString* queryString = ;
[SQLiteAccess insertWithSQL:
[NSString stringWithFormat:#"insert into images (photo) values ('%#')", imageData] // photo - blob column
]; // i use class SQLiteaccess
insert is normally
but when i read image from sqlite
NSArray *photoSelectArray = [SQLiteAccess selectManyRowsWithSQL: [NSString stringWithFormat:#"select photo from places where id=%i", idPlace]];
NSDictionary *imageDataDic = [photoSelectArray objectAtIndex:0];
NSData *dataForCachedImage = [[NSData alloc] initWithData: [imageDataDic objectForKey:#"photo"]];
UIImage *cachedImage = [UIImage imageWithData:dataForCachedImage];
i have an error - SIGABRT (Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString bytes]: unrecognized selector sent to instance 0x1e5c46d0')
p.s. class for easy access to sqlite
- SQLiteAccess.h - http://pastebin.com/BFxFry7T
- SQLiteAccess.m - http://pastebin.com/m67yNVLm

Yeah, I think the problem is here:
[NSString stringWithFormat:#"insert into images (photo) values ('%#')", imageData]]; // i use class SQLiteaccess
When using SQLite directly, you should set the binary data by sqlite3_bind_blob(), but you're actually setting the binary data as string.
So when you get back the data, it's not a binary data, it's a String object, of course, an string object don't response to -[NSData bytes]
Meanwhile I think you should check the field type in your SQLite DB file. Does the photo is actually set to blob.

Related

SIGABRT on cast to UIImage

I'm using FastttCamera as a wrapper to AVFoundation for taking, processing and displaying a picture. Here's my code (a FastttCamera delegate method) in which I cast (FastttCapturedImage *) to (UIImage *):
- (void)cameraController:(FastttCamera *)cameraController didFinishScalingCapturedImage:(FastttCapturedImage *)capturedImage
{
//Use the captured image's data--note that the FastttCapturedImage is cast to a UIImage
NSData *pngData = UIImagePNGRepresentation((UIImage *)capturedImage);
//Save the image, and add the path to this transaction's picPath attribute
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory
int timestamp = [[NSDate date] timeIntervalSince1970];
NSString *timeTag = [NSString stringWithFormat:#"%d",timestamp];
NSString *filePath = [documentsPath stringByAppendingString:timeTag]; //Add the file name
[pngData writeToFile:filePath atomically:YES]; //Write the file
self.thisTransaction.picPath = filePath;
[self.viewFinder setImage:(UIImage *)capturedImage];
}
However, I'm getting a SIGABRT at the line:
NSData *pngData = UIImagePNGRepresentation((UIImage *)capturedImage);
with this console readout:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[FastttCapturedImage CGImage]: unrecognized selector sent to instance 0x17e2a100'
I'm confused by the reference to CGImage. Is it a problem with my typecast? There was no complaint on build. Can someone please set me straight?
Read the docs for FastttCapturedImage. It's not a UIImage so you can't just cast it like that. Use the provided property to get the UIImage.
Change the problematic line to:
NSData *pngData = UIImagePNGRepresentation(capturedImage.fullImage);
You have the same problem later:
[self.viewFinder setImage:capturedImage.fullImage];
BTW - you didn't get a problem while compiling because a cast is a way to tell the compiler "trust me, it's really what I'm telling you it is". The problem here is you were wrong, it's not really what you claimed it was. :)

Break image/jpeg into chunks and bind in nsdictionary for sending JSON in iOS

EDIT: I did not do a very good job of explaining for the server works and my apologies for the same. So here are two things in which the server works ( expects data from clients)
1) Server has a size limitation for receiving image data. It expects images to be broken up in chunks of byte array
2) Server expects to receive these chunks of byte array through JSON.
So I am assuming this translates to the following on the client side
1) I need to break the image in parts
2) Create a Byte array of each part
3) Bind those byte array with JSON and send with server
Once received by the server, those are constructed as an Image by the server.
I am trying to achieve the above mentioned goal by the following approach (I keep the image file in NSData, then I create a Byte Buffer and keep chunks of the image file's NSData in that buffer. Post that I bind this buffer with JSON )
Following is the code for above approach:
-(void)dividepacketId:(int)pktId fileData:(NSData*)dt //dt contain the NSData of image file
{
Byte buffer[20480];
long long dtLength,from=0;
long long len=[dt length];
BOOL b=YES;
while (b)
{
int k=0,indexCont=0;
if(len>20480)
{
dtLength=20480;
}
else
{
dtLength=len;
b=NO;
}
[dt getBytes:buffer range:NSMakeRange(from,dtLength)];
NSData *imageData=nil;
imageData = [NSData dataWithBytes:buffer length:dtLength];
len=len-dtLength;
from=from+dtLength;
NSLog(#"sending buffer=%s legth of buffer=%lli len value=%lli",buffer,dtLength,len); //everything is fine till here
NSMutableDictionary *projectDictionary3 = [NSMutableDictionary dictionaryWithCapacity:1];
[projectDictionary3 setObject:#"2100" forKey:#"Action"];
[projectDictionary3 setObject:[NSString stringWithFormat:#"%i",pktId] forKey:#"PacketId"];
[projectDictionary3 setObject:#"101" forKey:#"FileAction"];
if(imageData!=nil)
[projectDictionary3 setObject: imageData forKey:#"FData"];//data
[projectDictionary3 setObject:[NSString stringWithFormat:#"%i",(int)dtLength] forKey:#"DataLength"];//data
NSError *jsonSerializationError = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:projectDictionary3 options:NSJSONWritingPrettyPrinted error:&jsonSerializationError]; //"here crashed"
if(!jsonSerializationError)
{
NSString *serJSON = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"Serialized JSON: %#", serJSON);
}
else
{
NSLog(#"JSON Encoding Failed: %#", [jsonSerializationError localizedDescription]);
}
code to send over stream
[self sendDataToServer:jsonData];
} //while loop
}
Here is the challenge. If I send simple data (for example a string) through this code, it goes over to server successfully ( through socket). But when I try to break an actual jpeg image into parts and bind it in nsdictionary to make json, it crashes with the following error.
terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (NSConcreteData)'. Any help here would be highly appreciated.
EDIT: As explained by bobnoble, I understand the reason for the exception. In that case however, how do I accomplish sending over data to server
Deleting all but the key portions that need to be changed.
As I stated in the comments the data needs to be in a format JSON handles, raw bytes are not acceptable so one way is to encode the data with Base64. The receiver will also need to decode the Base64 string into data.
while (b) {
//get chunk from and dtLength
NSData *imageData = [dt subdataWithRange:NSMakeRange(from, dtLength)];
NSData *imageBase64Data = [imageData base64EncodedDataWithOptions:0];
NSString *imageBase64String = [[NSString alloc] initWithData:imageBase64Data encoding: NSUTF8StringEncoding];
// update len and from
NSLog(#"sending imageData =%#. dtLength =%i len =%lli", imageBase64String, dtLength, len);
// Create projectDictionary3 and add items
// Added image data)
if(imageData.length) {
[projectDictionary3 setObject: imageBase64String forKey:#"FData"];
}
[projectDictionary3 setObject:#(imageBase64String.length) forKey:#"DataLength"];
// serialize projectDictionary3 into JSON and sent to server];
}
From the NSJSONSerialization class reference:
An object that may be converted to JSON must have the following
properties:
The top level object is an NSArray or NSDictionary.
All objects are instances of NSString, NSNumber, NSArray, NSDictionary, or NSNull.
All dictionary keys are instances of NSString.
Numbers are not NaN or infinity.
The second bullet does not include NSData, and is why the exception is being thrown.
Convert the image data to Base64 encoding, then put it in the dictionary as an NSString. Take a look at the NSData base64EncodedStringWithOptions method.

Using format specifier in for a URL in iOS

I'm having problems with using format specifiers for url's. Using the zBar scanner to scan a php link. I've spent a lot of time researching here on overflow but I cannot find the answer.
This is the code I use in my viewcontroller.m:
NSData *jsonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://mywebsite.co.uk/TM.php?id=%#",self.scannedValue]]];
//NSData *jsonData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Sample" ofType:#"JSON"]];
NSArray *jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves error:Nil];
I'm trying to get the part after id to take in any integer number like 200,201,202,203,...
For some strange reason it only works when I type the number in itself as id=201 or id=202.
when I use NSLog for NSLog(#"%#",scannedValue) it shows the following:
2014-02-26 21:45:27.185 MeCombine[2412:60b] http://mywebsite.co.uk/TM.php?id=201
2014-02-26 21:45:27.277 MeCombine[2412:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'data parameter is nil'
Can anyone tell me why this happens please?
A few notes:
scannedValue = sym.data;
is string, sum is ZBarSymbol class object
In the ZBarSymbol class
#property (readonly, nonatomic) NSString *data;
is the starting value.
When a value is successfully scanned it will return a NSString *data in the delegate method.
I can only provide a guess, since I don't see all of your code, but here's what I think goes on:
Your http link is malformed (http:: instead of http:). The jsonData object will be nil if it can't load the URL for whatever reason.
You don't do any null checking, and this nil object is sent to whatever method processes your json data, which throws a NSInvalidArgumentException if the data object is nil.
NSData's +dataWithContentsOfURL: does not tolerate nil URL, which in this case happens because of the incorrect URL format, notice you have two : in the URL after http. The correct URL would be.
http://mywebsite.co.uk/TM.php?id=%#
The modern and potentially more foolproof way of building URLs would be to use NSURLComponents (iOS 7 and OS X 10.9)
NSURLComponents *comps = [NSURLComponents componentsWithString:#"http://www.mywebsite.co.uk"];
comps.query = [NSString stringWithFormat:#"id=%#", self.scannedValue];
comps.path = #"/TM.php";
NSURL *URL = comps.URL;
The main benefit would be the ability to isolate the base URL into a constant string and then alter the query/path from elsewhere, both making things a bit more modular and easier to maintain than a hardcoded value in code.

NSLog string is fine but string into UITextView causes exception [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
So I have a view controller and in the viewdidload method it's supposed to load some content from a webpage (just a proof of concept, it'll be cached eventually). It gets the content using the tfhipple library and puts the contents into an array, it logs the data to the console and then I want it to apply the contents to a UITextView. However when the view controller is called it gets so far as to log the text to the console but on the line where it sets it as the contents of the UITextView it causes an exception.
NSData *dataURL;
NSString *url = #"http://www.testwebsite.com/testpage.html";
dataURL = [NSData dataWithContentsOfURL: [NSURL URLWithString: url]];
NSString *serverOutput = [[NSString alloc] initWithData:dataURL encoding: NSASCIIStringEncoding];
TFHpple * doc = [[TFHpple alloc] initWithHTMLData:dataURL];
NSArray *elements = [doc searchWithXPathQuery:#"//div[contains(#id,'main-section')]//text()"];
NSString * aboutcontents = [elements objectAtIndex:2];
NSLog(#"test: %#", aboutcontents);
self.aboutbox.text = aboutcontents;
The exception it causes is as follows, along with the console output before hand:
2013-06-24 09:37:51.433 AppName[24765:c07] test: {
nodeContent = "Test Content";
nodeName = text;
raw = "Test Content";
}
2013-06-24 09:37:51.434 AppName[24765:c07] -[TFHppleElement length]: unrecognized selector sent to instance 0x8043be0
2013-06-24 09:37:51.434 AppName[24765:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[TFHppleElement length]: unrecognized selector sent to instance 0x8043be0'
*** First throw call stack:
(0x25d012 0x16ebe7e 0x2e84bd 0x24cbbc 0x24c94e 0x76b4fb 0x3347 0x7111c7 0x711232 0x7328c9 0x732704 0x730bda 0x730a5c 0x732647 0x16ff705 0x6332c0 0x633258 0x855ff4 0x16ff705 0x6332c0 0x633258 0x6f4021 0x6f457f 0x6f4056 0x859af9 0x16ff705 0x6332c0 0x633258 0x6f4021 0x6f457f 0x6f36e8 0x662cef 0x662f02 0x640d4a 0x632698 0x22b2df9 0x22b2ad0 0x1d2bf5 0x1d2962 0x203bb6 0x202f44 0x202e1b 0x22b17e3 0x22b1668 0x62fffc 0x2fdd 0x21a5)
libc++abi.dylib: terminate called throwing an exception
(lldb)
I'm a little bit stuck as to why it does this. If I manually set the string aboutcontents to something then it changes the contents of the UITextView without issue.
Any help is as always appreciated.
Try this:
TFHppleElement * aboutcontents = [elements objectAtIndex:2];
NSLog(#"test: %#", [aboutcontents text]);
self.aboutbox.text = [aboutcontents text];
Here is the documentation part taken from hpple:
TFHppleElement * element = [elements objectAtIndex:0];
[e text]; // The text inside the HTML element (the content of the first text node)
[e tagName]; // "a"
[e attributes]; // NSDictionary of href, class, id, etc.
[e objectForKey:#"href"]; // Easy access to single attribute
[e firstChildWithTagName:#"b"]; // The first "b" child node
Try to get attributes for example and see what it returns to you.
you getting resutt for NSString * aboutcontents = [elements objectAtIndex:2]; is a dictionary,convert dictionary into string like this
NSString * aboutcontents=[NSString stringWithFormat:#"%#",[elements objectAtIndex:2]];
Try this.
NSDictionary * aboutcontents = [elements objectAtIndex:2];
NSLog(#"test: %#", aboutcontents);
self.aboutbox.text = [aboutcontents objectForKey:#"nodeContent"];
I don't understand the context but I saw { } in the Log and I guess only dictionaries get printed that way.

How to Retrive and Store NSArray from sqlite DB in iOS

I have an array itemQtyArray which i am storing in SQLITE table As:
NSData *toData = [NSKeyedArchiver archivedDataWithRootObject:self.itemQtyArray];
NSString *insertSQL = [NSString stringWithFormat: #"INSERT INTO ORDERTABLE(ITEMDESC,ITEMQTY)VALUES( \"%#\",\"%#\");",dataString2,toData];
and then i am retrieving as :
const void *itemQty = sqlite3_column_text(statement, 2);
NSInteger qtyBytes = sqlite3_column_bytes(statement, 2);
NSData *data2 = [NSData dataWithBytes:itemQty length:qtyBytes];
NSArray *myArrayFromDB = [[NSArray alloc]init];
myArrayFromDB = [NSKeyedUnarchiver unarchiveObjectWithData:data2];
[self.itemQtyArray addObjectsFromArray:myArrayFromDB];
BUt i am getting Exception at line
myArrayFromDB = [NSKeyedUnarchiver unarchiveObjectWithData:data2];
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
'-[__NSCFData objectForKey:]: unrecognized selector sent to instance
Please tell what is wrong
NSData *toData = [NSKeyedArchiver archivedDataWithRootObject:array];
instead of this you should pass NSDictionary
NSData *toData = [NSKeyedArchiver archivedDataWithRootObject:dictionary];
or
o convert a generic array to an NSData, you need an archiver! If you know how to feed the NSData, you know how to use NSKeyedArchiver. So:
NSArray* array= ... ;
NSData* data=[NSKeyedArchiver archivedDataWithRootObject:array];
Of course all elements in your array needs to implement NSCoding protocol

Resources