iOS FGallery objective c assigning string value dynamically - ios

It is a bit complicated to explain my problem. I am using FGallery library https://github.com/gdavis/FGallery-iPhone and especially its feature to load images from URL addresses. When I hardcode the URL path it works super, but wen I pass a string variable to the class which I have created it doesn't work. I tried to debug it and it seems that everything is ok, there is a string assigned to the variable and everything, but do not show the picture. I am doing this in a loop and using ARC.
-(void) loadSoftia
{
//======================================================================================
//THIS WORKS CORRECTLY!!!
wcSofia = [[NSMutableArray alloc] init];
Webcam *s1 = [[Webcam alloc]init];
s1.description=#"Sofia";
s1.location = #"http://www.ampthillweatherstation.info/currentweather/webcamimage.jpg";
[wcSofia addObject:s1];
//======================================================================================
NSMutableString *urlGetOthersLocations =[NSMutableString stringWithFormat:#"http://%#/WebHandlers/%#", #"192.168.188.204", #"BGCam.ashx"];
ServerResponse *serverResponseOthersLocations = [HelperViewController getJsonDataFromTheServer:urlGetOthersLocations];
if(serverResponseOthersLocations.data!=nil)
{
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:serverResponseOthersLocations.data
options:NSJSONReadingMutableLeaves|NSJSONReadingMutableContainers
error:nil];
[wcSofia removeAllObjects];
Webcam *wc;
int i=0;
for (NSDictionary *locationsDic in dic){
NSString *key;
for ( key in locationsDic) {
NSLog(#"%# = %#", key, [locationsDic objectForKey: key]);
}
NSLog(#"%#", [locationsDic objectForKey:#"URL"]);
NSLog(#"%# = %#", locationsDic, [locationsDic objectForKey: locationsDic]);
NSString *url =[locationsDic objectForKey:#"URL"];
// NSLog(#"%#", url);
NSMutableString* theString = [NSString stringWithFormat:#"%i ",i];
wc = [[Webcam alloc]initWithLocation: [NSString stringWithFormat:#"%#", url] withDescription:#"description"];
wc.location = url;//DOESNT WORK!
wc.description =#"София";// theString;//[NSString stringWithFormat:#"%#", #"aa"]; // #"София";
wc.location = #"http://media.borovets-bg.com/cams/channel?channel=61";//IT WORKS BECAUSE IT IS HARDCODED
if(wcSofia!=nil)
{
[wcSofia addObject:wc];
NSLog(#"%#", wc.location);
}
i++;
}
}
}
I have commented a section of the code which works and which doesn't.
I suppose that you are not going to need the whole program, because it make requests to my local web server to get the URL addresses and descriptions, but trust me this thing works perfect.
Thank you for your help in solving that mystery.
Edit:
Complete source Code: https://dl.dropboxusercontent.com/u/46512232/FGallery.zip

Related

Corruption of NSString or encoding issue in Objective C

Please see code below:
+ (void)splashDataFromJSON:(NSData *)objectNotation error:(NSError **)error
{
NSError *localError = nil;
NSDictionary *parsedObject = [NSJSONSerialization JSONObjectWithData:objectNotation options:0 error:&localError];
if (localError != nil) {
*error = localError;
}
NSMutableArray* btms = [[NSMutableArray alloc] init];
NSMutableDictionary* btmManufacturerResolutionDictionary = [[BTMCache sharedManager] btmManufacturerResolutionDictionary];
NSArray *results = [parsedObject valueForKey:#"results"];
NSLog(#"Count %d", parsedObject.count);
NSString* imageBaseUrl = [[parsedObject valueForKey:#"general"] valueForKey:#"image_base_url"];
imageBaseUrl = [imageBaseUrl stringByAppendingString:#"hdpi/"];
NSString* splashImageName = [[[parsedObject valueForKey:#"general"] valueForKey:#"splash"] valueForKey:#"img"];
NSString* splashAdvertiserURL = [[[[parsedObject valueForKey:#"general"] valueForKey:#"splash"] valueForKey:#"url"] copy];
NSMutableString* appendedString = [[NSMutableString alloc] init];
for(int i =0 ;i<[splashAdvertiserURL length]; i++) {
char character = [splashAdvertiserURL characterAtIndex:i];
printf(&character);
sleep(0.1);
if (character != "!")
{
[appendedString appendFormat:#"%c", character];
}
}
[[SplashData sharedManager] setSplashAdvertiserURL:appendedString];
[[SplashData sharedManager] setSplashImageName:splashImageName];
splashAdvertiserURL = [[SplashData sharedManager] splashAdvertiserURL];
}
The point of interest is in splashAdvertiserURL. When I receive this data and print it out using po, it comes out as "https://radar.com/ref/go/84/". This is fine and what was expected. When I look at the incoming data in JSONLint it looks like this:
"general": {
"image_base_url": "https:\/\/radar.com\/img\/manufacturers\/",
"splash": {
"img": "image1.png",
"url": "https:\/\/radar.com\/ref\/go\/84\/"
}
},
As you can see, further on I put the NSString into a singleton with an NSString property. Nothing abnormal here. I then proceed to retrieve it to see that all is ok. Further to this the program continues. In another class I wish to retrieve this information, and when I try and do that, it throws EXC_BAD_ACCESS. There appears to be garbage in there.
I then put in a loop in the code as you can see to print out the characters one at a time. Very curiously, when I print that out using po I get:
https://
r
a
d
ar.com/ref/go/8 4!/"
Exactly in that format. If I then proceed to hardcode the string https://radar.com/ref/go/84/ - including escape characters and everything, then all works fine. No issues. If I handle a normal string incoming without escape characters it stores fine in the singleton as well, no issue. enter code here
I am pretty stumped here as to what is going on. Can someone assist?
Thank you
For URL you received as string you need to encode before use it to in your app. Have a look at below code:
NSString *sampleUrl = #"https:\/\/radar.com\/ref\/go\/84\/";
NSString *encodedUrl = [sampleUrl stringByAddingPercentEscapesUsingEncoding:
NSUTF8StringEncoding];

How to get Mobile Number from vCard String Objective C

I am working on Action Extension Objective C. I have successfully created Extension for share recent contact in my Extension. In that I am getting v Card String. How can I get Mobile Number from v Card String. Any help would be appreciated.
Using contactsWithData:error: class method of CNContactVCardSerialization, you can retrieve info from a vCard.
It's from Contacts.framework, available since iOS9.
For earlier version, you can use AddressBook.framework. You can read info here.
NSError *errorVCF;
NSArray *allContacts = [CNContactVCardSerialization contactsWithData:[contactStr dataUsingEncoding:NSUTF8StringEncoding] error:&errorVCF];
if (!errorVCF)
{
NSMutableString *results = [[NSMutableString alloc] init];
//NSLog(#"AllContacts: %#", allContacts);
for (CNContact *aContact in allContacts)
{
NSArray *phonesNumbers = [aContact phoneNumbers];
for (CNLabeledValue *aValue in phonesNumbers)
{
CNPhoneNumber *phoneNumber = [aValue value];
[results appendFormat:#"%# %#\n", [aValue label], [phoneNumber stringValue]];
}
}
NSLog(#"Final: %#", results);
}

How to filter search within a set of letters in search bar so that each letter typed will reduce the results in objective -c

i have implemented a search bar that searching trough an array of countries(presented in a picker view), the problem is that the user need to type the full country name that it will find it and i want him to be able to type even one letter and it will show the first country that starts with that letter and if types another than it sorts even further etc etc.
Anyone have any ideas??
for(int x = 0; x < countryTable.count; x++){
NSString *countryName = [[countryTable objectAtIndex:x]objectForKey:#"name"];
if([searchedStr isEqualToString:countryName.lowercaseString]){
[self.picker selectRow:i inComponent:0 animated:YES];
flag.image = [UIImage imageNamed:[[countryTable objectAtIndex:i]objectForKey:#"flag"]];
}
}
There's a method on NSArray called filteredArrayUsingPredicate: and a method on NSString called hasPrefix:. Together they do what you need...
NSString *userInput = //... user input as lowercase string. don't call this countryName, its confusing
NSPredicate *p = [NSPredicate predicateWithBlock:^BOOL(id element, NSDictionary *bind) {
NSString countryName = [[element objectForKey:#"name"] lowercaseString];
return [countryName hasPrefix:userInput];
}];
NSArray *filteredCountries = [countryTable filteredArrayUsingPredicate:p];
If you're on iOS 8 or OS X Yosemite, you can do:
NSString *country = countryName.lowercaseString; //"england"
NSString *needle = #"engl";
if (![country containsString:needle]) {
NSLog(#"Country string does not contain part (or whole) of searched country");
} else {
NSLog(#"Found the country!");
}
Else, if on versions below iOS 8:
NSString *country = countryName.lowercaseString; //"england"
NSString *needle = #"engl";
if ([country rangeOfString:needle].location == NSNotFound) {
NSLog(#"Country string does not contain part (or whole) of searched country");
} else {
NSLog(#"Found the country!");
}
Lastly, just iterate through all possible countries and apply this to them all. There might exist more robust solutions out there (like danh's solution with some smaller modifications), but this is by far the easiest to start with.

Separate two strings from one array element

I was wondering if anyone could lend some assistance. Basically I am calling a web service and then trying to get the large hosted image url. The output from the web service is so:
images = (
{
hostedLargeUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.l.jpg";
hostedSmallUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.s.jpg";
}
);
The main problem is that the two strings are in only one of my array elements when I think they should be in 2. Also I'm not 100% but possibly they may be a dictionary :-S I'm just not sure. My code is as follows:
NSArray *imageArray = [[NSArray alloc]init];
imageArray = [self.detailedSearchYummlyRecipeResults objectForKey:#"images"];
NSLog(#"imageArray: %#", imageArray);
NSLog(#"count imageArray: %lu", (unsigned long)[imageArray count]);
NSString *hostedLargeurlString = [imageArray objectAtIndex:0];
NSLog(#"imageArrayString: %#", hostedLargeurlString);
The output (nslog's) from the above code is:
2013-04-28 18:59:52.265 CustomTableView[2635:11303] imageArray: (
{
hostedLargeUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.l.jpg";
hostedSmallUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.s.jpg";
}
)
2013-04-28 18:59:52.266 CustomTableView[2635:11303] count imageArray: 1
2013-04-28 18:59:52.266 CustomTableView[2635:11303] imageArrayString: {
hostedLargeUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.l.jpg";
hostedSmallUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.s.jpg";
}
Does anyone have any idea how I can seperate the one element into hostedlargeUrl and hostedsmallUrl respectively?
Any help you can provide is greatly appreciated!
Actually the images array contains a dictionary
images = (
{
hostedLargeUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.l.jpg";
hostedSmallUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.s.jpg";
}
);
so :
NSDictionary *d = [self.detailedSearchYummlyRecipeResults objectForKey:#"images"][0];
NSString *largeURL = d[#"hostedLargeUrl"];
NSString *smallURL = d[#"hostedSmallUrl"];
The value of [imageArray objectAtIndex:0] is a NSDictionary. You've incorrectly specified it as a NSString. You need the following:
NSDictionary *hostedLarguerDictionary =
(NSDictionary *) [imageArray objectAtIndex:0];
and then to access the 'large url' use:
hostedLarguerDictionary[#"hostedLargeUrl"]
or, equivalently
[hostedLarguerDictionary objectForKey: #"hostedLargeUrl"];
looks like an array with in an array so
NSArray* links = [self.detailedSearchYummlyRecipeResults objectForKey:#"images"];
NSString* bigLink = [links objectAtIndex:0];
NSString* smallLink = [links objectAtIndex:1];
or it could be a dictionary
NSDictionary* links = [self.detailedSearchYummlyRecipeResults objectForKey:#"images"];
NSString* bigLink = [links objectForKey:#"hostedLargeUrl "];
NSString* smallLink = [links objectForKey:#"hostedSmallUrl "];
you can see the class of the object by printing out the class name
NSLog(#"Class Type: %#", [[self.detailedSearchYummlyRecipeResults objectForKey:#"images"] class]);

JSON Objective-C Parsing Fail

I have written the following code but I keep on getting nil. I have tried many different variations of this but I am failing exceptionally hard.
This is what I am getting from the server.
Two objects.
[{"description":"yolo.","name":"ye","id":1},{"description":"sMITH","name":"John","id":2}]
Any help would be greatly appreciated...... Thanks.
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError];
SBJsonParser *jsonParser = [[SBJsonParser alloc] init];
NSArray *jsonObjects = [jsonParser objectWithData:response];
NSMutableString *yolo = [[NSMutableString alloc] init];
for ( int i = 0; i < [jsonObjects count]; i++ ) {
NSDictionary *jsonDict = [jsonObjects objectAtIndex:i];
NSString *IDID = [jsonDict objectForKey:#"id"];
NSString *name = [jsonDict objectForKey:#"name"];
NSLog(#"ID: %#", IDID); // THIS DISPLAYS
[yolo appendString: IDID]; // THIS seems to be causing the new error...
[yolo appendString:#": "];
[yolo appendString: name];
NSLog(#"%#", yolo); // RETURNS NIL
}
EDIT:
currently my new error is...
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[NSDecimalNumber length]:
unrecognized selector sent to instance 0x81b89f0'
Looks like your [jsonDict objectForKey:#"id"] is an NSNumber(or NSDecimalNumber) and not an NSString. You should change the line NSString *IDID = [jsonDict objectForKey:#"id"]; to,
id myObject = [jsonDict objectForKey:#"id"];
NSString *IDID = nil;
if ([myObject isKindOfClass:[NSNumber class]]) {
IDID = [[jsonDict objectForKey:#"id"] stringValue];
} else {
IDID = [jsonDict objectForKey:#"id"];
}
This error appeared now since earlier you were not initializing NSMutableString *yolo and you were using appendString: on a nil object. Since now it is initialized as NSMutableString *yolo = [[NSMutableString alloc] init]; it is trying to call appendString on NSMutableString object which accepts only NSString type as its inputs where as you are passing an NSNumber in it. length is a method which appendString: internally calls. So you need to change this as well.
You never initialize yolo, so it's just nil the whole time you're calling -appendString: on it. Try this:
NSMutableString *yolo = [NSMutableString string];
Have you tried initializing the NSMutableString?
NSMutableString *yolo = [[NSMutableString alloc] init];
It looks like you are not really checking the type of the data coming to your app via your JSON feed. This might be the case of random crashes when users actually use your app. It might be also a reason for rejection to the App Store, is such crashes happen during your App's review.
You should be checking the type of all objects you receive from JSON, before calling methods on them :)
By implementing best practices you will have a stable and usable app. Build data models to validate your data. You can also you a JSON data model framework like JSONModel: http://www.jsonmodel.com/
It's obvious from your data that "id" is not a string, but a number. Assigning a pointer to an NSString* doesn't magically convert it to an NSString*. And it's obvious from the exception that you got that some object is an NSDecimalNumber when you thought it would be an NSString.
So: IDID is an NSNumber*, and pretending it is an NSString* will lead to crashes.

Resources