I get four parameters from a web service (web service 2 in my flow) - slno, order, flag, name. I don't know how many times these parameters are going to be received. Out of these four paramters, I send 'name' to a label as it contains questions to be asked.
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"some url"]];
NSLog(#"Web service 2 url is = %#", url);
NSString *json = [NSString stringWithContentsOfURL:url encoding:NSASCIIStringEncoding error:&error];
NSLog(#"Json data = %# \n error = %#", json, error);
if(!error)
{
NSData *jsonData = [json dataUsingEncoding:NSASCIIStringEncoding];
NSArray *myJsonArray = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:Nil];
//NSArray *arrayLabel = [[NSArray alloc] initWithObjects:label1, label2, label3, label4, label5, label6, nil];
//NSMutableArray *tempArray = [NSMutableArray arrayWithCapacity:myJsonArray.count];
i = 0;
for(NSDictionary *myJsonDictionary in myJsonArray)
{
//UILabel *label = (UILabel *)[arrayLabel objectAtIndex:i++];
//[label setText:myJsonDictionary[#"Name"]];
NSString *name = myJsonDictionary[#"Name"];
NSLog(#"Question from ws2 is %#", name);
projectIdGobal = myJsonDictionary[#"ProjectID"];
NSLog(#"Project id from ws2 is %#", projectIdGobal);
slno = myJsonDictionary[#"SLNO"];
NSLog(#"slno from ws2 is %#", slno);
NSString *idWS2 = myJsonDictionary[#"ID"];
NSLog(#"id from ws2 is %#", idWS2);
order = myJsonDictionary[#"Order"];
NSLog(#"order from ws2 is %#", order);
flag = myJsonDictionary[#"Flag"];
NSLog(#"flag from ws2 is %#", flag);
[self putLabelsInScrollView:name];
i++;
}
NSLog(#"Number of cycles in for-each = %d", i);
[activity stopAnimating];
}
- (void) putLabelsInScrollView:(NSString *)labelText
{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, yPosition_label, 261, 30)];
[label setFont:[UIFont fontWithName:#"Helvetica Neue" size:12.0f]];
label.numberOfLines = 2;
[label setText:labelText];
[self.scroll addSubview:label];
yPosition_label += 90;
UITextField *text = [[UITextField alloc] initWithFrame:CGRectMake(10, yPosition_text, 261, 30)];
text.borderStyle = UITextBorderStyleRoundedRect;
text.textColor = [UIColor blackColor];
text.font = [UIFont systemFontOfSize:12.0];
text.backgroundColor = [UIColor clearColor];
text.keyboardType = UIKeyboardTypeDefault;
text.delegate = self;
[self.scroll addSubview:text];
yPosition_text += 90;
yPosition_result = yPosition_label + yPosition_text;
[self.scroll setContentSize:CGSizeMake(self.scroll.frame.size.width, yPosition_result)];
[self.view addSubview:self.scroll];
}
Now I created a dynamically created text fields and stored the answers entered by the user in the array as follows.
- (IBAction)save:(id)sender {
NSMutableArray *mutableTextArray = [[NSMutableArray alloc] init];
for(UITextField *field in self.scroll.subviews)
{
if([field isKindOfClass:[UITextField class]])
{
if([[field text] length] > 0)
{
[mutableTextArray addObject:field.text];
//NSLog(#"Save button 1 : %#", mutableTextArray);
//NSString *str = [str stringByAppendingString:[mutableTextArray objectAtIndex:0]];
//[self fetchStrings:mutableTextArray];
}
}
}
NSLog(#"Save button 2 : %#", mutableTextArray);
[self fetchStrings:mutableTextArray];
}
Now while posting the answer to another web service (web service 3 in my flow), I must pass slno, order, flag i get from web service 2 and the 'answer' that the user enters in the dynamically created field to the 'answer' key. How shall I get these 4 parameters [slno, order, flag (from web service 2) and answer (from dynamic text field)] to post to web service 3?
- (void) fetchStrings:(NSArray *)textArray
{
NSLog(#"Array string = %#", textArray); //I get the array that the user enters in the dynamically created text field here
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSUserDefaults *getDefaults = [NSUserDefaults standardUserDefaults];
NSString *uidObject = [getDefaults objectForKey:#"UIDKEY"];
NSString *str = [NSString stringWithFormat:#"{\"ProjID\": \"%#\",\"Uid\": \"%#\",\"EmailID\": \"%#\",", projectIdGobal, uidObject, emailFromLogin];
str = [str stringByAppendingString:#"\"ProjectInviterFQAnswers\": ["];
**for (SaveAsking *saveAsk in textArray) {
str = [str stringByAppendingString:[NSString stringWithFormat:#"{\"slno\":\"%#\",\"Answer\": \"%#\",\"order\": \"%#\", \"flag\": \"%#\"},", saveAsk.slno, saveAsk.answer, saveAsk.order, saveAsk.flag]]; // I want to save the parameters here
}**
// SaveAsking is a nsobject class where I have used a self created delegate for slno answer order and flag
str = [str stringByAppendingString:#"]}"];
NSLog(#"String is === %#", str);
NSURL *url = [NSURL URLWithString:#"some url"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
NSData *requestData = [str dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:[NSString stringWithFormat:#"%d", [requestData length]] forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody: requestData];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
if(error || !data)
{
NSLog(#"JSON Data not posted!");
[activity stopAnimating];
UIAlertView *alertMessage = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Data not saved" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertMessage show];
}
else
{
[activity startAnimating];
NSLog(#"JSON data posted! :)");
NSError *error = Nil;
NSJSONSerialization *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
NSLog(#"Response is %#", jsonObject);
}
}];
}
Please do correct my flow if you understood what am i trying to achieve. Number for iterations in left box == number of iterations in right box and the result is in the middle box which needs to be posted to web service.
Try keeping a dictionary of the requests, where the key would be the dynamically created UITextField, and the value would be another dictionary with the values that you need to send.
So , when you create the textField, after adding it to the subview, create a dictionary with your values (sino, order, flag), and set that dictionary to the textfield.
When you are ready to send the data, you'll have a direct connection between the textField and the values for your webservice3.
Related
UPDATE
I am making an api call getPacks() and successfully getting the values of two variables _numberOfPacks and _numberOfAutoRefills.
However, when I try to put it in a label it fails and gives output as (null) Packs & (null) Autorefiils
the calls are made in the following order:
getpacks()-------first (it sets value on _numberOfPacks and _numberOfAutoRefills as global variables
drawQuantity()-----set _numberOfPacks and _numberOfAutoRefills on labels.
-(void) getPacks: (IHPlacedOrder*)order{
NSOperationQueue *networkQueue = [[NSOperationQueue alloc] init];
networkQueue.maxConcurrentOperationCount = 5;
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"https://XXXXXXX.XXXXX/%#",order.ID]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]
initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString *string = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
if([string isEqualToString:#""]){
} else {
NSMutableDictionary *dict=[NSJSONSerialization JSONObjectWithData:[string dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:nil];
NSLog(#"%#",dict);
_numberOfPacks = [[dict objectForKey:#"prescription_interval"] valueForKey:#"quantity_per_interval"];
_numberOfAutoRefills = [[dict objectForKey:#"prescription_interval"]valueForKey:#"num_intervals"];
NSLog(#"PACKS:%# , AUTOREFILLS:%#",_numberOfPacks,_numberOfAutoRefills);
_quantity.text = [NSString stringWithFormat: #"%#,%#",_numberOfPacks,_numberOfAutoRefills];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"%s: AFHTTPRequestOperation error: %#", __FUNCTION__, error);
}];
[networkQueue addOperation:operation];
}
followed by:
-(void)drawQuantity: (IHPlacedOrder*)order{
PPLinearLayoutLabelItem *quantityLabel = [[PPLinearLayoutLabelItem alloc] initWithText:[NSString stringWithFormat:#"%# QUANTITY & %# REFILLS", _numberOfPacks,_numberOfAutoRefills] font:[PPFonts regular18] maxWidth:[LayoutValues getMaxWidthClipped]];
[quantityLabel setPaddingBottom:5];
[quantityLabel setPaddingTop:20];
[self.topContainerContent addObject:quantityLabel];
NSString* quantityText = [NSString stringWithFormat:#"Packs + Autorefills"];
PPLinearLayoutLabelItem *quantity = [[PPLinearLayoutLabelItem alloc] initWithText:quantityText font:[PPFonts genericParagraphFontBold] maxWidth:[LayoutValues getMaxWidthClipped]];
[quantity setPaddingBottom:20];
[self.topContainerContent addObject:quantity];
LinearLayoutHorizontalLine *line1 = [[LinearLayoutHorizontalLine alloc] initWithMaxWidth:[LayoutValues getMaxWidthClipped]];
[self.topContainerContent addObject:line1];
}
I found the solution. I was using wrong method call to set labels. The thing is my application uses PPLinearLayoutLabelItem as a custom built label. I had to call [self.quantity setLabel:#"%#",data_fromapi] to make it work. setText would just set the text within PPLinearLayoutLabelItem class and not set the Label.
I am trying to make a nsurl request and manage to retrieve the web response data out. The problem is i want to retrieve the specific parameter from the JSON list. The parameter i want to retrieve is "id" and display it out in a label.
Here is my viewDIDLoad for establishing the connection:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
feeds = [[NSMutableArray alloc] init];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"https://coolsoft.mousy.com/v1/messi/reports"]];
// Prepare the variables for the JSON response
// Create a mutable copy of the immutable request and add more headers
NSMutableURLRequest *mutableRequest = [request mutableCopy];
[mutableRequest addValue:#"application/json" forHTTPHeaderField:#"request"];
// Make synchronous request
request = [mutableRequest copy];
// Log the output to make sure our new headers are there
NSLog(#"%#", request.allHTTPHeaderFields);
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
if(connection)
{
_webResponseData = [NSMutableData data] ;
}
else
{
NSLog(#"Connection is NULL");
}
}
His is my connectionDidFinishLoading method:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSLog(#"Received %lu Bytes", (unsigned long)[_webResponseData length]);
// NSString *theXML = [[NSString alloc] initWithBytes:
// [_webResponseData mutableBytes] length:[_webResponseData length] encoding:NSUTF8StringEncoding];
// convert to JSON
NSError *myError = nil;
NSDictionary *res = [NSJSONSerialization JSONObjectWithData:self.webResponseData options:NSJSONReadingMutableLeaves error:&myError];
NSString *icon;
// show all values
for(id key in res) {
id value = [res objectForKey:key];
NSString *keyAsString = (NSString *)key;
NSString *valueAsString = (NSString *)value;
NSLog(#"key: %#", keyAsString);
NSLog(#"value: %#", valueAsString);
}
// extract specific value...
NSArray *results = [res objectForKey:#"id"];
for (NSDictionary *result in results) {
icon = [result objectForKey:#"id"];
NSLog(#"icon: %#", icon);
}
output.text = icon;
output = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 200, 100)]; //adjust label size and position as needed
output.font = [UIFont fontWithName:#"BradleyHandITCTT-Bold" size: 23.0];
output.textColor = [UIColor whiteColor];
output.textAlignment = NSTextAlignmentCenter;
output.numberOfLines = 0; //note: I said number of lines need to be 2
output.backgroundColor = [UIColor clearColor];
output.adjustsFontSizeToFitWidth = YES;
output.tag = 100;
}
Here is output when i NSLOG the res dictionary:
( { date = "2014-08-28T00:00:00Z"; id = 300005; title = "July 2014 USAA Phishing Campaign Uses KeNiHaCk Exploit"; uri = "/v1/joker/reports/300005"; }, { date = "2014-12-16T20:46:29Z"; id = 300062; title = "Two-Year Chinese Spearphishing Campaign Largely Targeted Japanese Aerospace and Energy Industries"; uri = "/v1/joker/reports/300062"; },
Here is my error message:
-[__NSCFArray objectForKey:]: unrecognized selector sent to instance 0x136713360
2015-12-30 11:58:17.692 FYP_IOS_APP[817:323807] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFArray objectForKey:]: unrecognized selector sent to instance 0x136713360'
Your JSON response is {"id":300005,"title":"pink","date":"2014-08-28T00:00:00Z","uri":"www.hipster.com/hip"}}
So, You can use like, lblName.text = [res valueForKey:#"id"];
Your json parsing is OK and it gives you JSON to NSDictionary
but you need some minor changes in pasing that NSDictionary object as below.
see this below code & It may help you
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
//{"id":300005, "title":"pink", "date":"2014-08-28T00:00:00Z", "uri":"www.hipster.com/hip"}
NSLog(#"Received %lu Bytes", (unsigned long)[_webResponseData length]);
// convert to JSON
NSError *myError = nil;
NSDictionary *res = [NSJSONSerialization JSONObjectWithData:self.webResponseData options:NSJSONReadingMutableLeaves error:&myError];
NSString *icon;
// show all values
for(id key in [res allKeys]) {
NSLog(#"key: %#", key);
NSLog(#"value: %#", [res objectForKey:key]);
}
// extract specific value...
icon = [res valueForKey:#"id"];
NSLog(#"icon: %#", icon);
output.text = icon;
output = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 200, 100)]; //adjust label size and position as needed
output.font = [UIFont fontWithName:#"BradleyHandITCTT-Bold" size: 23.0];
output.textColor = [UIColor whiteColor];
output.textAlignment = NSTextAlignmentCenter;
output.numberOfLines = 0; //note: I said number of lines need to be 2
output.backgroundColor = [UIColor clearColor];
output.adjustsFontSizeToFitWidth = YES;
output.tag = 100;
}
update
// convert to JSON
NSError *myError = nil;
NSArray *res = [NSJSONSerialization JSONObjectWithData:self.webResponseData options:NSJSONReadingMutableLeaves error:&myError];
// show all values
for(NSDictionary *dic in res) {
for(NSString *key in [dic allKeys]) {
NSLog(#"key: %#", key);
NSLog(#"value: %#", [dic objectForKey:key]);
}
}
I have a recursive loop using NSTimer that runs every two seconds and calls a function that calls the setupPhpCall function:
There are 3 NSTimers that run and always hits the setupPhpCall function,
could this be where the memory leakage is happening?
-(NSString*)setupPhpCall:(NSString*)requestString :(NSString*)sciptPage{
NSData *myRequestData = [NSData dataWithBytes: [requestString UTF8String] length: [requestString length]];
// Create your request string with parameter name as defined in PHP file
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: [NSString stringWithFormat: #"http://www.xxxx.co.uk/%#", sciptPage]]];
// set Request Type
[request setHTTPMethod: #"POST"];
// Set content-type
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"content-type"];
// Set Request Body
[request setHTTPBody: myRequestData];
// Now send a request and get Response
NSHTTPURLResponse* urlResponse = nil;
NSError *error = [[NSError alloc] init];
NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse:&urlResponse error: &error];
// Log Response
NSString *response = [[NSString alloc] initWithBytes:[returnData bytes] length:[returnData length] encoding:NSUTF8StringEncoding];
NSLog(#"%#",response);
return response;
}
This is the recursive method thats called using NSTimer:
-(void)recurseForumActivity:(NSTimer *)timer{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(concurrentQueue, ^{
NSString *myRequestString = [NSString stringWithFormat:#"lastDate=%#&threadTitle=%#&threadCountry=%#&threadCategory=%#&threadSubCategory=%#&getData=0",lastDateForumActivity,searchThreadTitle, searchThreadCountry, searchThreadCategory, searchThreadSubCategory];
NSString *response = [self setupPhpCall:myRequestString :#"xxx.php"];
dispatch_async(dispatch_get_main_queue(), ^{
if(response.length > 0 && ![response isEqualToString:#"[]"]){
labelNewForumThreads.text = [NSString stringWithFormat:#"%# new threads...", response];
if(imageviewForumAlert == NULL){
UIImage *image = [UIImage imageNamed:#"alert.png"];
imageviewForumAlert = [UIImageView new];
[viewNav1 addSubview:imageviewForumAlert];
imageviewForumAlert.translatesAutoresizingMaskIntoConstraints = NO;
imageviewForumAlert.image = image;
NSDictionary *viewsDictionary = #{#"imageviewForumAlert":imageviewForumAlert};
NSArray *constraint_H = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-19-[imageviewForumAlert(12)]-19-|"
options:0
metrics:nil
views:viewsDictionary];
NSArray *constraint_V = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-19-[imageviewForumAlert(12)]-19-|"
options:0
metrics:nil
views:viewsDictionary];
[self.view addConstraints:constraint_H];
[self.view addConstraints:constraint_V];
}else{
imageviewForumAlert.hidden = NO;
}
/**NSDictionary *dic = [response JSONValue];
if((NSNull*)dic != [NSNull null]){
labelNewForumThreads.text = [NSString stringWithFormat:#"%d new threads...", dic.count];
}**/
}else{
imageviewForumAlert.hidden = YES;
labelNewForumThreads.text = [NSString stringWithFormat:#"%d new threads...", 0];
}
/**else{
labelNewForumThreads.text = [NSString stringWithFormat:#"%d new threads...", 0];
}**/
});
});
}
EDIT
In the console i get this error after i have left the app to run for more than one hour:
Communications error: <OS_xpc_error: <error: 0x361c0614> { count = 1, contents =
"XPCErrorDescription" => <string: 0x361c086c> { length = 22, contents = "Connection interrupted" }
}>
i have Allocation tool running aswel
this is the screenshot of allocation tool when the app crashes
EDIT
EDIT
I have also noticed when starting Instrument Allocations tool my memory usage rapidly shots up quicker, why is this?
The app keeps score during a game. Based off of your score, it will retrieve a quote from an online database, using a GET method and returning it in JSON format. For example, your score is 5, you get 1 quote, 10, you get 2 and so on. The view that shows the quote(s) is a UIViewController with a UITextView in it.
I have a for loop that runs based off the score, to run the same GET request over and over again, after a 1.5 second delay so the server housing the database won't reject requests made nearly simultaneously.
I create a few NSStrings and pull information from the JSON data, append it into some basic HTML code and then set that as the UITextView attributedText.
Most of the time this runs great, but every once in a while, I'll expect 2 quotes, and only get 1, or some of the quotes will wind up being the same.
Can someone tell me if there is a better way to go about doing this than how I currently am?
- (void)viewWillAppear:(BOOL)animated {
if ([textView.text isEqualToString:#""]) {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSInteger getReady = [defaults integerForKey:#"after"];
self.theNumber = getReady;
for(int i = 0; i< self.theNumber; i++) {
[self performSelector:#selector(quoteView) withObject:self afterDelay:1.5 ];
}
}
}
-(void) quoteView {
NSString *bringitalltogether = #"http://url.com&type=json";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:bringitalltogether]
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:60];
[request setHTTPMethod:#"GET"];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
if ([response isKindOfClass:[NSHTTPURLResponse class]])
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*) response;
if (code == 200){
}
else
{
UIAlertView *oops = [[UIAlertView alloc] initWithTitle:#"Oops" message:#"The network is having difficulties getting you the quote. Please check your network settings and try again later." delegate:self cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[oops show];
}
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSMutableDictionary *allResults = [NSJSONSerialization
JSONObjectWithData:data
options:NSJSONReadingAllowFragments
error:nil];
NSArray *book = [allResults valueForKey:#"bookname"];
self.bookstring = [book objectAtIndex:0];
NSArray *chapter = [allResults valueForKey:#"chapter"];
self.chapterstring = [chapter objectAtIndex:0];
NSArray *verse = [allResults valueForKey:#"verse"];
self.versestring = [verse objectAtIndex:0];
NSArray *text = [allResults valueForKey:#"text"];
self.textstring = [text objectAtIndex:0];
[self doneGotIt];
}
- (void) doneGotIt {
if (!self.theArray) {
self.theArray = [[NSMutableArray alloc] init];
}
NSString *doIt = [NSString stringWithFormat:#"%# - %# %#:%#", self.textstring, self.bookstring, self.chapterstring, self.versestring];
[self.theArray addObject:doIt];
NSString *theEnd = [self.theArray componentsJoinedByString:#"\n"];
NSString *loadHTML = [#"<head> <style type='text/css'>a > img {pointer-events: none;cursor: default;}</style></head><b><div align=\"left\"><font size=5>" stringByAppendingString:theEnd];
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithData:[loadHTML dataUsingEncoding:NSUnicodeStringEncoding] options:#{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
textView.attributedText = attributedString;
NSLog(#"ARRAY: %#", self.theArray);
NSLog(#"String: %#", theEnd);
}
-(IBAction)finished {
[self dismissViewControllerAnimated:YES completion:nil];
textView = nil;
}
From the NSLogs I have towards the end there, sometimes the NSMutableArray contains several of the same quotes, which is why they don't show in the string, because it eliminates duplicates. My question is if there is a better way to do this that will keep these errors from occurring?
Here is some pseudo code for you
mutableArray = new NSMutableArray
while([mutableArray count] < total) {
quote = getQuote()
if([array indexOfObject:quote] != NSNotFound)
[mutableArray addObject:quote]
}
This will ensure you do not have duplicate quotes. After you have an array of valid quotes, you can then construct the string exactly how you want it.
I know that there are plenty of questions that have been asked and answered and non of them pertain to my problem.
I am posting XML to a server and I get a response back. My problem is getting a specified key back from the response.
I am trying to list all Genders e.g Male, Female and their id's however when parsing the XML into text with NSXML I only get back the Female and ID 2 and I do not get back Male?
I have researched and tried to fix this issue but to no avail.
here is my code:
- (void)getGender {
NSString *soapMessage = [NSString stringWithFormat:
#"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:app=\"http://app.ws.api.bells.wigroup.com/\">"
"<soap:Header/>\n"
"<soap:Body>\n"
"<app:getAllGenders>\n"
"<request>\n"
"<apiCredentials>\n"
"<apiId>IPHONE_APP</apiId>\n"
"<sha1Password>8656cafcd71cbbfe773a0fdb6c422666a80e5b8f</sha1Password>\n"
"</apiCredentials>\n"
"<request>\n"
"</request>\n"
"</request>\n"
"</app:getAllGenders>\n"
"</soap:Body>\n"
"</soap:Envelope>\n"
];
NSLog(#"Message%#",soapMessage);
NSURL *url = [NSURL URLWithString:#"http://qa.wigroup.co:8080/bells/AppWS"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:#"%d", [soapMessage length]];
[theRequest addValue: #"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
//[theRequest addValue: #"http://" forHTTPHeaderField:#"SOAPAction"];
[theRequest addValue: msgLength forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPMethod:#"POST"];
[theRequest setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if( theConnection )
{
NSURLResponse *response;
NSError *error;
NSData *urlData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&response error:&error];
NSString *str=[[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
NSLog(#"Login response XML:%#",str);
// create and init NSXMLParser object
XmlArrayParser *parser = [[XmlArrayParser alloc] initWithData:urlData];
parser.rowElementName = #"return";
parser.elementNames = [NSArray arrayWithObjects:#"response", #"responseCode", #"responseDesc", #"gendersList", nil];
parser.attributeNames = [NSArray arrayWithObjects:#"id", #"gender", nil];
if ([parser.rowElementName isEqualToString:#"responseCode"] && _flag)
{
//read the value here
NSLog(#"flagging");
}
// parsing...
BOOL success = [parser parse];
// test the result
if (success)
{
NSMutableArray *loginAuth = [parser items];
// self.textView.text = [NSString stringWithFormat:
// #"This is an array of dictionaries, one dictionary for each user:\n\n%#",
// [users description]];
// NSDictionary *eventLocation = [NSDictionary dictionaryWithObjectsAndKeys:#"response", nil];
NSDictionary *loginResponse = [loginAuth objectAtIndex:0]; // this retrieves the first user
NSString *userResponse = loginResponse[#"gendersList"]; // this retrieves that user's username in Xcode 4.5 and greater
NSString *userRes = [loginResponse objectForKey:#"id"];
NSString *test = [loginAuth description];
NSLog(#"Returned Code loginResponse %#",loginResponse);
NSLog(#"Returned Code userResponse %# %#",userResponse, userRes);
NSLog(#"Returned Code test %#",test);
NSMutableArray *array=[[NSMutableArray alloc]initWithCapacity:10];
for (NSDictionary *defineXMLData in loginAuth) {
NSNumber * responseCode = [defineXMLData objectForKey:#"responseCode"];
NSArray * responseDEsc = [defineXMLData objectForKey:#"responseDesc"];
NSArray * genderList = [defineXMLData objectForKey:#"gendersList"];
// NSArray * gender = [defineJsonData objectForKey:#"gender"];
NSLog(#"Genders%#", genderList);
[array addObject: responseCode];
[array addObject: responseDEsc];
[array addObject: genderList];
//[array addObject: gender];
// [array addObject: vouchersUser];
}
label.numberOfLines = 2000; // for example
label.lineBreakMode = NSLineBreakByClipping;
NSString *output=[array componentsJoinedByString:#","];
label.text = [NSString stringWithFormat:#"XML Result: %# ",output];
[SVProgressHUD dismiss];
// [[[UIAlertView alloc] initWithTitle:nil
// message:[NSString stringWithFormat:#"No errors - user count : %i", [[parser items] count]]
// delegate:nil
// cancelButtonTitle:#"OK"
// otherButtonTitles:nil] show];
}
else
{
NSLog(#"Error parsing document!");
// [[[UIAlertView alloc] initWithTitle:nil
// message:#"Error parsing document!"
// delegate:nil
// cancelButtonTitle:#"OK"
// otherButtonTitles:nil] show];
}
}
else
{
NSLog(#"theConnection is NULL");
}
NSLog(#"test");
}
And the XML I get back from my nslog:
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getAllGendersResponse xmlns:ns2="http://app.ws.api.bells.wigroup.com/">
<return>
<responseCode>-1</responseCode>
<responseDesc>Success</responseDesc>
<response>
<responseCode>-1</responseCode>
<responseDesc>Success</responseDesc>
<gendersList>
<gender>Male</gender>
<id>1</id>
</gendersList>
<gendersList>
<gender>Female</gender>
<id>2</id>
</gendersList>
</response>
Is only parsing:
{
gendersList = Female2;
responseCode = "-1";
responseDesc = Success;
}
You have not correctly pointed the problem. Your code parses the whole document, but you keep only the last items (last genderList, last responseCode, last responseDesc). Initialize an array and in your for loop add each dictionary to that array when parsed.