Skip to content

Commit 137eec0

Browse files
committed
objc: rewrote native with improved syntax
- objc native now creates NSDictionary literals for headers and parameters if possible - this makes helpers.js a valid file to put in a family folder (ignored when loading all available targets) - improved the application-json.json fixture for error proofed JSON to NSDictionary serialization. - remove multipart fixtures for every language I think that every language should be allowed to parse the JSON if postData.text is a valid JSON object, allowing the developer to have more flexibility over the snippet rather than a huge JSON.stringify string
1 parent 458c5ba commit 137eec0

15 files changed

Lines changed: 122 additions & 29 deletions

File tree

README.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Relies on the popular [HAR](http://www.softwareishard.com/blog/har-12-spec/#requ
2222

2323
## Targets
2424

25-
currently the following output [targets](/src/targets) are supported:
25+
Currently the following output [targets](/src/targets) are supported:
2626

2727
- [cURL](http://curl.haxx.se/)
2828
- [Go](http://golang.org/pkg/net/http/#NewRequest)
@@ -39,6 +39,8 @@ currently the following output [targets](/src/targets) are supported:
3939
- Python
4040
- [Python 3](https://docs.python.org/3/library/http.client.html)
4141
- [Wget](https://www.gnu.org/software/wget/)
42+
- Objective-C
43+
- [NSURLSession](https://developer.apple.com/library/mac/documentation/Foundation/Reference/NSURLSession_class/index.html)
4244

4345
## Installation
4446

@@ -100,6 +102,7 @@ process single file (assumes [HAR Request Object](http://www.softwareishard.com/
100102
}
101103
}
102104
```
105+
103106
```shell
104107
httpsnippet my-api-endpoint.json --target php --output ./snippets
105108
```
@@ -147,7 +150,7 @@ console.log(snippet.convert('curl', {
147150
indent: '\t';
148151
}));
149152

150-
// generate nodeJS output
153+
// generate Node.js output
151154
console.log(snippet.convert('node'));
152155

153156
// generate PHP output
@@ -221,6 +224,15 @@ module.exports.info = {
221224
| `indent` | ` ` | line break & indent output value, set to `false` to disable line breaks |
222225
| `verbose` | `false` | by default, `--quiet` is always used, unless `verbose` is set to `true` |
223226

227+
### Objective-C
228+
229+
##### Native
230+
231+
| Option | Default | Description |
232+
| --------- | ------- | ------------------------------------------------------------------------ |
233+
| `timeout` | `10.0` | NSURLRequest timeout |
234+
| `indent` | `true` | line break & indent NSDictionary literals |
235+
224236
## Bugs and feature requests
225237

226238
Have a bug or a feature request? Please first read the [issue guidelines](CONTRIBUTING.md#using-the-issue-tracker) and search for existing and closed issues. If your problem or idea is not addressed yet, [please open a new issue](/issues).

src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ module.exports.availableTargets = function () {
194194
var clients = Object.keys(targets[key])
195195

196196
.filter(function (prop) {
197-
return !~['info', 'index'].indexOf(prop)
197+
return !~['info', 'index'].indexOf(prop);
198198
})
199199

200200
.map(function (client) {

src/targets/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
'use strict'
22

3-
module.exports = require('require-directory')(module)
3+
module.exports = require('require-directory')(module, { exclude: /helpers\.js$/ });

src/targets/objc/helpers.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
'use strict';
2+
3+
var util = require('util');
4+
5+
module.exports = {
6+
/**
7+
* Create an string of given length filled with blank spaces
8+
*
9+
* @param {number} length Length of the array to return
10+
* @return {string}
11+
*/
12+
blankString: function (length) {
13+
return Array.apply(null, new Array(length)).map(String.prototype.valueOf, ' ').join('');
14+
},
15+
16+
/**
17+
* Create a string corresponding to a valid NSDictionary declaration and initialization for Objective-C.
18+
*
19+
* @param {string} name Desired name of the NSDictionary instance
20+
* @param {Object} parameters Key-value object of parameters to translate to an Objective-C NSDictionary litearal
21+
* @param {boolean} indent If true, will declare the NSDictionary litteral by indenting each new key/value pair.
22+
* @return {string} A valid Objective-C declaration and initialization of an NSDictionary.
23+
*
24+
* @example
25+
* nsDictionaryBuilder('params', {a: 'b', c: 'd'}, true)
26+
* // returns:
27+
* NSDictionary *params = @{ @"a": @"b",
28+
* @"c": @"d" };
29+
*
30+
* nsDictionaryBuilder('params', {a: 'b', c: 'd'})
31+
* // returns:
32+
* NSDictionary *params = @{ @"a": @"b", @"c": @"d" };
33+
*/
34+
nsDictionaryBuilder: function (name, parameters, indent) {
35+
var dicOpening = 'NSDictionary *' + name + ' = ';
36+
var dicLiteral = this.literalRepresentation(parameters, indent ? dicOpening.length : null);
37+
return dicOpening + dicLiteral + ';';
38+
},
39+
40+
/**
41+
* Create a valid Objective-C string of a literal value according to its type.
42+
*
43+
* @param {*} value Any JavaScript literal
44+
* @return {string}
45+
*/
46+
literalRepresentation: function (value, indentation) {
47+
switch (Object.prototype.toString.call(value)) {
48+
case '[object Number]':
49+
return '@' + value;
50+
case '[object Array]':
51+
var values_representation = value.map(function (v) {
52+
return this.literalRepresentation(v);
53+
}.bind(this));
54+
return '@[ ' + values_representation.join(', ') + ' ]';
55+
case '[object Object]':
56+
var keyValuePairs = [];
57+
for (var k in value) {
58+
keyValuePairs.push(util.format('@"%s": %s', k, this.literalRepresentation(value[k])));
59+
}
60+
61+
var join = indentation === undefined ? ', ' : ',\n ' + this.blankString(indentation);
62+
63+
return '@{ ' + keyValuePairs.join(join) + ' }';
64+
default:
65+
return '@"' + value.replace(/"/g, '\\"') + '"';
66+
}
67+
}
68+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
curl --request POST \
22
--url "http://mockbin.com/har" \
3-
--header "content-type: application/json" \
3+
--header "Content-Type: application/json" \
44
--data "{\"number\": 1, \"string\": \"f\\\"oo\", \"arr\": [1, 2, 3], \"nested\": {\"a\": \"b\"}, \"arr_mix\": [1, \"a\", {\"arr_mix_nested\": {}}] }"

test/fixtures/output/objc/native/application-form-encoded.m

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
#import <Foundation/Foundation.h>
22

3-
NSURLSession *session = [NSURLSession sharedSession];
3+
NSDictionary *headers = @{ @"Content-Type": @"application/x-www-form-urlencoded" };
4+
NSMutableData *postData = [[NSMutableData alloc] initWithData:[@"foo=bar" dataUsingEncoding:NSUTF8StringEncoding]];
5+
[postData appendData:[@"&hello=world" dataUsingEncoding:NSUTF8StringEncoding]];
46

57
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://mockbin.com/har"]
68
cachePolicy:NSURLRequestUseProtocolCachePolicy
79
timeoutInterval:10.0];
810
[request setHTTPMethod:@"POST"];
9-
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
10-
11-
NSMutableData *postData = [[NSMutableData alloc] initWithData:[@"foo=bar" dataUsingEncoding:NSUTF8StringEncoding]];
12-
[postData appendData:[@"&hello=world" dataUsingEncoding:NSUTF8StringEncoding]];
11+
[request setAllHTTPHeaderFields:headers];
1312
[request setHTTPBody:postData];
1413

14+
NSURLSession *session = [NSURLSession sharedSession];
1515
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
1616
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
1717

test/fixtures/output/objc/native/application-json.m

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
#import <Foundation/Foundation.h>
22

3-
NSURLSession *session = [NSURLSession sharedSession];
3+
NSDictionary *headers = @{ @"Content-Type": @"application/json" };
4+
NSDictionary *parameters = @{ @"number": @1,
5+
@"string": @"f\"oo",
6+
@"arr": @[ @1, @2, @3 ],
7+
@"nested": @{ @"a": @"b" },
8+
@"arr_mix": @[ @1, @"a", @{ @"arr_mix_nested": @{ } } ] };
9+
10+
NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];
411

512
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://mockbin.com/har"]
613
cachePolicy:NSURLRequestUseProtocolCachePolicy
714
timeoutInterval:10.0];
815
[request setHTTPMethod:@"POST"];
9-
[request setValue:@"application/json" forHTTPHeaderField:@"content-type"];
10-
11-
NSData *postData = [[NSData alloc] initWithData:[@"{\"number\": 1, \"string\": \"f\\\"oo\", \"arr\": [1, 2, 3], \"nested\": {\"a\": \"b\"}, \"arr_mix\": [1, \"a\", {\"arr_mix_nested\": {}}] }" dataUsingEncoding:NSUTF8StringEncoding]];
16+
[request setAllHTTPHeaderFields:headers];
1217
[request setHTTPBody:postData];
1318

19+
NSURLSession *session = [NSURLSession sharedSession];
1420
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
1521
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
1622

test/fixtures/output/objc/native/cookies.m

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
#import <Foundation/Foundation.h>
22

3-
NSURLSession *session = [NSURLSession sharedSession];
3+
NSDictionary *headers = @{ @"Cookie": @"foo=bar; bar=baz" };
44

55
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://mockbin.com/har"]
66
cachePolicy:NSURLRequestUseProtocolCachePolicy
77
timeoutInterval:10.0];
88
[request setHTTPMethod:@"POST"];
9-
[request setValue:@"foo=bar; bar=baz" forHTTPHeaderField:@"cookie"];
9+
[request setAllHTTPHeaderFields:headers];
1010

11+
NSURLSession *session = [NSURLSession sharedSession];
1112
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
1213
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
1314

test/fixtures/output/objc/native/full.m

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
#import <Foundation/Foundation.h>
22

3-
NSURLSession *session = [NSURLSession sharedSession];
3+
NSDictionary *headers = @{ @"Accept": @"application/json",
4+
@"Content-Type": @"application/x-www-form-urlencoded",
5+
@"Cookie": @"foo=bar; bar=baz" };
6+
NSMutableData *postData = [[NSMutableData alloc] initWithData:[@"foo=bar" dataUsingEncoding:NSUTF8StringEncoding]];
47

5-
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://mockbin.com/har?foo=bar&foo=baz&baz=abc&key=value"]
8+
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://mockbin.com/har?baz=abc&foo=bar&foo=baz"]
69
cachePolicy:NSURLRequestUseProtocolCachePolicy
710
timeoutInterval:10.0];
811
[request setHTTPMethod:@"POST"];
9-
[request setValue:@"application/json" forHTTPHeaderField:@"accept"];
10-
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
11-
[request setValue:@"foo=bar; bar=baz" forHTTPHeaderField:@"cookie"];
12-
13-
NSMutableData *postData = [[NSMutableData alloc] initWithData:[@"foo=bar" dataUsingEncoding:NSUTF8StringEncoding]];
12+
[request setAllHTTPHeaderFields:headers];
1413
[request setHTTPBody:postData];
1514

15+
NSURLSession *session = [NSURLSession sharedSession];
1616
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
1717
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
1818

test/fixtures/output/objc/native/headers.m

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
#import <Foundation/Foundation.h>
22

3-
NSURLSession *session = [NSURLSession sharedSession];
3+
NSDictionary *headers = @{ @"Accept": @"application/json",
4+
@"X-Foo": @"Bar" };
45

56
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://mockbin.com/har"]
67
cachePolicy:NSURLRequestUseProtocolCachePolicy
78
timeoutInterval:10.0];
89
[request setHTTPMethod:@"GET"];
9-
[request setValue:@"application/json" forHTTPHeaderField:@"accept"];
10-
[request setValue:@"Bar" forHTTPHeaderField:@"x-foo"];
10+
[request setAllHTTPHeaderFields:headers];
1111

12+
NSURLSession *session = [NSURLSession sharedSession];
1213
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
1314
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
1415

0 commit comments

Comments
 (0)