This code shows my user's username in a UILabel named caption
caption.text = [NSString stringWithFormat:#"#%#",[data objectForKey:#"username"]];
I want caption to instead show that user's device token instead of their username. This is how the device token has been used successfully in the app so far.
//A different Method that successfully handles the device token
NSMutableDictionary* params =[NSMutableDictionary dictionaryWithObjectsAndKeys:command, #"command", [_dataModel deviceToken], #"token", nil ];
&
//Another different method that successfully handles the device token with a slightly different syntax
NSDictionary *params = #{#"cmd":#"join",
//the red text passes user_id to _datamodels userId method and thusly to api.php's handleJoin function
#"token":[_dataModel deviceToken],
};
Question: how can one write the correct syntax to show the token, as is, for the objectforkey value? This is what I've tried but I get a compiler warning: no visible interface declaration for selector objectForKey. I know this can be done, how?
caption.text = [NSString stringWithFormat:#"#%#",[data objectForKey:#"token":[_dataModel deviceToken]]];
Original j son : data
//Method body
-(id)initWithIndex:(int)i andData:(NSDictionary*)data
{
self = [super init];
if (self !=nil)
{
Try this one:
caption.text = [NSString stringWithFormat:#"%#", data[#"username"][#"token"]];
i think this will solve your problem
caption.text = [NSString stringWithFormat:#"%#",[params valueForKey:#"token"]];
Related
I have the following method which is creating a URL to an image:
-(NSURL*)urlForImageWithId:(NSNumber*)IdPhoto isThumb:(BOOL)isThumb {
NSString* urlString = [NSString stringWithFormat:#"%#/%#upload/%#%#.jpg",
kAPIHost, kAPIPath, IdPhoto, (isThumb)?#"-thumb":#""
];
return [NSURL URLWithString:urlString];
}
I need to update the path to include the IdUser value that is associated with said image. Here is the way that I have attempted this:
-(NSURL*)urlForImageWithId:(NSNumber*)IdPhoto isThumb:(BOOL)isThumb {
NSString* urlString = [NSString stringWithFormat:#"%#/%#upload/%#/%#%#.jpg",
kAPIHost, kAPIPath, IdUser, IdPhoto, (isThumb)?#"-thumb":#""
];
return [NSURL URLWithString:urlString];
}
When I tried to do this, xcode says “Declare IdUser,” so I did. I Added this to the .h
#property (assign, nonatomic) NSNumber* IdUser;
and I added this below implementation:
#synthesize IdUser;
but when I run the program I get a null value for IdUser.
When I log the dictionary like this:
NSLog(#"Result from Stream: %#",json);
I get the following output:
result = (
{
IdPhoto = 5;
IdUser = 7;
title = this is the title;
username = presto;
});
}
as one example. Here you can clearly see that the IdUser value is being passed through the dictionary. My guess is that the IdPhoto from -(NSURL*)urlForImageWithId:(NSNumber*)IdPhoto isThumb:(BOOL)isThumb {
must be defined somewhere else. Any idea on what I should look for to track this down and be able to pull that IdUser value over as well?
Just adding a property does not set the value of that property. Where is self.IdUser being initiated? It sounds like you are confusing a key of a dictionary with a ViewController property.
Try this to see if that is the case (do this after you get that NSArray named json).
NSDictionary *dict = [json objectAtIndex:0];
self.IdUser = [dict objectForKey:#"IdUser"];
NSLog(#"self.IdUser = %#", self.IdUser];
if idUser is an instance variable, you need to write it as _IdUser or self.IdUser.
Also try: [_idUser stringValue] inside the NSString stringWithFormat method to get the correct type as you specified it as a string ("#").
I have an iPad app that links to an SQL database to retrieve information in the following way:
NSString *strGetCodeUrl = [NSString stringWithFormat:#"%#", #"http://website/getdevicecode.php?device=" , deviceName];
NSArray *deviceArray = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:strGetCodeUrl]];
This works when there is a device that matches and it retrieves the required information. However if there is not a match it returns
("")
The array however appears to have one record. Ideally I would like to stop this from happening and for the array to be empty if there is no match. Alternatively (although not very tidy) I could check the length of the entry at index 0 but I am struggling with this method.
NSString *deviceCode = [deviceArray objectAtIndex:0];
if ( [deviceCode length] == 0)
{
device does not exist
}
Any advice gratefully received.
What about this:
NSString *deviceCode = [deviceArray objectAtIndex:0];
if ([deviceCode isEqualToString:#""])
{
device does not exist
}
I don't think you can tell the init method to leave out empty strings...
However, you can do this:
NSString *strGetCodeUrl = [NSString stringWithFormat:#"%#", #"http://website/getdevicecode.php?device=" , deviceName];
NSArray *deviceArray = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:strGetCodeUrl]];
[deviceArray removeObject:#""];
Which also isn't as tidy as perhaps you were hoping for, but it will remove all empty strings. But at least its just 1 line of code as opposed to about 3 for the if
Per the documentation:
Removes all occurrences in the array of a given object.
I have an iOS app that is using RestKit and CoreData. I have run into a road block with making a POST request because the request body is formed from a NSDictionary. The problem I have is the request body needs to have duplicate keys. NSDictionary requires unique keys so I'm not sure how to make this work.
Here is how the server is expecting the request body.
<node>
<personId>2</personId>
<status>2</status>
<title>Dinosaur unearthed somewhere out there. </title>
<point>
<city>Somewhere</city>
<copy><![CDATA[An amazing discovery was unearthed as a local farmer was plowing his field]]></copy>
<state>Outthere</state>
<sequence>1</sequence>
</point>
<point>
<city>Somwhere</city>
<copy><![CDATA[Archeologists from around the world are amazed at the pristine condition of the remains. Also of note is that the farmer was only using a single blade plow on his John Deere tractor when it was unearthed. ]]></copy>
<sequence>2</sequence>
<state>Outthere</state>
</point>
<point>
......
</point>
</node>
This is a simplified version of how I tried to make it work....
params = [[NSMutableDictionary alloc] init];
nodes = [[NSMutableDictionary alloc] init];
nodeParams = [[NSMutableDictionary alloc] init];
NSString *personId = #"2";
NSString *status = #"2";
NSString *title = #"Dinosaur unearthed somewhere out there.";
NSString *city = #"Somewhere";
NSString *state = #"OutThere";
NSString *copyField = #"Testing this out to see if it works";
//Here I set up the point layer of the request body
//In my code this three line section is in a loop. Obviously this does not work because it just overwrites the objectForKey each time through the loop.
[params setObject:copyField forKey:#"copy"];
[params setObject:city forKey:#"city"];
[params setObject:state forKey:#"state"];
//Here I Set up the Node Layer of the request body
[nodeParams setObject:params forKey:#"point"];
[nodeParams setObject:personId forKey:#"personId"];
[nodeParams setObject:status forKey:#"status"];
[nodeParams setObject:title forKey:#"title"];
[nodes setObject:nodeParams forKey:#"node"];
NSLog(#"The Dictionary is %#",nodes);
At runtime the log shows that the body is formatted properly except their is only one point layer and it is populated with the data from the final pass in the loop. Does anyone know of any trickery to get around this?
As a note I believe the postObject method requires the NSDictionary because it passes the dictionary to a JSON Serialization tool. I suspect the serialization tool is expecting a dictionary to be passed in. If someone knows otherwise correct me if I'm wrong.
Okay I finally figured this out. It wasn't until I converted the XML above into JSON that I realized how it could be done. The key is recognizing how an Array and NSDictionary are formatted in the 'NSJSONSerialization' class.
Here is an example of how the server was expecting the JSON.
{ "status":"2",
"title":"test #5",
"personId":"1",
"point":[
{ "copy":"<p class=\"pt\" data-seq=\"1\">This is paragraph #1<\/p>",
"state":"OutThere",
"city":"Somewhere",
"sequence":"1"
},
{ "copy":"<p class=\"pt\" data-seq=\"2\">This is paragraph #2<\/p>",
"state":"OutThere",
"city":"Somewhere",
"sequence":"2"
}
]
}
The critical thing to note here is that the "point" field is and Array of Dictionaries. The [ denotes an array. Once I finally clued in on that I realized that each time through the loop I could reinitialize my dictionary, add the new objects, and then add the current dictionary to the array as you can see below.
while (![theScanner isAtEnd]) {
count = count +1;
//Initialize the dictionary
points = [[NSMutableDictionary alloc] init];
NSString *htmlTag = [NSString stringWithFormat:#"<p class=\"pt\" data-seq=\"%d\">",count];
[theScanner scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet] intoString:&temp];
NSString *preTagText = [htmlTag stringByAppendingString:temp];
NSString *postTagText = [preTagText stringByAppendingString:#"</p>"];
NSString *sequence = [NSString stringWithFormat:#"%d",count];
[points setObject:postTagText forKey:#"copy"];
[points setObject:sequence forKey:#"sequence"];
[points setObject:city forKey:#"city"];
[points setObject:state forKey:#"state"];
[pointArray addObject:points];
points = nil;
}
[params setObject:titleText forKey:#"title"];
[params setObject:personIdNumber forKey:#"personId"];
[params setObject:status forKey:#"status"];
[params setObject:pointArray forKey:#"point"];
After the loop is finished I just add the pointArray to the dictionary as the object with the key point (Thanks Wain). I add the title, status, and personId objects to the same dictionary and use it as the NSDictionary required for the Restkit POST request.
My if statement won't work. active returns 1 but will not work in the IF statement
JSONDecoder *jsonKitDecoder = [JSONDecoder decoder];
NSDictionary *dict = [jsonKitDecoder objectWithData:jsonData];
NSString *userid = [dict valueForKeyPath:#"users.user_id"];
NSString *active = [dict valueForKeyPath:#"users.active"];
NSLog(#"%#",userid); // 2013-06-20 03:03:21.864 test[81783:c07] (74)
NSLog(#"%#",active); // 2013-06-20 03:03:21.864 test[81783:c07] (1)
if ([active isEqualToString:#"1"]){
// Do something
}
I can't seem to get this IF to work. Do I need to change the NSString to a int?
For starters, use a modern style for retrieving values from dictionaries, rather than valueForKeyPath:.
NSDictionary* users = dict[#"users"];
id active = users[#"active"];
Once you're using a modern style, my guess is that the active value is actually an NSNumber representing a boolean value. So your if block would read:
if([active isKindOfClass:NSNumber] && [active boolValue]) {
//active is an NSNumber, and the user is active
}
The syntax of your if statement is just fine. I would try the alternate method for retrieving values from a dictionary as mentioned above.
NSString *active = #"1";
if ([active isEqualToString:#"1"])
{
// Do something
NSLog(#"It works!");
}
More than likely the "users.active" object being returned from that NSDictionary-ized JSON stream is a "BOOL" or a "NSInteger" as the payload of a NSNumber object and it's not a NSString object.
Try using:
NSNumber * activeNumber = [dict valueForKeyPath: #"users.active"];
and see if "if ([activeNumber boolValue] == YES)" works better for you.
When I scan the barcode and I get some value if it is Equal=2 then I need to display with == and if it is Equal=3 then I need to display with = and if the value is 4 then invalid.
But Scanned Barcode are of integer value -- when decode using NSASCII it is displaying only till value 127 after that it is showing invalid results. Eg: if my Barcode value = 9699 the result value=jem then my added result value=jem= actualstring value=%åasc value id only showing 37
Here is my code:
- (void) readerView:(ZBarReaderView *)view didReadSymbols:(ZBarSymbolSet *)syms fromImage:(UIImage *)img
{
// do something useful with results -- cool thing is that you get access to the image too
for (ZBarSymbol *symbol in syms) {
[resultsBox setText:symbol.data];
if ([resultsBox.text length] == 2) {
addedresult.text = [resultsBox.text stringByAppendingString:#"=="];
} else if ([resultsBox.text length] == 3) {
addedresult.text = [resultsBox.text stringByAppendingString:#"="];
} if ([resultsBox.text length] >= 4) {
addedresult.text = #"Invalid";
}
[Base64 initialize];
NSString *myString = [[NSString alloc]initWithString:addedresult.text];
NSData * data = [Base64 decode:myString];
NSString * actualString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(#"%#",actualString);
labeltext.text= actualString;
int asc = [actualString characterAtIndex:0];
label.text = [NSString stringWithFormat:#"%d", asc];
[actualString release];
break;
}
}
Since someone revived this question's comments, i'll revive this entire post.
You shouldn't go through NSData to create an NSString from something you already have, and you're probably losing something along the way. Go directly to NSString using stringWithFormat. Also, ASCII will come back and byte you later, if you have a choice, use UTF8.
NSString *actualStringUTF8 = [NSString stringWithFormat:#"%#",[addedresult.text urlEncodeUsingEncoding:NSUTF8StringEncoding]];
NSString *actualStringASCII = [NSString stringWithFormat:#"%#",[addedresult.text urlEncodeUsingEncoding:NSUTF8StringEncoding]];
NSLog(#"%#",actualStringUTF8);
NSLog(#"%c",[actualStringUTF8 UTF8String]); //This is a const char*
Secondly, I looked into the SDK and it says symbol.data is already an NSString*. Depending on what you want, you may not need to do anything. If you do end up needing to change encoding, make sure you understand why you need to (one good reason is "the rest of the application uses NS****StringEncoding").
Also make sure you compare strings the correct "Objective-C" way:
[actualString isEqualToString: testString];
NOT actualString == testString;