tags:

views:

983

answers:

2

Hi, I have been trying to create an NSDictionary of the parameters in my iPhone application and want to send it across(through a POST HTTP request, there are some other parameters also in the request) to a ruby on rails server to be consumed by a ruby method which takes a hash table as arguments.

  1. Do I need to serialize the NSDictionary in my iPhone client? How do I do that.
  2. I am using JSON but dont see any such JSON feature which can be used.
+2  A: 

How to use JSON in Cocoa/Objective-C

mcandre
+3  A: 

Yes, you need to encode parameters explicitly.

It's relatively straightforward. Here's a extension to NSMutableURLRequest that I use which encodes a dictionary of strings as POST parameters.

@interface NSMutableURLRequest (WebServiceClient) 

+ (NSString *) encodeFormPostParameters: (NSDictionary *) parameters;
- (void) setFormPostParameters: (NSDictionary *) parameters;

@end

@implementation NSMutableURLRequest (WebServiceClient)

+ (NSString *) encodeFormPostParameters: (NSDictionary *) parameters {
  NSMutableString *formPostParams = [[[NSMutableString alloc] init] autorelease];

  NSEnumerator *keys = [parameters keyEnumerator];

  NSString *name = [keys nextObject];
  while (nil != name) {
    NSString *encodedValue = [((NSString *) CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef) [parameters objectForKey: name], NULL, CFSTR("=/:"), kCFStringEncodingUTF8)) autorelease];

    [formPostParams appendString: name];
    [formPostParams appendString: @"="];
    [formPostParams appendString: encodedValue];

    name = [keys nextObject];

    if (nil != name) {
      [formPostParams appendString: @"&"];
    }
  }

  return formPostParams;
}

- (void) setFormPostParameters: (NSDictionary *) parameters {
  NSString *formPostParams = [NSMutableURLRequest encodeFormPostParameters: parameters];

  [self setHTTPBody: [formPostParams dataUsingEncoding: NSUTF8StringEncoding]];
  [self setValue: @"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField: @"Content-Type"];
}

@end
dmercredi
Hi dmercredi,Thanks for the details, but I want to send the NSDictionary so that my method in ruby(which takes a hash table) can still refer the complete set of parameters by the dictionary name.Use case:1) Create a NSDictionary(with name "myAttributes") with attributes and values, for a set of attributes to be used in ruby on the server side.2) Send the NSDictionary as a HTTP POST request body, the method in ruby should be able to refer the received dictionary as "params[:myAttributes]" which gets me all the attributes on the server side, which can be interpreted their after.TIA.
OK, I understand. You'll need to use a third party JSON library, there isn't one in the iPhone API. I use TouchJSON in my app because it parses very quickly directly from NSData. See http://code.google.com/p/touchcode/wiki/TouchJSON As long as the dictionary contains only NSString, NSNull, or NSNumber, NSDictionary, or NSArray you can use CJSONSerialer in TouchJSON to create a JSON string, and then set the HTTP body (using UTF8 encoding) and the content-type appropriately similarly to setFormPostParameters in the code.
dmercredi
Thanks for the pointer, tried using TouchJSON but after serializing the NSDictionary and setting it in the HTTP body for my POST request the attribute values I see in ruby are little different.Ruby expects something like: events=>{"name"=>"ABC", "budget"=>"123"}but I see: events=>{\"name\"=\"ABC\", \"budget\" = \"123\"}Is there a similar iPhone/Ruby on rails, example to send hash table parameters to ruby from Cocoa using NSDictionary which can be referred here? Thanks.