Взаимодействие iPhone с ASP.NET WebService

Мне нужно разработать приложение, которое будет запрашивать веб-службу, разработанную в ASP.NET.

Я не знаю, что такое код создания запроса на веб-службу asp.net,

Как веб-служба asp.net ответит на iPhone-приложение?

Как iPhone будет правильно анализировать этот ответ?

Я уже прочитал этот вопрос


Как получить данные из WebService в iPhone?
Но данная ссылка дает только файл .pdf.

Моя потребность - пример кода, который может объяснить мне, как сделать соединение и получить данные из веб-службы asp.net.

Ответы

Ответ 1

Фактически вы можете сделать веб-сервис и сделать его очень простым для интеграции в ваш iphone. Я бы предложил, если вы используете .net для создания службы WCF с помощью метода webHttp и внедрения методов get и post, вы можете получить ответы обратно в json и xml (theres набор классов для разбора Json на iphone, который будет обрабатывать ответ ветерок, они доступны в Интернете), с небольшой настройкой вы сможете выполнять получение и сообщение с iphone с помощью NSURLRequest. Вот статья, в которой говорится о том, чтобы сделать спокойную услугу wcf http://www.developer.com/net/article.php/10916_3695436_2. Его также очень легко добавить аутентификацию и безопасность для ваших сервисов с помощью WCF.

Ответ 2

- (void)viewDidLoad {
[super viewDidLoad];

// create a soap Message which is given in your required web service

NSString *[email protected]"<?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/\">\n"
"<soap:Body>\n"
"<GetCategory xmlns=\"http://tempuri.org/\" />\n"
"</soap:Body>\n"
"</soap:Envelope>";

// create a url to your asp.net web service.
NSURL *tmpURl=[NSURL URLWithString:[NSString stringWithFormat:@"http://192.168.32.10/Itavema/Admin/Itavema_Service.asmx"]];

// create a request to your asp.net web service.
NSMutableURLRequest *theRequest=[NSMutableURLRequest requestWithURL:tmpURl];

// add http content type - to your request
[theRequest addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];

// add  SOAPAction - webMethod that is going to be called
[theRequest addValue:@"http://tempuri.org/GetCategory" forHTTPHeaderField:@"SOAPAction"];

// count your soap message lenght - which is required to be added in your request
NSString *msgLength=[NSString stringWithFormat:@"%i",[soapMessage length]];
// add content length 
[theRequest addValue:msgLength forHTTPHeaderField:@"Content-Length"];

// set method - post
[theRequest setHTTPMethod:@"POST"];

// set http request - body
[theRequest setHTTPBody:[soapMessage dataUsingEncoding:NSUTF8StringEncoding]];

// establish connection with your request & here delegate is self, so you need to implement connection methods
NSURLConnection *con=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

// if connection is established
if(con)
{
    myWebData=[[NSMutableData data] retain];
    // here -> NSMutableData *myWebData; -> declared in .h file
}
}   

// a method when connection receives response from asp.net web server
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[myWebData setLength: 0];
}
// when web-service sends data to iPhone
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[myWebData appendData:data];
}
// when there is some error with web service
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[connection release];
}
// when connection successfully finishes 
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// check out your web-service retrieved data on log screen
NSString *theXML = [[NSString alloc] initWithBytes: [myWebData mutableBytes] length:[myWebData length] encoding:NSUTF8StringEncoding];
NSLog(@"%@",theXML);
[theXML release];

// if parser isn't nil. here NSXMLParser *myXMLParser; in .h file
if( myXMLParser )
{
    [myXMLParser release];
}

// supply your responded data to xmlParser - xmlParser will parse xmlData & then you can use it
myXMLParser = [[NSXMLParser alloc] initWithData: myWebData];

// here delegate self means implement xmlParse methods
[myXMLParser setDelegate: self];

[myXMLParser setShouldResolveExternalEntities: YES];

// parse method - will invoke xmlParserMethods
[myXMLParser parse];
[connection release];
[myWebData release];
}


//#pragma mark xmlParser
// suppose <myDataTag>myData</endmyDataTag> is the xmlData
// this function will read "<myDataTag>" & tag attributes
-(void)parser:(NSXMLParser*)parser 
                            didStartElement:(NSString*)elementName
                            namespaceURI:(NSString*)namespaceURI
                            qualifiedName:(NSString*)qualifiedName
                            attributes:(NSDictionary*)attributeDict
{
    if([elementName isEqualToString:@"GetCategoryResult"])
    {
        // here categoryArray is NSMutable array declared in .h file.
        // init your array when root element / document element is found
        CategoryArray=[[NSMutableArray alloc]init];
    }
    else if([elementName isEqualToString:@"Prop_Category"])
    {
        aCategory=[[Category alloc] init];
        // if a tag has attribues like <myDataTag id="sagar">
        //aCategory.ID=[attributeDict objectForKey:@"id"];
    }
}

