I am a .Net programmer and a beginner in Xcode. I want to display the result from a WCF service on the iPad in UITableViewController. I have successfully created stubs for the service by using wsdl2objc. The SOAP message created is as follows:
2012-07-25 14:02:37.169 TestWCF[5280:fb03] OutputHeaders:
{
"Content-Length" = 572;
"Content-Type" = "text/xml; charset=utf-8";
Host = "XXX.XXX.XXX";
SOAPAction = "http://tempuri.org/IDocSync/getAllCategories";
"User-Agent" = wsdl2objc;
}
2012-07-25 14:02:37.172 TestWCF[5280:fb03] OutputBody:
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema- instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:iPadDocSyncServiceSvc="http://tempuri.org/" xmlns:ns1="http://tempuri.org/Imports" xmlns:tns1="http://schemas.datacontract.org/2004/07/DocSyncService" xmlns:tns2="http://schemas.microsoft.com/2003/10/Serialization/" xsl:version="1.0">
<soap:Body>
<iPadDocSyncServiceSvc:getAllCategories/>
</soap:Body>
</soap:Envelope>
2012-07-25 14:03:03.119 TestWCF[5280:fb03] ResponseStatus: 200
2012-07-25 14:03:03.120 TestWCF[5280:fb03] ResponseHeaders:
{
"Cache-Control" = private;
"Content-Encoding" = gzip;
"Content-Length" = 421;
"Content-Type" = "text/xml; charset=utf-8";
Date = "Wed, 25 Jul 2012 06:03:02 GMT";
Server = "Microsoft-IIS/7.5";
"Set-Cookie" = "ASP.NET_SessionId=55w4noiub50zqtqclwdx3ral; path=/; HttpOnly";
Vary = "Accept-Encoding";
"X-AspNet-Version" = "4.0.30319";
"X-Powered-By" = "ASP.NET";
}
2012-07-25 14:03:03.121 TestWCF[5280:fb03] ResponseBody:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<getAllCategoriesResponse xmlns="http://tempuri.org/">
<getAllCategoriesResult xmlns:a="http://schemas.datacontract.org/2004/07/DocSyncService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:Category>
<a:categoryId>4</a:categoryId>
<a:categoryName>IT</a:categoryName>
<a:categoryType>0</a:categoryType>
<a:docCount>3</a:docCount>
<a:subCategoryId>0</a:subCategoryId>
</a:Category>
<a:Category>
<a:categoryId>6</a:categoryId>
<a:categoryName>CPG</a:categoryName>
<a:categoryType>0</a:categoryType>
<a:docCount>1</a:docCount>
<a:subCategoryId>0</a:subCategoryId>
</a:Category>
</getAllCategoriesResult>
</getAllCategoriesResponse>
</s:Body>
</s:Envelope>
The code in Appdelegate.m is:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
BasicHttpBinding_IDocSyncBinding *myBinding = [iPadDocSyncServiceSvc BasicHttpBinding_IDocSyncBinding];
myBinding.logXMLInOut = YES;
//iPadDocSyncServiceSvc_getAllCategories *allCate = [[iPadDocSyncServiceSvc_getAllCategories new]autorelease];
iPadDocSyncServiceSvc_getAllCategories *allCate = [[iPadDocSyncServiceSvc_getAllCategories alloc]init];
BasicHttpBinding_IDocSyncBindingResponse *response = [myBinding getAllCategoriesUsingParameters:allCate];
for(id bodyPart in response.bodyParts)
{
//if([bodyPart isKindOfClass:[BasicHttpBinding_IDocSyncBindingResponse class]])
//{
//tns1_ArrayOfCategory *cateClass = (tns1_ArrayOfCategory *) bodyPart;
//[self.tableView reloadData];
//categories = (NSMutableArray *) cateClass;
//tns1_ArrayOfCategory *cateClass = [bodyPart getAllCategoriesResult];
self.categories = (NSMutableArray *) [bodyPart getAllCategoriesResult];
//}
}
return YES;
}
When I run this,nothing is displayed in the Simulator...it shows a blank screen. There is something very obvious that I am missing. How can I get it working?
I wrote a few tutorials using Wsdl2Objc a while back; maybe they can help.
http://brismith66.blogspot.com/search/label/iPhone%20Development
Related
I'm using Sudzc to parse a soap XML.
I'm setting up:
amount.currency = #"BRL";
It gives me the following error:
validation 138 Unsupported currency specified
logcat:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soap:Body><soap:Fault><faultcode>soap:Server</faultcode><faultstring>validation 138 Unsupported currency specified</faultstring></soap:Fault></soap:Body></soap:Envelope>
I know that the wsdl is good. So Where should I look to find this error?
SDZPayment* service = [SDZPayment service];
service.logging = YES;
service.username = #"**************";
service.password = #"****************";
SDZAmount *amount = [SDZAmount new];
amount.value = (long)100;
amount.currency = #"BRL";
SDZCard *card = [SDZCard new];
card.cvc = #"412";
card.number = #"21432423423";
card.holderName = #"Marcus Ataide";
card.expiryMonth = #"12";
card.expiryYear = #"2017";
card.brand = #"visa";
card.issueNumber = #"10";
card.startMonth = #"10";
card.startYear = #"2010";
SDZPaymentRequest *payment = [SDZPaymentRequest new];
payment.amount = amount;
payment.card = card;
payment.merchantAccount = #"*************";
payment.shopperReference = #"123456";
// Returns SDZPaymentResult*
/* */
[service authorise:self action:#selector(authoriseHandler:) paymentRequest: payment];
From web service:
<xsd:complexType name="Amount">
<xsd:sequence>
<xsd:element minOccurs="1" name="currency">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:minLength value="3"/>
<xsd:maxLength value="3"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element minOccurs="1" name="value" type="xsd:long"/>
</xsd:sequence>
</xsd:complexType>
The problem was with namespace:
Inside, "SDZAmount.m", I need to change:
[s appendString: [Soap serialize: self.currency]];
to:
[s appendFormat: #"<currency xmlns=\"http://common.services.adyen.com\">%#</currency>", [Soap serialize: self.currency]];
I am using QuickBlox in my iOS app and trying to add data in Places table
QBLPlace *place = [QBLPlace place];
place.geoDataID = 34691;
place.photoID = 447;
place.title = [NSString stringWithFormat:#"%#",[aView.annotation title]];
place.address = #"London, Gadge st, 34";
place.placeDescription = #"My place description";
place.latitude = pinLocation.coordinate.latitude;
place.longitude = pinLocation.coordinate.longitude;
[QBLocation createPlace:place delegate:self];
but I am not able to add place. Below is the console log
RestRequest:
POST http://api.quickblox.com/places.xml
headers:{
"QB-SDK" = "iOS 1.3.1";
"Qb-Token" = c1191ff8ffbfdb79b11fba6bf2a4c054d2644de8;
"QuickBlox-REST-API-Version" = "0.1.1";
}
parameters:{
"place[address]" = "London, Gadge st, 34";
"place[description]" = "My place description";
"place[geo_data_id]" = 34691;
"place[photo_id]" = 447;
"place[title]" = "The Bridge Room";
}
raw body:place[address]=London%2C%20Gadge%20st%2C%2034&place[description]=My%20place%20description&place[geo_data_id]=34691&place[photo_id]=447&place[title]=The%20Bridge%20Room
2013-01-02 10:21:14.543 Chat.Points[10229:1d903] Query QBLPlaceCreateQuery DEALLOC
2013-01-02 10:21:14.551 Chat.Points[10229:1d903] Request finished, response:
RestResponse:
<QBASIHTTPRequest: 0xb40fc00>
headers:{
"Access-Control-Allow-Origin" = "*";
"Access-Control-Request-Method" = "*";
"Cache-Control" = "no-cache";
Connection = Close;
"Content-Length" = 116;
"Content-Type" = "application/xml; charset=utf-8";
Date = "Wed, 02 Jan 2013 04:51:14 GMT";
"QuickBlox-REST-API-Version" = "0.1.1";
Server = "nginx/1.0.15";
Status = "422 Unprocessable Entity";
"X-Rack-Cache" = "invalidate, pass";
"X-Request-Id" = 5ad6e7d628b4fbd931b7896058f012cd;
"X-Runtime" = "0.052140";
"X-UA-Compatible" = "IE=Edge,chrome=1";
}
body:<?xml version="1.0" encoding="UTF-8"?>
<errors type="array">
<error>No photo with such id found</error>
</errors>
The right way to create place is:
QBLPlace *place = [QBLPlace place];
place.geoDataID = 34691;
place.photoID = 447;
place.title = [NSString stringWithFormat:#"%#",[aView.annotation title]];
place.address = #"London, Gadge st, 34";
place.placeDescription = #"My place description";
[QBLocation createPlace:place delegate:self];
where:
geoDataID - ID of QBLGeoData object
photoID - ID of QBCBlob object
Your error says that you have to create file with photo and then connect it to place.
To upload file please use this code:
NSData *file = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Hotel47" ofType:#"png"]];
[QBContent TUploadFile:file fileName:#"Hotel47 Image" contentType:#"image/png" isPublic:YES delegate:self];
#pragma mark -
#pragma mark QBActionStatusDelegate
- (void)completedWithResult:(Result *)result{
// Upload file result
if(result.success && [result isKindOfClass:[QBCFileUploadTaskResult class]]){
// File uploaded, do something
QBCBlob *uploadedFile = ((QBCFileUploadTaskResult *)result).uploadedBlob;
NSUInteger photoID = uploadedFile.ID; // use this as photo IS for place
}else{
NSLog("errors=%#", result.errors);
}
}
To create GeoData please use next code:
QBLGeoData *geodata = [QBLGeoData geoData];
geodata.latitude = 23.2344;
geodata.longitude = -12.23523;
geodata.status = #"Hello, world";
[QBLocation createGeoData:geodata delegate:self];
#pragma mark -
#pragma mark QBActionStatusDelegate
- (void)completedWithResult:(Result *)result{
// Check-in result
if(result.success && [result isKindOfClass:QBLGeoDataResult.class]){
QBLGeoDataResult *checkinResult = (QBLGeoDataResult *)result;
NSUInteger geoDataID = checkinResult.geoData.ID; // your geo data ID
}else{
NSLog(#"errors=%#", result.errors);
}
}
After being very disappointed with CLGeocoder, I decided to use the GoogleMaps API instead.
I have designed the call as following, using AFNetwork :
AFHTTPClient *new = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:#"http://maps.googleapis.com/"]];
NSDictionary *dict = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:#"thorsgade",#"true", nil] forKeys:[NSArray arrayWithObjects:#"address",#"sensor", nil]];
NSMutableURLRequest *req = [new requestWithMethod:#"GET" path:#"maps/api/geocode/json" parameters:dict];
AFJSONRequestOperation *call = [AFJSONRequestOperation JSONRequestOperationWithRequest:req success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSArray *geos = [JSON objectForKey:#"results"];
DLog(#"Got result : '%#' %# from %# %# %#",JSON,geos,[NSHTTPURLResponse localizedStringForStatusCode:response.statusCode],response.allHeaderFields,request.URL.description);
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
DLog(#"Failed %# %#",error.localizedDescription,request.URL.description);
}];
[call start];
I get this feedback:
Got result : '(null)' (null) from no error {
"Cache-Control" = "public, max-age=86400";
"Content-Encoding" = gzip;
"Content-Length" = 1603;
"Content-Type" = "application/json; charset=UTF-8";
Date = "Fri, 07 Dec 2012 08:51:58 GMT";
Expires = "Sat, 08 Dec 2012 08:51:58 GMT";
Server = mafe;
Vary = "Accept-Language";
"X-Frame-Options" = SAMEORIGIN;
"X-XSS-Protection" = "1; mode=block"; } http://maps.googleapis.com/maps/api/geocode/json?sensor=true&address=thorsgade
Null result, but no errors. The content is recognized in the headers as JSON, but the raw JSON is null.
The annoying thing is that if I open http://maps.googleapis.com/maps/api/geocode/json?sensor=true&address=thorsgade in a browser, i get plenty of results.
So far i have tried:
Flicking the sensor booleon true/false.
Faking the user-agent to be regular safari.
Use POST instead of GET.
With no luck...
If the problem persists, I would recommend using MKNetworkKit instead
Here is my solution -
GoogleGeocodeApi.h
//GoogleGeocodeApi.h
#import <Foundation/Foundation.h>
#import "MKNetworkEngine.h"
typedef void (^JsonResponseBlock)(NSDictionary *);
typedef void (^ErrorBlock)(NSError* error);
#interface GoogleGeocodeApi : MKNetworkEngine
-(MKNetworkOperation*) geocodeWithAddress: (NSString *) address
onCompletion:(JsonResponseBlock) completionBlock
onError:(ErrorBlock) errorBlock;
#end
GoogleGeocodeApi.m
//GoogleGeocodeApi.m
#import "GoogleGeocodeApi.h"
#implementation GoogleGeocodeApi
-(id)init
{
if (self = [super initWithHostName:#"maps.googleapis.com" apiPath:#"maps/api/geocode" customHeaderFields:nil]) {
}
return self;
}
-(MKNetworkOperation*) geocodeWithAddress: (NSString *) address
onCompletion:(JsonResponseBlock) completionBlock
onError:(ErrorBlock) errorBlock;
{
MKNetworkOperation *op = [self operationWithPath:[NSString stringWithFormat:#"json?sensor=true&address=%#", address] params:nil httpMethod:#"GET"];
[op onCompletion:^(MKNetworkOperation *completedOperation) {
NSDictionary *responseJSON = [completedOperation responseJSON];
if (responseJSON && [[responseJSON objectForKey:#"status"] isEqualToString:#"OK"]) {
completionBlock(responseJSON);
} else {
NSDictionary* errorDictionary = #{NSLocalizedDescriptionKey :#"Google geocode failed!"};
NSError *error = [NSError errorWithDomain:#"Failed response" code:100 userInfo:errorDictionary];
errorBlock(error);
}
} onError:^(NSError* error) {
errorBlock(error);
}];
[self enqueueOperation:op];
return op;
}
Somewhere in code
GoogleGeocodeApi *gma = [[GoogleGeocodeApi alloc] init];
[gma geocodeWithAddress:#"thorsgade"
onCompletion:^(NSDictionary *responseJSON) {
NSLog(#"Geocode succeeded: %#", responseJSON);
} onError:^(NSError *error) {
NSLog(#"Geocode failed with error: %#", [error localizedDescription]);
}];
I have an ARC-enabled project using RestKit and although most of my requests are done asynchronously, I am having an issue with performing a synchronous request:
In my AppDelegate:
else if (![IKUserController loggedInUserIsAuthenticated]) {
IKLoginViewController *loginVC = [[IKLoginViewController alloc] init];
loginVC.scenario = SCENARIO_EXISTING;
[self.window.rootViewController presentModalViewController:loginVC animated:YES];
}
In the implementation for loggedInUserIsAuthenticated:
+ (BOOL)loggedInUserIsAuthenticated {
IKUser *user = [IKUserController loggedInUser];
if (!user) {
return NO;
}
else {
NSString *username = user.userName;
NSString *password = user.userPassword;
if ([IKUserController loginWithUsername:username password:password]) {
return YES;
}
else {
return NO;
}
}
return NO;
}
and the loginWithUserName:password:
+ (BOOL)loginWithUsername:(NSString *)username password:(NSString *)password {
//return YES;
NSDictionary *params = [[NSDictionary alloc] initWithObjectsAndKeys:username, #"username", password, #"password", nil];
RKResponse *response = [[[RKClient sharedClient] post:#"/user/authenticate" params:params delegate:nil] sendSynchronously];
if (response.isOK) {
return YES;
}
else {
return NO;
}
return NO;
}
and the error:
*** Assertion failure in -[RKRequestQueue removeRequest:decrementCounter:], /Users/admin/Documents/dev/RestKit/Code/Network/RKRequestQueue.m:350
The RKClient method post already adds the request to the default request queue, so I think the problem is that you send the request twice - once async and once sync. Instead of using RKClient post method, configure the request manually. There is a method setupRequest on RKClient, this will make it easier for you and you will only need to define the url, method and params, like this:
RKRequest* req = [RKRequest requestWithURL:reqURL delegate:self];
[req setMethod:RKRequestMethodPOST];
[req setParams:params];
[client setupRequest:req];
[req sendSynchronously];
How to print NSMutableURLRequest using NSLog ?
.allHTTPHeaderFields returns a dictionary with the header content:
NSLog(#"%#", [request allHTTPHeaderFields]);
// {
// "Accept-Language" = "en;q=1";
// "Content-Length" = 190706;
// "Content-Type" = "multipart/form-data; boundary=Boundary+D90A259975186725";
// "User-Agent" = "...";
// }
Or for specific field:
NSString *field = #"Content-Type";
NSLog(#"%#",[request valueForHTTPHeaderField:field]);
// multipart/form-data; boundary=Boundary+D90A259975186725
Did you try with
NSLog(#" %#", myMutableURLRequest);