When I receive XMPP Presence in the app , I am adding its contents to a NSMutableDictionary to send it across another ViewController.If I use NSLog to see the contents of this dictionary , I can see everything fine.But when I access this NSMutableDictionary from another ViewController I can't find the JID.Rest of the things are stored fine.
This is what I am doing while storing the XMPP Presence contents i e JID and Name.
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence
{
NSString *fromUser = [[presence from]user]; //name of user
NSString *fromUserJID = [NSString stringWithFormat:#"%#",[presence from]] ;
NSLog(#"presence from user JID :- %#", fromUserJID); // This shows the JID.
[_locationDictionary setObject:fromUser forKey:#"fromUser"];
[_locationDictionary setObject:fromUserJID forKey:#"fromJID"];
NSLog(#"locationary dictionary :- %#",_locationDictionary ); // This shows name as well as JID.
// add to array
[_presenceArray addObject:_locationDictionary];
Now when I am trying to access this in another ViewController I do this:-
NSString *str=view.annotation.title; //This has the name of the user.
NSLog(#"annotation title :- %#", str);
for (NSDictionary *obj in appDelegate.presenceArray)
{
NSString *titleString = [obj objectForKey:#"fromUser"];
if ([str isEqualToString:titleString]) //for the same username I need the JID
{
NSString *jidString = [obj objectForKey:#"fromJID"];
[ dict setObject:jidString forKey:#"jid"]; //dict is NSMutableDictionary
NSLog(#"retrieved jid is :- %#", dict); // THIS IS NULL
[presence from] will give XMPPJid which is NSObject type.
XMPPJID *jid = [presence from];
Try to get Jid string this way
NSString *fromUserJID = [[presence from] full];//Will give Jid have user, resource, domain
//OR
NSString *fromUserJID = [presence fromStr]; //Only give Jid of user.
Related
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);
}
I am parsing a JSON in my code. But I am getting some unexpected issues while retrieving data of parsed JSON. So let me explain my problem.
I have to parse following JSON data using xcode. This is what data to be parsed looks like while I hit same URL in browser:
{
"RESPONSE":[
{"id":"20",
"username":"john",
"email":"abc#gmail.com",
"phone":"1234567890",
"location":"31.000,71.000"}],
"STATUS":"OK",
"MESSAGE":"Here will be message"
}
My code to reach up to this JSON data is as follow:
NSData *data = [NSData dataWithContentsOfURL:finalurl];
NSError *error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
If I print object json using NSLog, i.e. NSLog(#"json: %#", [json description]); it looks like:
json: {
MESSAGE = "Here will be message";
RESPONSE =(
{
email = "abc#gmail.com";
id = 20;
location = "31.000,71.000";
phone = 1234567890;
username = john;
}
);
STATUS = OK;
}
So, here I observed two things:
Sequence of keys (or nodes) (MESSAGE, RESPONSE and STATUS) is changed as compared to web response above.
The RESPONSE is get enclosed in '(' & ')' braces.
Now if I separate out values for keys MESSAGE & STATUS and NsLog them, then they get printed as proper string.
Like msgStr:Here will be message & Status:OK
But if I separate out value for RESPONSE as a dictionary and again separating sub values of that dictionary like email and username, then I can't getting those as string.
Here is the code so far I wrote:
NSMutableDictionary *response = [json valueForKey:#"RESPONSE"];
NSString *username = [response valueForKey:#"username"];
NSString *emailId = [response valueForKey:#"email"];
If I print username and emailId, then they are not getting printed as normal string, instead it outputs as:
username:(
john
)
email:(
abc#gmail.com
)
So my question is why it's not getting as a normal string? If I tried to use this variables further then they show value enclosed within '(' & ')' braces. Is this happening because of NSJSONSerialization?
First of all in your JSON response dictionary, under the key 'RESPONSE' you have a array not a dictionary and that array contains dictionary object.
So to extract username and email ID so as below
NSMutableDictionary *response = [[[json valueForKey:#"RESPONSE"] objectAtIndex:0]mutableCopy];
NSString *username = [response valueForKey:#"username"];
NSString *emailId = [response valueForKey:#"email"];
When you see braces like that, it represents an array, not a dictionary. Your JSON also shows that by enclosing the data in brackets ('[' and ']'). So:
RESPONSE =(
{
email = "abc#gmail.com";
id = 20;
location = "31.000,71.000";
phone = 1234567890;
username = john;
}
);
RESPONSE is an Array of Dictionaries. To access the data, iterate through the array:
for (NSDictionary *responseDictionary in [JSONDictionary objectForKey:#"RESPONSE"]) {
NSString *name = [responseDictionary objectForKey:#"username"];
.....
}
or grab a dictionary at an index:
NSDictionary *responseDictionary = [[JSONDictionary objectForKey:#"RESPONSE"] objectAtIndex:0];
NSString *name = [responseDictionary objectForKey:#"username"];
Whenever in doubt, log the the class:
NSLog(#"%#", [[dictionary objectForKey:#"key"] class]);
to see what is being returned from the dictionary.
1)Sequence of keys (or nodes) (MESSAGE, RESPONSE and STATUS) is
changed as compared to web response above.
The NSLog of NSDictionary is based on the sorted keys.
2)The RESPONSE is get enclosed in '(' & ')' braces.
RESPONSE =(
{
email = "abc#gmail.com";
id = 20;
location = "31.000,71.000";
phone = 1234567890;
username = john;
}
);
The RESPONSE is a key and the value is an NSArray. The array contains one NSDictionary object with keys as email, id, location, phone and username.
NOTE: () says array. {} says dictionary.
RESPONSE contains an array not an object.
So try like this:
NSMutableArray *response = [json valueForKey:#"RESPONSE"];
NSString *username = [[response objectAtIndex:0] valueForKey:#"username"];
NSString *emailId = [[response objectAtIndex:0] valueForKey:#"email"];
NSLog(#"User=>[%#] Pwd=>[%#]",username ,emailId );
pragma mark - Checking Reachability and Parsing Datas
NSString *urlString = [NSString stringWithFormat: #"https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=11.021459,76.916332&radius=2000&types=atm&sensor=false&key=AIzaSyD7c1IID7zDCdcfpC69fC7CUqLjz50mcls"];
NSURL *url = [NSURL URLWithString: urlString];
NSData *data = [NSData dataWithContentsOfURL:url];
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData: data options: 0 error: nil];
array = [[NSMutableArray alloc]init];
array = [[jsonData objectForKey:#"results"] mutableCopy];
[jsonTableview reloadData];}
pragma mark- UITableView Delegate
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return array.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellid = #"cell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:cellid];
cell = [[UITableViewCell
alloc]initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:cellid];
cell.textLabel.text = [[array
valueForKeyPath:#"name"]objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [[array
valueForKeyPath:#"vicinity"]objectAtIndex:indexPath.row];
NSURL *imgUrl = [NSURL URLWithString:[[array
valueForKey:#"icon"]objectAtIndex:indexPath.row]];
NSData *imgData = [NSData dataWithContentsOfURL:imgUrl];
cell.imageView.layer.cornerRadius =
cell.imageView.frame.size.width/2;
cell.imageView.layer.masksToBounds = YES;
cell.imageView.image = [UIImage imageWithData:imgData];
return cell;
}
#import.h
#interface JsonViewController :
UIViewController<UITableViewDelegate,UITableViewDataSource>
#property (weak, nonatomic) IBOutlet UITableView *jsonTableview;
#property (weak, nonatomic) IBOutlet UIBarButtonItem *barButton;
#property (strong,nonatomic)NSArray *array;
#property NSInteger select;
By serializing the data, u get a json object. Json object and dictionary are different a bit.
Instead of using:
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
use:
NSDictionary *json = (NSDictionary*) data;
m using facebook graph apis in my app.
i want to fetch my fb friends email ids
in a tableview in my app
fb graph user doesn't provides any property for emails.
how can i achive this
help me
- (void)loginViewShowingLoggedInUser:(FBLoginView *)loginView {
self.userInfoTextView.hidden = NO;
// Fetch user data
[FBRequestConnection
startForMeWithCompletionHandler:^(FBRequestConnection *connection,
id<FBGraphUser> user,
NSError *error) {
if (!error) {
NSString *userInfo = #"";
// Example: typed access (name)
// - no special permissions required
userInfo = [userInfo
stringByAppendingString:
[NSString stringWithFormat:#"Name: %#\n\n",
user.name]];
// Example: typed access, (birthday)
// - requires user_birthday permission
userInfo = [userInfo
stringByAppendingString:
[NSString stringWithFormat:#"Birthday: %#\n\n",
user.birthday]];
// Example: partially typed access, to location field,
// name key (location)
// - requires user_location permission
userInfo = [userInfo
stringByAppendingString:
[NSString stringWithFormat:#"Location: %#\n\n",
user.location[#"name"]]];
// Example: access via key (locale)
// - no special permissions required
userInfo = [userInfo
stringByAppendingString:
[NSString stringWithFormat:#"Locale: %#\n\n",
user[#"locale"]]];
// Example: access via key for array (languages)
// - requires user_likes permission
if (user[#"languages"]) {
NSArray *languages = user[#"languages"];
NSMutableArray *languageNames = [[NSMutableArray alloc] init];
for (int i = 0; i < [languages count]; i++) {
languageNames[i] = languages[i][#"name"];
}
userInfo = [userInfo
stringByAppendingString:
[NSString stringWithFormat:#"Languages: %#\n\n",
languageNames]];
}
// Display the user info
self.userInfoTextView.text = userInfo;
}
}];
}
Add this line to your code. Hope it will be helpful to you.
NSLog(#"%#",[user objectForKey:#"email"]);
You cannot obtain e-mail addresses for friends through the Facebook API (with good reason - to prevent spam). You can obtain the current user's e-mail address, but only with an extended permission (more about that here).
My company has an iOS app that interfaces directly with Salesforce, with one major drawback. When a user attempts to upload an illegal character, the app hangs, returns bad values, or results in some other erratic behavior.
I found a really handy piece of code out in the mystical interwebs (thanks, MailDrop), that filters a string and escapes those illegal characters with a forward slash. It then returns the value in a string, ready for upserting/querying.
One thing I'm really having trouble with is getting this to work with our application, though. Our data is stored in a dictionary and is written to in a variety of ways (querying the server, or manual input), and at various times in the application's life cycle. I'm not quite sure how to invoke this nifty 'escapeSosl' in the most efficient method. Is there a way that I can escape these characters every time I write to Core Data? What I'm most afraid of is going through the app and calling this hundreds of times.
Here is the escaping method:
- (NSString *)escapeSosl:(NSString *)src {
// from docs, these are all reserved
NSArray *reserved = [NSArray arrayWithObjects:#"\\", #"&", #"|", #"!", #"{", #"}", #"[", #"]", #"^", #"~", #"*:", #":", #"'" ,#"\"", #"+", #"-", nil];
NSMutableString *s = [NSMutableString stringWithString:src];
NSString *r;
NSEnumerator *e = [reserved objectEnumerator];
while (r = [e nextObject])
[s replaceOccurrencesOfString:r withString:[NSString stringWithFormat:#"\\%#", r] options:NSLiteralSearch range:NSMakeRange(0, [s length])];
return s;
}
What I find complicated is the timing of these escapings, and how to apply that to each situation. For instance, the app queries Salesforce for an Account using a location that was either manually entered or found via reverse geocoding. Here is an example of the app requesting data from the Salesforce Server:
-(void)checkServerForLeadMatchingAddressOnAccount:(SFAccount *)account {
currentAccount = account;
//Parse the account location data, removing the last word in the `street` object
NSString *street = account.shippingStreetAddress;
NSMutableArray *streetArray = [[street componentsSeparatedByString:#" "] mutableCopy];
[streetArray removeLastObject];
street = [streetArray componentsJoinedByString:#" "];
street = [street stringByAppendingString:#"_%"];
NSString *city = account.shippingCity;
NSString *state = account.shippingState;
NSString *zip = account.shippingZIP;
//Check for a matching lead on the server. User the callback methods to proceed (either create new data on the server or download to the device
NSLog(#"is connected: %i", self.isConnectedToServer);
if (self.isConnectedToServer){
requestCheckForLead = [[SFRestAPI sharedInstance] requestForQuery:[NSString stringWithFormat:#"SELECT ID, Company, Name, Street, City, State, PostalCode, Phone FROM Lead WHERE PostalCode = '%#' AND Street LIKE '%#' AND City = '%#' AND State = '%#'", zip, street, city, state]];
[[SFRestAPI sharedInstance] send:requestCheckForLead delegate:self];
openTasks++;
} else {
NSLog(#"I can't connect");
[self.serverDelegate serverObjectManager:self communicationSuccessful:NO withResponse:#"Could not connect to the server."];
}
Another area where I might escape characters is right before initiating an upload to the server. There are a couple things that get uploaded, including an Account, the Account's Contact (1:1 rel.), the Account's Opportunity (1:1 rel.), and an Opportunity's Current Service Levels (1:many rel).
Here is an example of the Contact associated with an Account - it uses both Strings and dictionary references, but has some additional logic for parsing firstName from lastName. I'd like to escape the data in a way that I do not need to worry about the timing of these manipulations.
NSMutableDictionary *contactDict = [NSMutableDictionary new];
if (myAccount.contact.email) {
[contactDict setObject:myAccount.contact.email forKey:#"Email"];
} else {
[contactDict setObject:#"" forKey:#"Email"];
}
if (myAccount.contact.name) {
//Split name in two
NSArray *nameArray = [myAccount.contact.name componentsSeparatedByString:#" "];
NSString *firstName = [nameArray objectAtIndex:0];
NSString *lastName = [nameArray lastObject];
[contactDict setObject:firstName forKey:#"firstName"];
[contactDict setObject:lastName forKey:#"lastName"];
} else {
[contactDict setObject:#"" forKey:#"firstName"];
[contactDict setObject:#"" forKey:#"lastName"];
}
if (myAccount.contact.phone){
[contactDict setObject:myAccount.contact.phone forKey:#"Phone"];
} else {
[contactDict setObject:#"" forKey:#"Phone"];
}
updateContactRequest = [[SFRestAPI sharedInstance] requestForUpdateWithObjectType:#"Contact" objectId:myAccount.createdContactID fields:contactDict];
[[SFRestAPI sharedInstance] send:updateContactRequest delegate:self];
So this may seem like a bit of a large question, but does anyone have some pointers as to how I could escape characters in these various dictionaries, using something similar to the 'escapeSosl' code I included above, whenever things are written to core data?
In this line you build your query
requestCheckForLead = [[SFRestAPI sharedInstance] requestForQuery:[NSString stringWithFormat:#"SELECT ID, Company, Name, Street, City, State, PostalCode, Phone FROM Lead WHERE PostalCode = '%#' AND Street LIKE '%#' AND City = '%#' AND State = '%#'", zip, street, city, state]];
instead of passing street as the parameter pass [self escapeSosl:street] and so on for the other params.
Could you help me to parse response correctly:
Parser in - (void)request:(FBRequest *) request didLoad:(id)result:
case education:{
NSArray *arrayRsult = [[result objectForKey:#"education"] objectForKey:#"school"];
for (NSDictionary *placeForResults in arrayRsult){
NSString *output = [placeForResults objectForKey:#"name"];
NSLog(#"%#", output);
}
}
break;
My request:
- (IBAction)eduacation:(id)sender {
currentApiCall = education;
FacebookInfoGetterAppDelegate *delegate = (FacebookInfoGetterAppDelegate *) [[UIApplication sharedApplication] delegate];
[[delegate facebook] requestWithGraphPath:#"me?fields=education" andDelegate:self];
}
But it returns array with nulls. Whats wrong?
first of all you need to set up rights for this - "user_education_history"
I corrected code for your parsing part because your receive dictionary with key education that consists array of your schools.
NSArray *arrayRsult = [result objectForKey:#"education"];
for (NSDictionary *placeForResults in arrayRsult){
NSString *output = [[placeForResults objectForKey:#"school"] objectForKey:#"name"];
NSLog(#"%#", output);
}
it works for me.