// suppose <myDataTag>myData</endmyDataTag> is the xmlData
// this function will read "myData" & tag attributes
-(void)parser:(NSXMLParser*)parser
                            foundCharacters:(NSString*)string
{
    // here currentElementValue is an NSMutableString declared in .h file
    // store read characters in that mutable string & then add to your object.
    if(!currentElementValue)
    {
        currentElementValue=[[NSMutableString alloc] initWithString:string];
    }
    else
    {
        [currentElementValue appendString:string];
    }
}

// suppose <myDataTag>myData</endmyDataTag> is the xmlData
// this function will read "</endmyDataTag>" & tag attributes
-(void)parser:(NSXMLParser*)parser
            didEndElement:(NSString*)elementName
            namespaceURI:(NSString*)namespaceURI
            qualifiedName:(NSString*)qualifiedName
{
    if([elementName isEqualToString:@"GetCategoryResult"])
    {
        // if end of root element is found- i.e. end of your xml file.
        return;
    }
    else if([elementName isEqualToString:@"Prop_Category"])
    {
        // end of a single data element
        // suppose <category>
        //             <id>10</id>
        //             <name><sagar></name>
        //         </category>
        // when we found </category> we have finished entire category object.
        // here we have an object aCategory -> created custom class "Category"
        // CategoryClass -> NSString *name; NSInteger id;
        // Note: "important"
        //->class variables must be same as tag

        // now after reading entire object add to your mutable array
        // now this mutable array can be used for Table, UIPicker
        [CategoryArray addObject:aCategory];
        [aCategory release];
        aCategory=nil;
        [CategoryTable reloadData];
    }
    else
    {
        // which is equivalent to aCategory.id=10 & [email protected]"sagar"
        [aCategory setValue:currentElementValue forKey:elementName];

        // remove previously read data
        [currentElementValue release];
        currentElementValue=nil;
    }
}

Ответ 3

Hessian - гораздо лучший протокол связи, чем XML. Будучи двоичным форматом, он еще более компактен, а при строгом анализе формата намного быстрее.

В качестве бонуса уже существуют рамки для Java,.NET и PHP для публикации веб-службы. Действительно просто. У вас есть этот интерфейс С#:

public interface ITest {
  public string getGreeting();
  int addNumbers(int a, int b);
}

Затем, реализуя его на сервере с помощью HessianС#, вы можете:

public class CTest:CHessianHandler, ITest {
  public string getGreeting() { return "Hello World!"; }
  public int addNumbers(int a, int b) { return a + b; }
  [STAThread]
  private static void Main(string[] args) {
    CWebServer web = new CWebServer(5667, "/test/test.hessian", typeof (CTest));
    web.Paranoid = true;
    web.AcceptClient("[\\d\\s]");
    web.Run();
    for (;; ) {
      if (Console.ReadLine() != "") {
        web.Stop();
        break;
      }
    }
  }
}

На стороне iPhone интерфейс С# необходимо преобразовать в протокол Objective-C:

@protocol ITest
-(NSString*)getGreeting;
-(int)addNumbers:(int)a :(int)b;
@end

И затем с помощью HessianKit для получения прокси для службы почти так же легко:

id<ITest> proxy = [CWHessianConnection proxyWithURL:serviceURL
                                           protocol:@protocol(ITest)];
NSLog(@"Greeting: %@", [proxy getGreeting]);
NSLog(@"The answer: %d", [proxy addNumbers:40 :2]);

В этом кратком ответе имена методов не совсем совпадают с С#, но не совсем Obj-C-ish. Это связано с тем, что по умолчанию HessianKit использует соглашения об именах Java. Это можно переопределить в HessianKit, предоставив метод и переименовать имена имен. Так что обе стороны С# и Obj-C в соединении чувствуют себя на 100% дома. Например:

[CWHessianArchiver setClassName:@"com.mycompany.ITest" 
                    forProtocol:@protocol(CWTest)];
[CWHessianArchiver setMethodName:@"AddNumbers"
                     forSelector:@selector(addInt:toInt:)];

Ответ 4

Если вы не интегрируетесь с ASP.NET с обеих сторон, я бы, вероятно, избегал "веб-сервиса", а просто выводил свой собственный формат XML и обрабатывал его соответствующим образом на стороне iPhone с помощью XML lib.

Ответ 5

этот ответ устарел, но для протокола:

Я использую sudzc.com для преобразования моего веб-сервиса в классы Objective-C.

Он работает очень хорошо и значительно упрощает работу.

Cheers, Одед.

Ответ 6

Попробуйте wcf приятель, он позволяет создавать easilly SOAP webService, который вы можете вызывать из любого места