iPhone XMLRequest

You can use libxml2. I suspect it is the fastest approach. Add its framework to your project (see the “setting up your project” section of this document).

In the header of your XML writer, add the following imports:

#import <libxml/encoding.h>
#import <libxml/xmlwriter.h>

In the implementation, write a method to generate your XML. Presumably you’ll be sending your request’s bytes via an NSData* object, so you might write something like this:

- (NSData *) xmlDataFromRequest 
{
    xmlTextWriterPtr _writer;
    xmlBufferPtr _buf;
    xmlChar *_tmp;
    const char *_UTF8Encoding = "UTF-8";

    _buf = xmlBufferCreate();
    _writer = xmlNewTextWriterMemory(_buf, 0);

    // <?xml version="1.0" encoding="UTF-8"?>
    xmlTextWriterStartDocument(_writer, "1.0", _UTF8Encoding, NULL);

    // <request type="handle" action="update">
    xmlTextWriterStartElement(_writer, BAD_CAST "request");
    xmlTextWriterWriteAttribute(_writer, BAD_CAST "type", BAD_CAST "handle");
    xmlTextWriterWriteAttribute(_writer, BAD_CAST "action", BAD_CAST "update");
    xmlTextWriterEndElement(_writer);

    // <userdata>...</userdata>
    xmlTextWriterStartElement(_writer, BAD_CAST "userdata");
    xmlTextWriterStartElement(_writer, BAD_CAST "username");
    _tmp = [self xmlCharPtrForInput:[[NSString stringWithFormat:@"YourUsername"] cStringUsingEncoding:NSUTF8StringEncoding] withEncoding:_UTF8Encoding];
    xmlTextWriterWriteString(_writer, _tmp);
    xmlTextWriterEndElement(_writer); // closing <username>
    xmlFree(_tmp);
    xmlTextWriterStartElement(_writer, BAD_CAST "password");
    _tmp = [self xmlCharPtrForInput:[[NSString stringWithFormat:@"YourPassword"] cStringUsingEncoding:NSUTF8StringEncoding] withEncoding:_UTF8Encoding];
    xmlTextWriterWriteString(_writer, _tmp);
    xmlTextWriterEndElement(_writer); // closing <password>
    xmlFree(_tmp); 
    xmlTextWriterEndElement(_writer); // closing <userdata>

    // etc.

    xmlTextWriterEndDocument(_writer);
    xmlFreeTextWriter(_writer);

    // turn libxml2 buffer into NSData* object

    NSData *_xmlData = [NSData dataWithBytes:(_buf->content) length:(_buf->use)];
    xmlBufferFree(_buf);

    return _xmlData;
}

I have a helper method here that I use to convert const char * into xmlChar *:

- (xmlChar *) xmlCharPtrForInput:(const char *)_input withEncoding:(const char *)_encoding 
{
    xmlChar *_output;
    int _ret;
    int _size;
    int _outputSize;
    int _temp;
    xmlCharEncodingHandlerPtr _handler;

    if (_input == 0)
        return 0;

    _handler = xmlFindCharEncodingHandler(_encoding);

    if (!_handler) {
        NSLog(@"convertInput: no encoding handler found for '%s'\n", (_encoding ? _encoding : ""));
        return 0;
    }

    _size = (int) strlen(_input) + 1;
    _outputSize = _size * 2 - 1;
    _output = (unsigned char *) xmlMalloc((size_t) _outputSize);

    if (_output != 0) {
        _temp = _size - 1;
        _ret = _handler->input(_output, &_outputSize, (const xmlChar *) _input, &_temp);
        if ((_ret < 0) || (_temp - _size + 1)) {
            if (_ret < 0) {
                NSLog(@"convertInput: conversion wasn't successful.\n");
            } else {
                NSLog(@"convertInput: conversion wasn't successful. Converted: %i octets.\n", _temp);
            }   
            xmlFree(_output);
            _output = 0;
        } else {
            _output = (unsigned char *) xmlRealloc(_output, _outputSize + 1);
            _output[_outputSize] = 0;  /*null terminating out */
        }
    } else {
        NSLog(@"convertInput: no memory\n");
    }

    return _output;
}

Leave a Comment