0

请不要关闭这个话题。我真的需要帮助。我正在 IOS 6.Xcode-4.5.2 上开发 单击按钮我从服务器获取以下 xml 数据

<country>america</country>
 <dateOfBirth xsi:nil="true"/>
 <firstName>John</firstName>
 <lastName>Smith</lastName>
 <userEmail>johnsmith@email.com</userEmail>

我正在尝试解析它并获取值。我按照此网址http://www.edumobile.org/iphone/iphone-programming-tutorials/parsing-an-xml-file/中显示的示例进行了操作, 但我是调用 parse 方法时出现错误。我使用的是 viewcontroller 类,而不是示例 url 中所示的 appdelegate 类。我不想在 Appdelegate 类中添加任何代码。

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[AppDelegate setUserDetails:]: unrecognized selector sent to instance 0x9272a40'

我只是 iphone 编程的初学者。所以我需要帮助来成功解析它,我只想以某种方式获取这些值,以便我可以使用它们在某些标签的屏幕上显示。以下是 6 个文件的代码(Viewcontroller.h & m、User.h & m、Xmlparser.h & m)

//ViewController.h
    #import <UIKit/UIKit.h>
    #import "GlobalVariable.h"
    #import "QuotesViewController.h"
    @interface ViewController : UIViewController <NSXMLParserDelegate,UIApplicationDelegate,NSStreamDelegate,UIAlertViewDelegate,WriteProtocol>
    {
        QuotesViewController *quoteobj;
        NSMutableArray *userDetails;
    }
    @property (retain, nonatomic) IBOutlet UITextField *txtUsername;
    @property (retain, nonatomic) IBOutlet UITextField *txtPassword;
    @property (retain, nonatomic) NSInputStream *inputStream;
    @property (retain, nonatomic) NSOutputStream *outputStream;
    @property (nonatomic, retain) NSMutableArray *messages;
    @property (retain, nonatomic) IBOutlet UILabel *label1;
    - (IBAction)btnLogin:(id)sender;
    - (IBAction)btnExit:(id)sender;
    - (void)initNetworkCommunication;
    - (void)readIn:(NSString *)s;
    - (void)writeOut:(NSString *)s;
    @property (nonatomic, retain) NSMutableArray *userDetails;
    @end




    //ViewController.m
    #import "ViewController.h"
    #import "NewTabViewController.h"
    #import "QuotesViewController.h"
    #import "XMLParser.h"
    @implementation ViewController
    @synthesize txtPassword,txtUsername,inputStream, outputStream,messages,label1,userDetails;
    - (void)viewDidLoad
    {
    [super viewDidLoad];
    quoteobj =[[QuotesViewController alloc]init];
    quoteobj.myTableView = [[UITableView alloc]init];
        quoteobj.myTableView.delegate=quoteobj;
         quoteobj.myTableView.dataSource=quoteobj;

    // Do any additional setup after loading the view, typically from a nib.
    }
    - (IBAction)btnLogin:(id)sender {
    NSLog(@"Clicked button1");
    [self initNetworkCommunication];
    NSString *response  = [NSString stringWithFormat:@"POST\r\n\r\nTMS|Login|%@|%@",txtUsername.text,txtPassword.text];
    NSLog(@"1");
    [self writeOut:response];
    }

    - (IBAction)btnExit:(id)sender {
    exit(0);
    }
    - (void) initNetworkCommunication {
    NSLog(@"initNetworkCommunication called");
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"xxx.xxx.x.xx", xxxx, &readStream, &writeStream);
    inputStream = (NSInputStream *)readStream;
    outputStream = (NSOutputStream *)writeStream;
    [inputStream retain];
    [outputStream retain];
    [inputStream setDelegate:self];
    [outputStream setDelegate:self];
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [inputStream open];
    [outputStream open];
    }

    - (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
    NSLog(@"stream event %i", streamEvent);
    switch (streamEvent) {
        case NSStreamEventOpenCompleted:
           NSLog(@"Stream opened");
            break;
        case NSStreamEventHasBytesAvailable:

            if (theStream == inputStream) {

                uint8_t buffer[1024];
                int len;

                while ([inputStream hasBytesAvailable]) {
                    len = [inputStream read:buffer maxLength:sizeof(buffer)];
                    if (len > 0) {

                        NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
                        [self readIn:output];
                        if([output hasPrefix:@"JSESSIONID"]){
                            int len = [output length];
                            int lenn = len-29;
                        sessionId =   [output substringWithRange:NSMakeRange(0, lenn)];
                        label1.text=sessionId;
                        NSLog(@"New String %@ LENGTH SESSUIn %i",sessionId,sessionId.length);
                        sessionId=label1.text;
                        NewTabViewController *so = [self.storyboard instantiateViewControllerWithIdentifier:@"newtab"];
                           for(UIViewController *ssa in so.viewControllers){
                                if([ssa isKindOfClass:[QuotesViewController class]]){
                                    QuotesViewController *qq = (QuotesViewController *) ssa;
                                    NSLog(@"PREESENTING THIS FZZZZZZZZZZZzzaaadfsdfssdfsa");
                                    [qq setDel:self];
                                }
                            }
                            [self presentViewController:so animated:YES completion:nil];

                        }

                    }
                }
            }
            break;


        case NSStreamEventErrorOccurred:

            NSLog(@"Can not connect to the host!");
            UIAlertView *alert =[[UIAlertView alloc]initWithTitle:@"Server says.." message:@"Due to some reason server is unavailable" delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok", nil];
            [alert show];
            [alert release];

            break;

        case NSStreamEventEndEncountered:
            NSLog(@"NSStreamEventEndEncountered:method is called");
            [theStream close];
            NSLog(@"theStream is closed");

            [theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            NSLog(@"theStream is removed from runloop");

            [theStream release];
            NSLog(@"theStream is released");
            NSLog(@"Server is unavailable");

            theStream = nil;
            if(theStream==nil){
                UIAlertView *alert =[[UIAlertView alloc]initWithTitle:@"Server says.." message:@"Due to some reason server is unavailable" delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok", nil];
                [alert show];
                [alert release];

            }
            NSLog(@"IT reaches 1 here");

            break;
        default:
            NSLog(@"Unknown event");
    }
    }//End of stream

    -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
        NSLog(@"IT reaches here");
        NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
        if([title isEqualToString:@"Ok"])
        {
            NSLog(@"Ok is clicked");
            exit(0);
        }
    }

    - (void) messageReceived:(NSString *)message {
    NSLog(@"Entered MessageRecieved");
    [messages addObject:message];
    }
    - (void)readIn:(NSString *)s {
    NSLog(@"%@", s);
        if ([s hasPrefix:@"{"]) {
            if([s rangeOfString:@"instrSymbol"].location ==NSNotFound){
                NSLog(@"Received a data which is not instrumentid");
            }
           else{
            NSLog(@"JSON DATA RECEIVED");
            [quoteobj parseJsonData:s];
               }
        }
        else if([s hasPrefix:@"<"]){
            NSLog(@"XML DATA RECEIVED");
            NSData *xmlData= [[NSData alloc]initWithData:[s dataUsingEncoding:NSUTF8StringEncoding]];
            NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:xmlData];
            XMLParser *parser = [[XMLParser alloc] initXMLParser];
            //Set delegate
            [xmlParser setDelegate:parser];

            //Start parsing the XML file.
            BOOL success = [xmlParser parse];

            if(success)
                NSLog(@"No Errors");
            else
                NSLog(@"Error Error Error!!!");
        }
    }

    - (void)writeOut:(NSString *)s {
    if (outputStream) {
        NSLog(@"WRITING OUT");
        uint8_t *buf = (uint8_t *)[s UTF8String];
        [outputStream write:buf maxLength:strlen((char *)buf)];
        NSLog(@"Writing out the following:");
        NSLog(@"%@", s);
    }
    else{
        NSLog(@"Noutoyt");
    }
    }
    @end

    //XMLParser.h
    #import <Foundation/Foundation.h>
    @class ViewController,User;
    @interface XMLParser : NSObject{

        NSMutableString *currentElementValue;
        ViewController *zappDelegate;
        User *aBook;
    }
    - (XMLParser *) initXMLParser;
    @end

    //XMLParser.m
    #import "XMLParser.h"
    #import "ViewController.h"
    #import "User.h"

    @implementation XMLParser

    - (XMLParser *) initXMLParser {

        [super init];

        zappDelegate = (ViewController *)[[UIApplication sharedApplication] delegate];

        return self;
    }

    - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
      namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
        attributes:(NSDictionary *)attributeDict {

        if([elementName isEqualToString:@"country"]) {
            //Initialize the array.
            zappDelegate.userDetails = [[NSMutableArray alloc] init];
        }
        else if([elementName isEqualToString:@"firstName"]) {

            //Initialize the book.
            aBook = [[User alloc] init];

            //Extract the attribute here.
            //aBook.bookID = [[attributeDict objectForKey:@"id"] integerValue];

            //NSLog(@"Reading id value :%i", aBook.bookID);
        }
        NSLog(@"Processing Element: %@", elementName);
    }
    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {

        if(!currentElementValue)
            currentElementValue = [[NSMutableString alloc] initWithString:string];
        else
            [currentElementValue appendString:string];
        NSLog(@"Processing Value: %@", currentElementValue);
    }
    - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
      namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

        if([elementName isEqualToString:@"Books"])
            return;
        if([elementName isEqualToString:@"Book"]) {
            [zappDelegate.userDetails addObject:aBook];
            [aBook release];
            aBook = nil;
        }
        else
            [aBook setValue:currentElementValue forKey:elementName];
        [currentElementValue release];
        currentElementValue = nil;
    }
    @end

    //User.h
    #import <Foundation/Foundation.h>

    @interface User : NSObject {

        //NSInteger bookID;
        NSString *firstName;    //Same name as the Entity Name.
        NSString *lastName; //Same name as the Entity Name.
        NSString *userEmail;    //Same name as the Entity Name.
        }
    @property (nonatomic, retain) NSString *firstName;
    @property (nonatomic, retain) NSString *lastName;
    @property (nonatomic, retain) NSString *userEmail;
    @end

    //User.m
    #import "User.h"
    @implementation User
    @synthesize firstName,lastName,userEmail;

    - (void) dealloc {
        [firstName release];
        [lastName release];
        [userEmail release];
        [super dealloc];
    }

    @end
4

2 回答 2

1

您创建了一个名为的类,但随后您尝试通过强制转换不相关的应用程序委托在该类ViewController中分配它的一个实例。XMLParser

zappDelegate = (ViewController *)[[UIApplication sharedApplication] delegate];

您需要将 的名称更改为zappDelegate更合适的名称并将其分配给您的ViewController.

我确实注意到您ViewController确实符合UIApplicationDelegate协议,但这并不会自动使其成为应用程序委托。真正的委托应该在main.m[m]文件中正确设置。

return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
于 2013-05-29T12:07:16.767 回答
0

检查这个链接我修改了源代码:

http://dcraziee.wordpress.com/2013/05/29/parsing-xml-in-objective-c/

它将从您的 xml 响应中返回字典。xml 中的所有键都将是键,值将在字典的值部分。

如果您包含分层 xml,则将进行相应管理。我希望这将有所帮助。

于 2013-05-29T12:50:32.580 回答