1

My application uses NSTask to start a Python script, then the script returns an array via NSPipe. I read the data, stick it in a string, and display it:

NSMutableData *data = [[NSMutableData alloc] init];
NSData *readData;

while ((readData = [readHandle availableData])&& [readData length]) {
    [data appendData: readData];
}


NSString *string = [[NSString alloc] 
                    initWithData: data 
                    encoding: NSUTF8StringEncoding];

That's all fine, but I realized I really need to keep it as an array - not a string. I can't find a method that initiates array from data (data returned from NSPipe). How can I do that? The closest thing I found is possibly using:

[NSPropertyListSerialization dataWithPropertyList:format:options:error:]

... but I don't need a "property list" per se. Do I have to convert the data to plist first?

EDITED: I just realized it's more complicated than I thought. Python returns an array of dictionaries, in the dictionary there are strings. These strings can have commas and other chars, so I don't think I can use a "," separator to break it up.

in Python:

msg_set = []
msg_set = [
   dict(mts="t,s1", mfrom="f@ro,m1", msbj="msb,j1", mbody="bod,y1", mid="i,d1"),
   dict(mts="ts2", mfrom="from2", msbj="msb,j2", mbody="body2", mid="id2")
]
print msg_set # <- this is what python returns
janeh
  • 3,734
  • 7
  • 26
  • 43

2 Answers2

1

If the data coming back represents an array with a separator, e.g. a comma @"," you can take your string, and split it into an array, like this:

NSString *string = [[NSString alloc] 
                initWithData: data 
                encoding: NSUTF8StringEncoding];
NSArray *array = [string componentsSeparatedByString:@","];

You need to use the same separator character as the sending side. If multiple characters can be used as separators, you may want to use componentsSeparatedByCharactersInSet: instead:

NSArray *array = [string componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Thanks, I just edited my question. The returned array might contain strings with "," in them, so I don't think I can use a componentsSeparatedByString:@",". (it breaks "bod,y" into "y") – janeh Aug 21 '12 at 15:18
  • @janeh You need a parser for something as complex as this. Do you control the Python side? Can you change its output to be more parse-friendly, e.g. [encode its results as JSON](http://docs.python.org/library/json.html)? – Sergey Kalinichenko Aug 21 '12 at 15:21
  • The strings are coming to python from IMAP, but I can control how they are "grouped" before sending them to obj-c. I thought an array of dics would be the best, but guess not. I have never used JSON before, but let me see what I can do... – janeh Aug 21 '12 at 15:27
1

You can convert the data to JSON first (I saw the comments on dasblinkenlight's answer but I had already typed my answer) and then pass them to Cocoa. Something like this:

Python Side

import json
#...
json.dumps(msg_set) # <- return this one instead

Objective-C Side

NSString *myPythonJson = @""; // <- Whatever you got from python
NSError *error = nil;
id myObjectsFromJson = [NSJSONSerialization JSONObjectWithData:[myPythonJson dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:&error];
Alladinian
  • 34,483
  • 6
  • 89
  • 91