1. 程式人生 > >NSData 與 struct 以及XML的轉換。

NSData 與 struct 以及XML的轉換。

在做OC與C++ 混編的時候,我們可能會用到struct 與NSData的相互轉換。在這裡做一個記錄

1、struct轉換為NSData

例如如下的struct:

struct tagPackageHead		
{
	tagPackageHead()
	{
		memset(this,0,sizeof(*this));
		bStartcode = 0xFE;
	}
	Byte	bStartcode;				
	uint	iCmd;					
	uint	iXMLLen;				
	uint	iSeqNumber;            
	Byte	bExpand[10];			
};
struct tagPackageHead tagPack;
    tagPack.bStartcode = 0xFE;
    tagPack.iCmd = CMD_CLIENT_LOGIN;
    tagPack.iXMLLen = data.length;
    tagPack.iSeqNumber = 1;
以上是在OC中定義一個結構體,然後需要轉換為NSData。轉換的過程如下:

NSData *headerData = [NSDatadataWithBytes:&tagPacklength:sizeof(tagPack)];

2、NSData轉換為struct

struct tagPackageHead tagPack;
[data getBytes:&tagPack length:sizeof(tagPack)];
NSLog(@"tagPack.iXMLLen:%d",tagPack.iXMLLen);
NSLog(@"tagPack.iCmd:%d",tagPack.iCmd);
NSLog(@"tagPack.iSeqNumber:%d",tagPack.iSeqNumber);
3、建立XML檔案,本來打算用kissXML的,結果找不到如何講kissXML轉換為NSData,而且檔案又多,就換成了GDataXMLNode了。直接上程式碼:
//建立XML
GDataXMLElement *rootElement = [GDataXMLNode elementWithName:@"SignInReq"];
GDataXMLElement *element = [GDataXMLNode elementWithName:@"ClientType" stringValue:@"PC"];
[rootElement addChild:element];
element = [GDataXMLNode elementWithName:@"UserName" stringValue:@"abcdef"];
[rootElement addChild:element];
element = [GDataXMLNode elementWithName:@"Password" stringValue:@"123456"];
[rootElement addChild:element];
element = [GDataXMLNode elementWithName:@"UserAgent" stringValue:@"1.01"];
[rootElement addChild:element];
GDataXMLDocument *document = [[GDataXMLDocument alloc] initWithRootElement:rootElement];
NSData *data =  [document XMLData];

4、解析XML檔案

因為伺服器返回的資料中有包頭和XML檔案兩部分,所以要先獲取包頭,然後再獲取XML檔案

struct tagPackageHead tagPack;
[data getBytes:&tagPack length:sizeof(tagPack)];
        
NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
NSString *string = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(sizeof(tagPack), tagPack.iXMLLen)] encoding:enc];
NSData *data2 = [string dataUsingEncoding:NSUTF8StringEncoding];
        
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path=[paths objectAtIndex:0];
NSString *areaDevice_path=[path stringByAppendingPathComponent:@"areaDevice.xml"];
//==寫入檔案
[data2 writeToFile:areaDevice_path atomically:YES];
//開始解析
NSDictionary *dict = [NSDictionary dictionaryWithXMLData:data2];
這裡第二行的data,就是從伺服器返回的NSData型別的data,先獲取包頭,因為伺服器返回的格式是GBK格式,所以轉碼一次,然後儲存到本地後,解析轉換為字典,解析用的第三方是XMLDictionary。