├── .gitignore
├── Demo
├── MJGHTTPRequestDemo-Info.plist
├── MJGHTTPRequestDemo-Prefix.pch
├── MJGHTTPRequestDemo.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
├── Source
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── BeerMapApiRequest.h
│ ├── BeerMapApiRequest.m
│ ├── MJGHTTPRequestDemoViewController.h
│ ├── MJGHTTPRequestDemoViewController.m
│ └── MJGHTTPRequestDemoViewController.xib
└── main.m
├── LICENSE
├── README.markdown
└── Source
├── MJGHTTPDownload.h
├── MJGHTTPDownload.m
├── MJGHTTPRequest.h
├── MJGHTTPRequest.m
├── NSDictionary-HTTP.h
├── NSDictionary-HTTP.m
├── NSString-HTTP.h
└── NSString-HTTP.m
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | *.pbxuser
3 | *.mode1v3
4 | *.mode2v3
5 | *.pbxuser
6 | *.perspective
7 | *.perspectivev3
8 | *.xcuserdatad
9 |
10 | .DS_Store
11 |
--------------------------------------------------------------------------------
/Demo/MJGHTTPRequestDemo-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIconFiles
12 |
13 | CFBundleIdentifier
14 | com.yourcompany.${PRODUCT_NAME:rfc1034identifier}
15 | CFBundleInfoDictionaryVersion
16 | 6.0
17 | CFBundleName
18 | ${PRODUCT_NAME}
19 | CFBundlePackageType
20 | APPL
21 | CFBundleShortVersionString
22 | 1.0
23 | CFBundleSignature
24 | ????
25 | CFBundleVersion
26 | 1.0
27 | LSRequiresIPhoneOS
28 |
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Demo/MJGHTTPRequestDemo-Prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #import
4 | #endif
5 |
--------------------------------------------------------------------------------
/Demo/MJGHTTPRequestDemo.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | C9020A2314A222A500EF6DF8 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9020A2214A222A500EF6DF8 /* UIKit.framework */; };
11 | C9020A2514A222A500EF6DF8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9020A2414A222A500EF6DF8 /* Foundation.framework */; };
12 | C9020A2714A222A500EF6DF8 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9020A2614A222A500EF6DF8 /* CoreGraphics.framework */; };
13 | C9020A4314A225E700EF6DF8 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C9020A3D14A225E700EF6DF8 /* main.m */; };
14 | C9020A4514A225E700EF6DF8 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C9020A4214A225E700EF6DF8 /* AppDelegate.m */; };
15 | C9020A4E14A2263400EF6DF8 /* MJGHTTPRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = C9020A4B14A2263400EF6DF8 /* MJGHTTPRequest.m */; };
16 | C9020A4F14A2263400EF6DF8 /* NSDictionary-HTTP.m in Sources */ = {isa = PBXBuildFile; fileRef = C9020A4D14A2263400EF6DF8 /* NSDictionary-HTTP.m */; };
17 | C9020A5A14A22FC000EF6DF8 /* BeerMapApiRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = C9020A5914A22FC000EF6DF8 /* BeerMapApiRequest.m */; };
18 | C9020A5E14A233B900EF6DF8 /* MJGHTTPRequestDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C9020A5C14A233B900EF6DF8 /* MJGHTTPRequestDemoViewController.m */; };
19 | C9020A5F14A233B900EF6DF8 /* MJGHTTPRequestDemoViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = C9020A5D14A233B900EF6DF8 /* MJGHTTPRequestDemoViewController.xib */; };
20 | C9EB549F14A5E22F003B4206 /* NSString-HTTP.m in Sources */ = {isa = PBXBuildFile; fileRef = C9EB549E14A5E22F003B4206 /* NSString-HTTP.m */; };
21 | C9EC378C14B9CDDF00D82F67 /* MJGHTTPDownload.m in Sources */ = {isa = PBXBuildFile; fileRef = C9EC378B14B9CDDF00D82F67 /* MJGHTTPDownload.m */; };
22 | /* End PBXBuildFile section */
23 |
24 | /* Begin PBXFileReference section */
25 | C9020A1E14A222A500EF6DF8 /* MJGHTTPRequestDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MJGHTTPRequestDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
26 | C9020A2214A222A500EF6DF8 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
27 | C9020A2414A222A500EF6DF8 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
28 | C9020A2614A222A500EF6DF8 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
29 | C9020A3D14A225E700EF6DF8 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = SOURCE_ROOT; };
30 | C9020A3E14A225E700EF6DF8 /* MJGHTTPRequestDemo-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "MJGHTTPRequestDemo-Info.plist"; sourceTree = SOURCE_ROOT; };
31 | C9020A3F14A225E700EF6DF8 /* MJGHTTPRequestDemo-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MJGHTTPRequestDemo-Prefix.pch"; sourceTree = SOURCE_ROOT; };
32 | C9020A4114A225E700EF6DF8 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
33 | C9020A4214A225E700EF6DF8 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
34 | C9020A4A14A2263400EF6DF8 /* MJGHTTPRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJGHTTPRequest.h; sourceTree = ""; };
35 | C9020A4B14A2263400EF6DF8 /* MJGHTTPRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJGHTTPRequest.m; sourceTree = ""; };
36 | C9020A4C14A2263400EF6DF8 /* NSDictionary-HTTP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary-HTTP.h"; sourceTree = ""; };
37 | C9020A4D14A2263400EF6DF8 /* NSDictionary-HTTP.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary-HTTP.m"; sourceTree = ""; };
38 | C9020A5814A22FC000EF6DF8 /* BeerMapApiRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BeerMapApiRequest.h; sourceTree = ""; };
39 | C9020A5914A22FC000EF6DF8 /* BeerMapApiRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BeerMapApiRequest.m; sourceTree = ""; };
40 | C9020A5B14A233B900EF6DF8 /* MJGHTTPRequestDemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJGHTTPRequestDemoViewController.h; sourceTree = ""; };
41 | C9020A5C14A233B900EF6DF8 /* MJGHTTPRequestDemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJGHTTPRequestDemoViewController.m; sourceTree = ""; };
42 | C9020A5D14A233B900EF6DF8 /* MJGHTTPRequestDemoViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MJGHTTPRequestDemoViewController.xib; sourceTree = ""; };
43 | C9EB549D14A5E22F003B4206 /* NSString-HTTP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString-HTTP.h"; sourceTree = ""; };
44 | C9EB549E14A5E22F003B4206 /* NSString-HTTP.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString-HTTP.m"; sourceTree = ""; };
45 | C9EC378A14B9CDDF00D82F67 /* MJGHTTPDownload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJGHTTPDownload.h; sourceTree = ""; };
46 | C9EC378B14B9CDDF00D82F67 /* MJGHTTPDownload.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJGHTTPDownload.m; sourceTree = ""; };
47 | /* End PBXFileReference section */
48 |
49 | /* Begin PBXFrameworksBuildPhase section */
50 | C9020A1B14A222A500EF6DF8 /* Frameworks */ = {
51 | isa = PBXFrameworksBuildPhase;
52 | buildActionMask = 2147483647;
53 | files = (
54 | C9020A2314A222A500EF6DF8 /* UIKit.framework in Frameworks */,
55 | C9020A2514A222A500EF6DF8 /* Foundation.framework in Frameworks */,
56 | C9020A2714A222A500EF6DF8 /* CoreGraphics.framework in Frameworks */,
57 | );
58 | runOnlyForDeploymentPostprocessing = 0;
59 | };
60 | /* End PBXFrameworksBuildPhase section */
61 |
62 | /* Begin PBXGroup section */
63 | C9020A1314A222A500EF6DF8 = {
64 | isa = PBXGroup;
65 | children = (
66 | C9020A4814A2262900EF6DF8 /* MJGHTTPRequest */,
67 | C9020A2814A222A500EF6DF8 /* MJGHTTPRequestDemo */,
68 | C9020A2114A222A500EF6DF8 /* Frameworks */,
69 | C9020A1F14A222A500EF6DF8 /* Products */,
70 | );
71 | sourceTree = "";
72 | };
73 | C9020A1F14A222A500EF6DF8 /* Products */ = {
74 | isa = PBXGroup;
75 | children = (
76 | C9020A1E14A222A500EF6DF8 /* MJGHTTPRequestDemo.app */,
77 | );
78 | name = Products;
79 | sourceTree = "";
80 | };
81 | C9020A2114A222A500EF6DF8 /* Frameworks */ = {
82 | isa = PBXGroup;
83 | children = (
84 | C9020A2214A222A500EF6DF8 /* UIKit.framework */,
85 | C9020A2414A222A500EF6DF8 /* Foundation.framework */,
86 | C9020A2614A222A500EF6DF8 /* CoreGraphics.framework */,
87 | );
88 | name = Frameworks;
89 | sourceTree = "";
90 | };
91 | C9020A2814A222A500EF6DF8 /* MJGHTTPRequestDemo */ = {
92 | isa = PBXGroup;
93 | children = (
94 | C9020A4014A225E700EF6DF8 /* Source */,
95 | C9020A4714A2260100EF6DF8 /* Supporting Files */,
96 | );
97 | path = MJGHTTPRequestDemo;
98 | sourceTree = "";
99 | };
100 | C9020A4014A225E700EF6DF8 /* Source */ = {
101 | isa = PBXGroup;
102 | children = (
103 | C9020A4114A225E700EF6DF8 /* AppDelegate.h */,
104 | C9020A4214A225E700EF6DF8 /* AppDelegate.m */,
105 | C9020A5814A22FC000EF6DF8 /* BeerMapApiRequest.h */,
106 | C9020A5914A22FC000EF6DF8 /* BeerMapApiRequest.m */,
107 | C9020A5B14A233B900EF6DF8 /* MJGHTTPRequestDemoViewController.h */,
108 | C9020A5C14A233B900EF6DF8 /* MJGHTTPRequestDemoViewController.m */,
109 | C9020A5D14A233B900EF6DF8 /* MJGHTTPRequestDemoViewController.xib */,
110 | );
111 | path = Source;
112 | sourceTree = SOURCE_ROOT;
113 | };
114 | C9020A4714A2260100EF6DF8 /* Supporting Files */ = {
115 | isa = PBXGroup;
116 | children = (
117 | C9020A3D14A225E700EF6DF8 /* main.m */,
118 | C9020A3E14A225E700EF6DF8 /* MJGHTTPRequestDemo-Info.plist */,
119 | C9020A3F14A225E700EF6DF8 /* MJGHTTPRequestDemo-Prefix.pch */,
120 | );
121 | name = "Supporting Files";
122 | sourceTree = "";
123 | };
124 | C9020A4814A2262900EF6DF8 /* MJGHTTPRequest */ = {
125 | isa = PBXGroup;
126 | children = (
127 | C9020A4914A2263400EF6DF8 /* Source */,
128 | );
129 | name = MJGHTTPRequest;
130 | sourceTree = "";
131 | };
132 | C9020A4914A2263400EF6DF8 /* Source */ = {
133 | isa = PBXGroup;
134 | children = (
135 | C9020A4A14A2263400EF6DF8 /* MJGHTTPRequest.h */,
136 | C9020A4B14A2263400EF6DF8 /* MJGHTTPRequest.m */,
137 | C9EC378A14B9CDDF00D82F67 /* MJGHTTPDownload.h */,
138 | C9EC378B14B9CDDF00D82F67 /* MJGHTTPDownload.m */,
139 | C9020A4C14A2263400EF6DF8 /* NSDictionary-HTTP.h */,
140 | C9020A4D14A2263400EF6DF8 /* NSDictionary-HTTP.m */,
141 | C9EB549D14A5E22F003B4206 /* NSString-HTTP.h */,
142 | C9EB549E14A5E22F003B4206 /* NSString-HTTP.m */,
143 | );
144 | name = Source;
145 | path = ../Source;
146 | sourceTree = "";
147 | };
148 | /* End PBXGroup section */
149 |
150 | /* Begin PBXNativeTarget section */
151 | C9020A1D14A222A500EF6DF8 /* MJGHTTPRequestDemo */ = {
152 | isa = PBXNativeTarget;
153 | buildConfigurationList = C9020A3614A222A500EF6DF8 /* Build configuration list for PBXNativeTarget "MJGHTTPRequestDemo" */;
154 | buildPhases = (
155 | C9020A1A14A222A500EF6DF8 /* Sources */,
156 | C9020A1B14A222A500EF6DF8 /* Frameworks */,
157 | C9020A1C14A222A500EF6DF8 /* Resources */,
158 | );
159 | buildRules = (
160 | );
161 | dependencies = (
162 | );
163 | name = MJGHTTPRequestDemo;
164 | productName = MJGHTTPRequestDemo;
165 | productReference = C9020A1E14A222A500EF6DF8 /* MJGHTTPRequestDemo.app */;
166 | productType = "com.apple.product-type.application";
167 | };
168 | /* End PBXNativeTarget section */
169 |
170 | /* Begin PBXProject section */
171 | C9020A1514A222A500EF6DF8 /* Project object */ = {
172 | isa = PBXProject;
173 | attributes = {
174 | LastUpgradeCheck = 0420;
175 | };
176 | buildConfigurationList = C9020A1814A222A500EF6DF8 /* Build configuration list for PBXProject "MJGHTTPRequestDemo" */;
177 | compatibilityVersion = "Xcode 3.2";
178 | developmentRegion = English;
179 | hasScannedForEncodings = 0;
180 | knownRegions = (
181 | en,
182 | );
183 | mainGroup = C9020A1314A222A500EF6DF8;
184 | productRefGroup = C9020A1F14A222A500EF6DF8 /* Products */;
185 | projectDirPath = "";
186 | projectRoot = "";
187 | targets = (
188 | C9020A1D14A222A500EF6DF8 /* MJGHTTPRequestDemo */,
189 | );
190 | };
191 | /* End PBXProject section */
192 |
193 | /* Begin PBXResourcesBuildPhase section */
194 | C9020A1C14A222A500EF6DF8 /* Resources */ = {
195 | isa = PBXResourcesBuildPhase;
196 | buildActionMask = 2147483647;
197 | files = (
198 | C9020A5F14A233B900EF6DF8 /* MJGHTTPRequestDemoViewController.xib in Resources */,
199 | );
200 | runOnlyForDeploymentPostprocessing = 0;
201 | };
202 | /* End PBXResourcesBuildPhase section */
203 |
204 | /* Begin PBXSourcesBuildPhase section */
205 | C9020A1A14A222A500EF6DF8 /* Sources */ = {
206 | isa = PBXSourcesBuildPhase;
207 | buildActionMask = 2147483647;
208 | files = (
209 | C9020A4314A225E700EF6DF8 /* main.m in Sources */,
210 | C9020A4514A225E700EF6DF8 /* AppDelegate.m in Sources */,
211 | C9020A4E14A2263400EF6DF8 /* MJGHTTPRequest.m in Sources */,
212 | C9020A4F14A2263400EF6DF8 /* NSDictionary-HTTP.m in Sources */,
213 | C9020A5A14A22FC000EF6DF8 /* BeerMapApiRequest.m in Sources */,
214 | C9020A5E14A233B900EF6DF8 /* MJGHTTPRequestDemoViewController.m in Sources */,
215 | C9EB549F14A5E22F003B4206 /* NSString-HTTP.m in Sources */,
216 | C9EC378C14B9CDDF00D82F67 /* MJGHTTPDownload.m in Sources */,
217 | );
218 | runOnlyForDeploymentPostprocessing = 0;
219 | };
220 | /* End PBXSourcesBuildPhase section */
221 |
222 | /* Begin XCBuildConfiguration section */
223 | C9020A3414A222A500EF6DF8 /* Debug */ = {
224 | isa = XCBuildConfiguration;
225 | buildSettings = {
226 | ALWAYS_SEARCH_USER_PATHS = NO;
227 | ARCHS = "$(ARCHS_STANDARD_32_BIT)";
228 | CLANG_ENABLE_OBJC_ARC = YES;
229 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
230 | COPY_PHASE_STRIP = NO;
231 | GCC_C_LANGUAGE_STANDARD = gnu99;
232 | GCC_DYNAMIC_NO_PIC = NO;
233 | GCC_OPTIMIZATION_LEVEL = 0;
234 | GCC_PREPROCESSOR_DEFINITIONS = (
235 | "DEBUG=1",
236 | "$(inherited)",
237 | );
238 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
239 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
240 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
241 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
242 | GCC_WARN_UNUSED_VARIABLE = YES;
243 | IPHONEOS_DEPLOYMENT_TARGET = 5.0;
244 | SDKROOT = iphoneos;
245 | };
246 | name = Debug;
247 | };
248 | C9020A3514A222A500EF6DF8 /* Release */ = {
249 | isa = XCBuildConfiguration;
250 | buildSettings = {
251 | ALWAYS_SEARCH_USER_PATHS = NO;
252 | ARCHS = "$(ARCHS_STANDARD_32_BIT)";
253 | CLANG_ENABLE_OBJC_ARC = YES;
254 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
255 | COPY_PHASE_STRIP = YES;
256 | GCC_C_LANGUAGE_STANDARD = gnu99;
257 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
258 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
259 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
260 | GCC_WARN_UNUSED_VARIABLE = YES;
261 | IPHONEOS_DEPLOYMENT_TARGET = 5.0;
262 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
263 | SDKROOT = iphoneos;
264 | VALIDATE_PRODUCT = YES;
265 | };
266 | name = Release;
267 | };
268 | C9020A3714A222A500EF6DF8 /* Debug */ = {
269 | isa = XCBuildConfiguration;
270 | buildSettings = {
271 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
272 | GCC_PREFIX_HEADER = "MJGHTTPRequestDemo-Prefix.pch";
273 | INFOPLIST_FILE = "MJGHTTPRequestDemo-Info.plist";
274 | PRODUCT_NAME = "$(TARGET_NAME)";
275 | WRAPPER_EXTENSION = app;
276 | };
277 | name = Debug;
278 | };
279 | C9020A3814A222A500EF6DF8 /* Release */ = {
280 | isa = XCBuildConfiguration;
281 | buildSettings = {
282 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
283 | GCC_PREFIX_HEADER = "MJGHTTPRequestDemo-Prefix.pch";
284 | INFOPLIST_FILE = "MJGHTTPRequestDemo-Info.plist";
285 | PRODUCT_NAME = "$(TARGET_NAME)";
286 | WRAPPER_EXTENSION = app;
287 | };
288 | name = Release;
289 | };
290 | /* End XCBuildConfiguration section */
291 |
292 | /* Begin XCConfigurationList section */
293 | C9020A1814A222A500EF6DF8 /* Build configuration list for PBXProject "MJGHTTPRequestDemo" */ = {
294 | isa = XCConfigurationList;
295 | buildConfigurations = (
296 | C9020A3414A222A500EF6DF8 /* Debug */,
297 | C9020A3514A222A500EF6DF8 /* Release */,
298 | );
299 | defaultConfigurationIsVisible = 0;
300 | defaultConfigurationName = Release;
301 | };
302 | C9020A3614A222A500EF6DF8 /* Build configuration list for PBXNativeTarget "MJGHTTPRequestDemo" */ = {
303 | isa = XCConfigurationList;
304 | buildConfigurations = (
305 | C9020A3714A222A500EF6DF8 /* Debug */,
306 | C9020A3814A222A500EF6DF8 /* Release */,
307 | );
308 | defaultConfigurationIsVisible = 0;
309 | defaultConfigurationName = Release;
310 | };
311 | /* End XCConfigurationList section */
312 | };
313 | rootObject = C9020A1514A222A500EF6DF8 /* Project object */;
314 | }
315 |
--------------------------------------------------------------------------------
/Demo/MJGHTTPRequestDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Demo/Source/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // MJGHTTPRequestDemo
4 | //
5 | // Copyright (c) 2011 Matt Galloway. All rights reserved.
6 | //
7 | // Redistribution and use in source and binary forms, with or without
8 | // modification, are permitted provided that the following conditions are met:
9 | //
10 | // 1. Redistributions of source code must retain the above copyright notice, this
11 | // list of conditions and the following disclaimer.
12 | //
13 | // 2. Redistributions in binary form must reproduce the above copyright notice,
14 | // this list of conditions and the following disclaimer in the documentation
15 | // and/or other materials provided with the distribution.
16 | //
17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 |
29 | #import
30 |
31 | @interface AppDelegate : UIResponder
32 |
33 | @property (strong, nonatomic) UIWindow *window;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/Demo/Source/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // MJGHTTPRequestDemo
4 | //
5 | // Copyright (c) 2011 Matt Galloway. All rights reserved.
6 | //
7 | // Redistribution and use in source and binary forms, with or without
8 | // modification, are permitted provided that the following conditions are met:
9 | //
10 | // 1. Redistributions of source code must retain the above copyright notice, this
11 | // list of conditions and the following disclaimer.
12 | //
13 | // 2. Redistributions in binary form must reproduce the above copyright notice,
14 | // this list of conditions and the following disclaimer in the documentation
15 | // and/or other materials provided with the distribution.
16 | //
17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 |
29 | #import "AppDelegate.h"
30 |
31 | #import "MJGHTTPRequestDemoViewController.h"
32 |
33 | @implementation AppDelegate
34 |
35 | @synthesize window = _window;
36 |
37 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
38 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
39 | self.window.backgroundColor = [UIColor whiteColor];
40 |
41 | MJGHTTPRequestDemoViewController *viewController = [[MJGHTTPRequestDemoViewController alloc] initWithNibName:nil bundle:nil];
42 | self.window.rootViewController = viewController;
43 |
44 | [self.window makeKeyAndVisible];
45 | return YES;
46 | }
47 |
48 | - (void)applicationWillResignActive:(UIApplication *)application {
49 | }
50 |
51 | - (void)applicationDidEnterBackground:(UIApplication *)application {
52 | }
53 |
54 | - (void)applicationWillEnterForeground:(UIApplication *)application {
55 | }
56 |
57 | - (void)applicationDidBecomeActive:(UIApplication *)application {
58 | }
59 |
60 | - (void)applicationWillTerminate:(UIApplication *)application {
61 | }
62 |
63 | @end
64 |
--------------------------------------------------------------------------------
/Demo/Source/BeerMapApiRequest.h:
--------------------------------------------------------------------------------
1 | //
2 | // BeerMapApiRequest.h
3 | // MJGHTTPRequestDemo
4 | //
5 | // Copyright (c) 2011 Matt Galloway. All rights reserved.
6 | //
7 | // Redistribution and use in source and binary forms, with or without
8 | // modification, are permitted provided that the following conditions are met:
9 | //
10 | // 1. Redistributions of source code must retain the above copyright notice, this
11 | // list of conditions and the following disclaimer.
12 | //
13 | // 2. Redistributions in binary form must reproduce the above copyright notice,
14 | // this list of conditions and the following disclaimer in the documentation
15 | // and/or other materials provided with the distribution.
16 | //
17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 |
29 | /**
30 | * Example of how to use MJGHTTPRequest by creating a class that can talk to the BeerMap API.
31 | */
32 |
33 | #import "MJGHTTPRequest.h"
34 |
35 | @interface BeerMapApiRequest : MJGHTTPRequest
36 |
37 | - (id)initWithApiPath:(NSString*)apiPath requestMethod:(MJGHTTPRequestMethod)method;
38 |
39 | // Methods to override from MJGHTTPRequest
40 | - (NSString*)url;
41 | - (NSDictionary*)extraParameters;
42 | - (NSDictionary*)extraGetParameters;
43 | - (id)handleResult:(NSData*)result error:(NSError**)error;
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/Demo/Source/BeerMapApiRequest.m:
--------------------------------------------------------------------------------
1 | //
2 | // BeerMapApiRequest.m
3 | // MJGHTTPRequestDemo
4 | //
5 | // Copyright (c) 2011 Matt Galloway. All rights reserved.
6 | //
7 | // Redistribution and use in source and binary forms, with or without
8 | // modification, are permitted provided that the following conditions are met:
9 | //
10 | // 1. Redistributions of source code must retain the above copyright notice, this
11 | // list of conditions and the following disclaimer.
12 | //
13 | // 2. Redistributions in binary form must reproduce the above copyright notice,
14 | // this list of conditions and the following disclaimer in the documentation
15 | // and/or other materials provided with the distribution.
16 | //
17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 |
29 | #import "BeerMapApiRequest.h"
30 |
31 | @interface BeerMapApiRequest ()
32 | @property (nonatomic, copy) NSString *apiPath;
33 | @end
34 |
35 | @implementation BeerMapApiRequest
36 |
37 | @synthesize apiPath;
38 |
39 | #pragma mark -
40 |
41 | - (id)initWithApiPath:(NSString*)inApiPath requestMethod:(MJGHTTPRequestMethod)method {
42 | if ((self = [super initWithRequestMethod:method])) {
43 | self.apiPath = inApiPath;
44 | }
45 | return self;
46 | }
47 |
48 |
49 | #pragma mark -
50 |
51 | - (NSString*)url {
52 | return [NSString stringWithFormat:@"http://bmapi.mynet.org.uk/v2/%@", apiPath];
53 | }
54 |
55 | - (NSDictionary*)extraParameters {
56 | return nil;
57 | }
58 |
59 | - (NSDictionary*)extraGetParameters {
60 | return [NSDictionary dictionaryWithObjectsAndKeys:
61 | @"json", @"format",
62 | nil];
63 | }
64 |
65 | - (id)handleResult:(NSData*)result error:(NSError**)error {
66 | NSError *jsonError = nil;
67 | NSDictionary *outResult = [NSJSONSerialization JSONObjectWithData:result
68 | options:0
69 | error:&jsonError];
70 | if (jsonError) {
71 | if (error) {
72 | *error = jsonError;
73 | }
74 | return nil;
75 | }
76 |
77 | return outResult;
78 | }
79 |
80 | @end
81 |
--------------------------------------------------------------------------------
/Demo/Source/MJGHTTPRequestDemoViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // MJGHTTPRequestDemoViewController.h
3 | // MJGHTTPRequestDemo
4 | //
5 | // Copyright (c) 2011 Matt Galloway. All rights reserved.
6 | //
7 | // Redistribution and use in source and binary forms, with or without
8 | // modification, are permitted provided that the following conditions are met:
9 | //
10 | // 1. Redistributions of source code must retain the above copyright notice, this
11 | // list of conditions and the following disclaimer.
12 | //
13 | // 2. Redistributions in binary form must reproduce the above copyright notice,
14 | // this list of conditions and the following disclaimer in the documentation
15 | // and/or other materials provided with the distribution.
16 | //
17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 |
29 | #import
30 |
31 | @interface MJGHTTPRequestDemoViewController : UIViewController
32 |
33 | @property (nonatomic, strong) IBOutlet UITextView *outputText;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/Demo/Source/MJGHTTPRequestDemoViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // MJGHTTPRequestDemoViewController.m
3 | // MJGHTTPRequestDemo
4 | //
5 | // Copyright (c) 2011 Matt Galloway. All rights reserved.
6 | //
7 | // Redistribution and use in source and binary forms, with or without
8 | // modification, are permitted provided that the following conditions are met:
9 | //
10 | // 1. Redistributions of source code must retain the above copyright notice, this
11 | // list of conditions and the following disclaimer.
12 | //
13 | // 2. Redistributions in binary form must reproduce the above copyright notice,
14 | // this list of conditions and the following disclaimer in the documentation
15 | // and/or other materials provided with the distribution.
16 | //
17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 |
29 | #import "MJGHTTPRequestDemoViewController.h"
30 |
31 | #import "BeerMapApiRequest.h"
32 |
33 | @implementation MJGHTTPRequestDemoViewController
34 |
35 | @synthesize outputText;
36 |
37 | #pragma mark -
38 |
39 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
40 | if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
41 | }
42 | return self;
43 | }
44 |
45 | - (void)didReceiveMemoryWarning {
46 | [super didReceiveMemoryWarning];
47 | }
48 |
49 |
50 | #pragma mark - View lifecycle
51 |
52 | - (void)viewDidLoad {
53 | [super viewDidLoad];
54 |
55 | BeerMapApiRequest *request = [[BeerMapApiRequest alloc] initWithApiPath:@"beer/show" requestMethod:MJGHTTPRequestMethodGET];
56 | request.parameters = [NSDictionary dictionaryWithObjectsAndKeys:@"651", @"id", nil];
57 | [request startWithHandler:^(id result, NSHTTPURLResponse *response, NSError *error){
58 | if (!error) {
59 | // BeerMapApiRequest returns an NSDictionary, but we'll just output it's description anyway
60 | self.outputText.text = [result description];
61 | } else {
62 | // Ooops! Error!
63 | self.outputText.text = [error description];
64 | }
65 | }];
66 | }
67 |
68 | - (void)viewDidUnload {
69 | [super viewDidUnload];
70 | self.outputText = nil;
71 | }
72 |
73 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
74 | return (interfaceOrientation == UIInterfaceOrientationPortrait);
75 | }
76 |
77 | @end
78 |
--------------------------------------------------------------------------------
/Demo/Source/MJGHTTPRequestDemoViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 1280
5 | 11C74
6 | 1938
7 | 1138.23
8 | 567.00
9 |
13 |
14 | IBProxyObject
15 | IBUIView
16 | IBUITextView
17 |
18 |
19 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
20 |
21 |
25 |
26 |
30 |
34 |
82 |
83 |
84 |
85 |
86 |
87 | view
88 |
89 |
90 |
91 | 3
92 |
93 |
94 |
95 | outputText
96 |
97 |
98 |
99 | 6
100 |
101 |
102 |
103 |
104 |
105 | 0
106 |
107 |
108 |
109 |
110 |
111 | 1
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 | -1
120 |
121 |
122 | File's Owner
123 |
124 |
125 | -2
126 |
127 |
128 |
129 |
130 | 5
131 |
132 |
133 |
134 |
135 |
136 |
137 | MJGHTTPRequestDemoViewController
138 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
139 | UIResponder
140 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
141 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
142 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
143 |
144 |
145 |
146 |
147 |
148 | 6
149 |
150 |
151 |
152 |
153 | MJGHTTPRequestDemoViewController
154 | UIViewController
155 |
156 | outputText
157 | UITextView
158 |
159 |
160 | outputText
161 |
162 | outputText
163 | UITextView
164 |
165 |
166 |
167 | IBProjectSource
168 | ./Classes/MJGHTTPRequestDemoViewController.h
169 |
170 |
171 |
172 |
173 | 0
174 | IBCocoaTouchFramework
175 | YES
176 | 3
177 | 933
178 |
179 |
180 |
--------------------------------------------------------------------------------
/Demo/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // MJGHTTPRequestDemo
4 | //
5 | // Copyright (c) 2011 Matt Galloway. All rights reserved.
6 | //
7 | // Redistribution and use in source and binary forms, with or without
8 | // modification, are permitted provided that the following conditions are met:
9 | //
10 | // 1. Redistributions of source code must retain the above copyright notice, this
11 | // list of conditions and the following disclaimer.
12 | //
13 | // 2. Redistributions in binary form must reproduce the above copyright notice,
14 | // this list of conditions and the following disclaimer in the documentation
15 | // and/or other materials provided with the distribution.
16 | //
17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 |
29 | #import
30 |
31 | #import "AppDelegate.h"
32 |
33 | int main(int argc, char *argv[])
34 | {
35 | @autoreleasepool {
36 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2011 Matt Galloway. All rights reserved.
2 |
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions are met:
5 |
6 | 1. Redistributions of source code must retain the above copyright notice, this
7 | list of conditions and the following disclaimer.
8 |
9 | 2. Redistributions in binary form must reproduce the above copyright notice,
10 | this list of conditions and the following disclaimer in the documentation
11 | and/or other materials provided with the distribution.
12 |
13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
17 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
21 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 |
--------------------------------------------------------------------------------
/README.markdown:
--------------------------------------------------------------------------------
1 | # MJGHTTPRequest
2 |
3 | ## Introduction
4 |
5 | MJGHTTPRequest is a class designed to be subclassed to take the pain out of performing HTTP
6 | requests on iOS. Most HTTP APIs have a base URL that's the same (e.g. api.twitter.com) and take
7 | certain parameters. They also usually return a given format of data such as JSON or XML.
8 | MJGHTTPRequest enables you to create your own class to talk to these APIs and handle all the HTTP
9 | level things for you. All you need to do is hook into whatever mechanism you want to handle the
10 | returned data which might be passing it through a JSON or XML deserialiser for example.
11 |
12 | ## Features
13 |
14 | * GET & POST HTTP requests.
15 | * URL encoded, multipart & raw POST formats.
16 | * Customisation hooks to act on the request at its various stages.
17 |
18 | ## Why should I use MJGHTTPRequest?
19 |
20 | MJGHTTPRequest is useful for when you have a project that is using an HTTP API and you find
21 | yourself writing the same code over and over again. Whether it's the same code using standard
22 | Cocoa APIs or some other asynchronous HTTP request framework, MJGHTTPRequest is the perfect
23 | replacement to take the pain out of all that duplicated code. It gives you the flexibility to
24 | write once a class that conforms to the spec laid out by your HTTP API and then use it everywhere!
25 |
26 | ## License
27 |
28 | MJGHTTPRequest uses the 2-clause BSD license. So you should be free to use it pretty much however
29 | you want. Contact me if you require further information.
30 |
31 | Copyright (c) 2011 Matt Galloway. All rights reserved.
32 |
33 | Redistribution and use in source and binary forms, with or without
34 | modification, are permitted provided that the following conditions are met:
35 |
36 | 1. Redistributions of source code must retain the above copyright notice, this
37 | list of conditions and the following disclaimer.
38 |
39 | 2. Redistributions in binary form must reproduce the above copyright notice,
40 | this list of conditions and the following disclaimer in the documentation
41 | and/or other materials provided with the distribution.
42 |
43 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
44 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
46 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
47 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
49 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
50 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
51 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53 |
54 | ## Automatic Reference Counting (ARC)
55 |
56 | This project uses ARC.
57 |
58 | ## Author
59 |
60 | MJGHTTPRequest is written and maintained by Matt Galloway .
61 |
62 | ## Projects using MJGHTTPRequest
63 |
64 | * BeerMap - http://www.beermap.co/
65 | * Kindmags Magazine Framework - http://www.kindmags.com/
66 |
67 | Are you using MJGHTTPRequest? If so, contact me and I'll add you to the list.
68 |
69 | ## How to use
70 |
71 | As an example, we will assume there is a HTTP API which is based at http://api.example.com/v1/
72 | which has the following methods:
73 |
74 | * `search` - takes a single paramter `term` and returns an array of results. Result will be found in
75 | under the key `results` in the returned object.
76 | * `upload` - takes files to be uploaded to the server and returns success or failure.
77 |
78 | In addition, all methods are required to have a `format` paremeter set in the query part of the URL
79 | to indicate either `json` or `xml` return types. We will use `json`. The API defines that every
80 | request will return a JSON object with the data in it.
81 |
82 | ### Adding MJGHTTPRequest to your project
83 |
84 | All you need to do to get started is to add everything in the `Source` folder to your project.
85 |
86 | ### Subclassing MJGHTTPRequest
87 |
88 | 1. Create a class which inherits from `MJGHTTPRequest`:
89 |
90 | #import "MJGHTTPRequest.h"
91 | @interface MyApiRequest : MJGHTTPRequest
92 | @property (nonatomic, strong) NSString *path;
93 | @end
94 |
95 | 1. Implement the required methods:
96 |
97 | @implementation MyApiRequest
98 |
99 | @synthesize path;
100 |
101 | - (NSString*)url {
102 | return [NSString stringWithFormat:@"http://api.example.com/v1/%@", path];
103 | }
104 |
105 | - (NSDictionary*)extraParameters {
106 | return nil;
107 | }
108 |
109 | - (NSDictionary*)extraGetParameters {
110 | return [NSDictionary dictionaryWithObjectsAndKeys:
111 | @"json", @"format",
112 | nil];
113 | }
114 |
115 | - (id)handleResult:(NSData*)result error:(NSError**)error {
116 | // We know our API is returning a JSON object, so lets deserialise it and return the object
117 |
118 | NSError *jsonError = nil;
119 | NSDictionary *outResult = [NSJSONSerialization JSONObjectWithData:result
120 | options:0
121 | error:&jsonError];
122 | if (jsonError) {
123 | if (error) {
124 | *error = jsonError;
125 | }
126 | return nil;
127 | }
128 |
129 | return outResult;
130 | }
131 | @end
132 |
133 | ### Using your subclass
134 |
135 | 1. Now use the subclass to peform a search:
136 |
137 | MyApiRequest *request = [[MyApiRequest alloc] initWithRequestMethod:MJGHTTPRequestMethodGET];
138 | request.path = @"search";
139 | request.parameters = [NSDictionary dictionaryWithObjectsAndKeys:@"bunnies", @"term", nil];
140 | [request startWithHandler:^(id result, NSHTTPURLResponse *response, NSError *error){
141 | if (!error) {
142 | // Yay the request worked!
143 | NSArray *results = [(NSDictionary*)result objectForKey:@"results"];
144 | NSLog(@"Results:\n%@", results);
145 | } else {
146 | // Ooops! Error!
147 | }
148 | }];
149 |
150 | 1. And now upload a picture:
151 |
152 | UIImage *image = ;
153 | MyApiRequest *request = [[MyApiRequest alloc] initWithRequestMethod:MJGHTTPRequestMethodPOST];
154 | request.postMethod = MJGHTTPRequestPOSTMethodFormData;
155 | request.path = @"upload";
156 | [request addFileData:UIImagePNGRepresentation(image)
157 | forKey:@"image"
158 | withFilename:@"image.png"
159 | type:@"image/png"];
160 | [request startWithHandler:^(id result, NSHTTPURLResponse *response, NSError *error){
161 | if (!error) {
162 | // Yay the request worked!
163 | } else {
164 | // Ooops! Error!
165 | }
166 | }];
167 |
--------------------------------------------------------------------------------
/Source/MJGHTTPDownload.h:
--------------------------------------------------------------------------------
1 | //
2 | // MJGHTTPDownload.h
3 | // MJGHTTPRequest
4 | //
5 | // Copyright (c) 2011 Matt Galloway. All rights reserved.
6 | //
7 | // Redistribution and use in source and binary forms, with or without
8 | // modification, are permitted provided that the following conditions are met:
9 | //
10 | // 1. Redistributions of source code must retain the above copyright notice, this
11 | // list of conditions and the following disclaimer.
12 | //
13 | // 2. Redistributions in binary form must reproduce the above copyright notice,
14 | // this list of conditions and the following disclaimer in the documentation
15 | // and/or other materials provided with the distribution.
16 | //
17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 |
29 | #import
30 |
31 | typedef void(^MJGHTTPDownloadHandler)(NSString *filename, NSHTTPURLResponse *response, NSError *error);
32 | typedef void(^MJGHTTPDownloadProgressHandler)(float progress);
33 |
34 | @interface MJGHTTPDownload : NSObject
35 |
36 | @property (nonatomic, assign, readonly) float progress;
37 |
38 | - (id)initWithURL:(NSString*)url downloadFilename:(NSString*)filename;
39 | + (MJGHTTPDownload*)requestWithURL:(NSString*)url downloadFilename:(NSString*)filename;
40 |
41 | - (void)startWithHandler:(MJGHTTPDownloadHandler)handler;
42 | - (void)startWithHandler:(MJGHTTPDownloadHandler)handler progressHandler:(MJGHTTPDownloadProgressHandler)progressHandler;
43 | - (void)cancel;
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/Source/MJGHTTPDownload.m:
--------------------------------------------------------------------------------
1 | //
2 | // MJGHTTPDownload.m
3 | // MJGHTTPRequest
4 | //
5 | // Copyright (c) 2011 Matt Galloway. All rights reserved.
6 | //
7 | // Redistribution and use in source and binary forms, with or without
8 | // modification, are permitted provided that the following conditions are met:
9 | //
10 | // 1. Redistributions of source code must retain the above copyright notice, this
11 | // list of conditions and the following disclaimer.
12 | //
13 | // 2. Redistributions in binary form must reproduce the above copyright notice,
14 | // this list of conditions and the following disclaimer in the documentation
15 | // and/or other materials provided with the distribution.
16 | //
17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 |
29 | #if ! __has_feature(objc_arc)
30 | #error This file requires ARC to be enabled. Either enable ARC for the entire project or use -fobjc-arc flag.
31 | #endif
32 |
33 | #import "MJGHTTPDownload.h"
34 |
35 | @interface MJGHTTPDownload ()
36 | @property (nonatomic, copy) MJGHTTPDownloadHandler handler;
37 | @property (nonatomic, copy) MJGHTTPDownloadProgressHandler progressHandler;
38 |
39 | @property (nonatomic, copy) NSString *url;
40 | @property (nonatomic, copy) NSString *filename;
41 |
42 | @property (nonatomic, strong) NSURLConnection *connection;
43 | @property (nonatomic, strong) NSHTTPURLResponse *response;
44 | @property (nonatomic, strong) NSFileHandle *responseFileHandle;
45 | @property (nonatomic, assign) long long expectedContentLength;
46 | @property (nonatomic, assign) long long downloadedLength;
47 |
48 | - (void)failWithError:(NSError*)error;
49 | - (void)finish;
50 | @end
51 |
52 | @implementation MJGHTTPDownload
53 |
54 | @synthesize handler = _handler, progressHandler = _progressHandler;
55 | @synthesize url = _url, filename = _filename;
56 | @synthesize connection = _connection, response = _response, responseFileHandle = _responseFileHandle, expectedContentLength = _expectedContentLength, downloadedLength = _downloadedLength;
57 |
58 | #pragma mark -
59 |
60 | - (id)initWithURL:(NSString*)inUrl downloadFilename:(NSString*)inFilename {
61 | if ((self = [self init])) {
62 | _url = [inUrl copy];
63 | _filename = [inFilename copy];
64 | }
65 | return self;
66 | }
67 |
68 | + (MJGHTTPDownload*)requestWithURL:(NSString*)inUrl downloadFilename:(NSString*)inFilename {
69 | return [[MJGHTTPDownload alloc] initWithURL:inUrl downloadFilename:inFilename];
70 | }
71 |
72 |
73 | #pragma mark - Custom accessors
74 |
75 | - (float)progress {
76 | return (float)((double)_downloadedLength / (double)_expectedContentLength);
77 | }
78 |
79 |
80 | #pragma mark -
81 |
82 | - (void)startWithHandler:(MJGHTTPDownloadHandler)inHandler {
83 | [self startWithHandler:inHandler progressHandler:nil];
84 | }
85 |
86 | - (void)startWithHandler:(MJGHTTPDownloadHandler)inHandler progressHandler:(MJGHTTPDownloadProgressHandler)inProgressHandler {
87 | self.handler = inHandler;
88 | self.progressHandler = inProgressHandler;
89 |
90 | NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:_url]
91 | cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
92 | timeoutInterval:30.0];
93 | [request setHTTPMethod:@"GET"];
94 |
95 | NSFileManager *fileManager = [[NSFileManager alloc] init];
96 | if ([fileManager fileExistsAtPath:_filename]) {
97 | // Try to restart the download
98 | NSError *error = nil;
99 | NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:_filename error:&error];
100 | NSNumber *fileSize = [fileAttributes objectForKey:NSFileSize];
101 | if (!error && fileSize) {
102 | unsigned long long bytes = [fileSize unsignedLongLongValue];
103 | [request setValue:[NSString stringWithFormat:@"bytes=%llu-", bytes] forHTTPHeaderField:@"Range"];
104 | } else {
105 | [fileManager removeItemAtPath:_filename error:nil];
106 | [fileManager createFileAtPath:_filename contents:nil attributes:nil];
107 | }
108 | } else {
109 | // Just create a new file
110 | [fileManager createFileAtPath:_filename contents:nil attributes:nil];
111 | }
112 |
113 | _connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
114 | }
115 |
116 | - (void)cancel {
117 | [_connection cancel];
118 | _connection = nil;
119 | }
120 |
121 |
122 | #pragma mark -
123 |
124 | - (void)failWithError:(NSError*)error {
125 | if (_handler) {
126 | _handler(nil, _response, error);
127 | }
128 | }
129 |
130 | - (void)finish {
131 | if (_handler) {
132 | _handler(_filename, _response, nil);
133 | }
134 | }
135 |
136 |
137 | #pragma mark - NSURLConnectionDelegate
138 |
139 | - (void)connection:(NSURLConnection*)aConnection didReceiveResponse:(NSURLResponse*)inResponse {
140 | _expectedContentLength = [inResponse expectedContentLength];
141 | _downloadedLength = 0;
142 |
143 | _responseFileHandle = nil;
144 |
145 | if ([inResponse isKindOfClass:[NSHTTPURLResponse class]]) {
146 | _response = (NSHTTPURLResponse*)inResponse;
147 |
148 | NSInteger statusCode = [_response statusCode];
149 | if (statusCode >= 200 && statusCode <= 299) {
150 | _responseFileHandle = [NSFileHandle fileHandleForWritingAtPath:_filename];
151 |
152 | NSString *contentRangeHeader = [[_response allHeaderFields] objectForKey:@"Content-Range"];
153 | NSString *removePrefix = [contentRangeHeader stringByReplacingOccurrencesOfString:@"bytes " withString:@""];
154 | NSArray *splitSlash = [removePrefix componentsSeparatedByString:@"/"];
155 | if (splitSlash.count == 2) {
156 | NSArray *splitDash = [[splitSlash objectAtIndex:0] componentsSeparatedByString:@"-"];
157 | if (splitDash.count == 2) {
158 | NSString *startByte = [splitDash objectAtIndex:0];
159 | unsigned long long bytes = strtoull([startByte UTF8String], NULL, 0);
160 | @try {
161 | [_responseFileHandle seekToFileOffset:bytes];
162 | _expectedContentLength += bytes;
163 | _downloadedLength += bytes;
164 | } @catch (NSException *e) {
165 | [_connection cancel];
166 | _connection = nil;
167 | [self failWithError:nil];
168 | }
169 | }
170 | }
171 | } else if (statusCode == 416) {
172 | [_connection cancel];
173 | _connection = nil;
174 | NSFileManager *fileManager = [[NSFileManager alloc] init];
175 | [fileManager removeItemAtPath:_filename error:nil];
176 | [self startWithHandler:_handler progressHandler:_progressHandler];
177 | } else {
178 | [_connection cancel];
179 | _connection = nil;
180 | NSError *error = [NSError errorWithDomain:NSURLErrorDomain
181 | code:NSURLErrorUnknown
182 | userInfo:nil];
183 | [self failWithError:error];
184 | }
185 | }
186 | }
187 |
188 | - (NSURLRequest *)connection:(NSURLConnection *)aConnection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse {
189 | return nil;
190 | }
191 |
192 | - (void)connection:(NSURLConnection*)aConnection didReceiveData:(NSData*)data {
193 | _downloadedLength += [data length];
194 |
195 | if (_responseFileHandle) {
196 | [_responseFileHandle writeData:data];
197 | [_responseFileHandle synchronizeFile];
198 | }
199 |
200 | if (_expectedContentLength != NSURLResponseUnknownLength) {
201 | if (_progressHandler) {
202 | _progressHandler([self progress]);
203 | }
204 | }
205 | }
206 |
207 | - (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite {
208 | }
209 |
210 | - (NSCachedURLResponse*)connection:(NSURLConnection*)aConnection willCacheResponse:(NSCachedURLResponse*)cachedResponse {
211 | return nil;
212 | }
213 |
214 | - (void)connectionDidFinishLoading:(NSURLConnection*)aConnection {
215 | [self finish];
216 | _responseFileHandle = nil;
217 | _connection = nil;
218 | }
219 |
220 | - (void)connection:(NSURLConnection*)aConnection didFailWithError:(NSError*)error {
221 | [self failWithError:error];
222 | _responseFileHandle = nil;
223 | _connection = nil;
224 | }
225 |
226 |
227 | #pragma mark -
228 |
229 | - (id)init {
230 | if ((self = [super init])) {
231 | _expectedContentLength = NSURLResponseUnknownLength;
232 | _downloadedLength = 0;
233 | }
234 | return self;
235 | }
236 |
237 | - (void)dealloc {
238 | [_connection cancel];
239 | }
240 |
241 | @end
242 |
--------------------------------------------------------------------------------
/Source/MJGHTTPRequest.h:
--------------------------------------------------------------------------------
1 | //
2 | // MJGHTTPRequest.h
3 | // MJGHTTPRequest
4 | //
5 | // Copyright (c) 2011 Matt Galloway. All rights reserved.
6 | //
7 | // Redistribution and use in source and binary forms, with or without
8 | // modification, are permitted provided that the following conditions are met:
9 | //
10 | // 1. Redistributions of source code must retain the above copyright notice, this
11 | // list of conditions and the following disclaimer.
12 | //
13 | // 2. Redistributions in binary form must reproduce the above copyright notice,
14 | // this list of conditions and the following disclaimer in the documentation
15 | // and/or other materials provided with the distribution.
16 | //
17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 |
29 | #import
30 |
31 | typedef enum {
32 | MJGHTTPRequestMethodGET = 1,
33 | MJGHTTPRequestMethodPOST,
34 | } MJGHTTPRequestMethod;
35 |
36 | typedef enum {
37 | MJGHTTPRequestMethodPOSTFormatRawData = 1,
38 | MJGHTTPRequestMethodPOSTFormatURLEncode,
39 | MJGHTTPRequestMethodPOSTFormatFormData,
40 | } MJGHTTPRequestPOSTFormat;
41 |
42 | typedef void(^MJGHTTPRequestHandler)(id result, NSHTTPURLResponse *response, NSError *error);
43 | typedef void(^MJGHTTPRequestProgressHandler)(BOOL uploading, float progress);
44 |
45 | @class MJGHTTPRequest;
46 |
47 | @interface MJGHTTPRequest : NSObject
48 |
49 | @property (nonatomic, strong) NSDictionary *parameters;
50 | @property (nonatomic, assign) MJGHTTPRequestPOSTFormat postFormat;
51 |
52 | - (id)initWithRequestMethod:(MJGHTTPRequestMethod)method;
53 | + (MJGHTTPRequest*)requestWithRequestMethod:(MJGHTTPRequestMethod)method;
54 |
55 | - (void)setPOSTBody:(NSData*)data type:(NSString*)type;
56 | - (void)addFileData:(NSData*)data forKey:(NSString*)key withFilename:(NSString*)filename type:(NSString*)type;
57 |
58 | - (void)startWithHandler:(MJGHTTPRequestHandler)handler;
59 | - (void)startWithHandler:(MJGHTTPRequestHandler)handler progressHandler:(MJGHTTPRequestProgressHandler)progressHandler;
60 | - (void)cancel;
61 |
62 | /**
63 | * IMPORTANT: Must override this method!
64 | * Return the URL to hit for this request.
65 | */
66 | - (NSString*)url;
67 |
68 | /**
69 | * Return any extra paramters to add to the request.
70 | */
71 | - (NSDictionary*)extraParameters;
72 |
73 | /**
74 | * Return any extra GET query paramters to add to the request.
75 | * This can be used to always have certain parameters in the query part of the URL.
76 | */
77 | - (NSDictionary*)extraGetParameters;
78 |
79 | /**
80 | * Optionally override this to handle the data which has been returned from the request.
81 | * If error is set by this method then it is passed back to the handler.
82 | * An example implementation for this would be to deserialise a JSON body.
83 | */
84 | - (id)handleResult:(NSData*)result error:(NSError**)error;
85 |
86 | @end
87 |
--------------------------------------------------------------------------------
/Source/MJGHTTPRequest.m:
--------------------------------------------------------------------------------
1 | //
2 | // MJGHTTPRequest.m
3 | // MJGHTTPRequest
4 | //
5 | // Copyright (c) 2011 Matt Galloway. All rights reserved.
6 | //
7 | // Redistribution and use in source and binary forms, with or without
8 | // modification, are permitted provided that the following conditions are met:
9 | //
10 | // 1. Redistributions of source code must retain the above copyright notice, this
11 | // list of conditions and the following disclaimer.
12 | //
13 | // 2. Redistributions in binary form must reproduce the above copyright notice,
14 | // this list of conditions and the following disclaimer in the documentation
15 | // and/or other materials provided with the distribution.
16 | //
17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 |
29 | #if ! __has_feature(objc_arc)
30 | #error This file requires ARC to be enabled. Either enable ARC for the entire project or use -fobjc-arc flag.
31 | #endif
32 |
33 | #import "MJGHTTPRequest.h"
34 |
35 | #import "NSDictionary-HTTP.h"
36 |
37 | @interface MJGHTTPRequest ()
38 | @property (nonatomic, assign) MJGHTTPRequestMethod method;
39 | @property (nonatomic, strong) NSData *rawPostData;
40 | @property (nonatomic, copy) NSString *rawPostType;
41 | @property (nonatomic, strong) NSMutableArray *fileData;
42 |
43 | @property (nonatomic, copy) MJGHTTPRequestHandler handler;
44 | @property (nonatomic, copy) MJGHTTPRequestProgressHandler progressHandler;
45 |
46 | @property (nonatomic, strong) NSURLConnection *connection;
47 | @property (nonatomic, strong) NSHTTPURLResponse *response;
48 | @property (nonatomic, strong) NSMutableData *responseData;
49 | @property (nonatomic, assign) long long expectedContentLength;
50 | @property (nonatomic, assign) long long downloadedLength;
51 |
52 | - (void)failWithError:(NSError*)error;
53 | - (void)handleResponseData;
54 |
55 | - (void)generateFormDataPostBody:(NSMutableURLRequest*)request;
56 | - (void)generateUrlEncodedPostBody:(NSMutableURLRequest*)request;
57 | @end
58 |
59 | @implementation MJGHTTPRequest
60 |
61 | @synthesize parameters = _parameters, postFormat = _postFormat;
62 | @synthesize method = _method, rawPostData = _rawPostData, rawPostType = _rawPostType, fileData = _fileData;
63 | @synthesize handler = _handler, progressHandler = _progressHandler;
64 | @synthesize connection = _connection, response = _response, responseData = _responseData, expectedContentLength = _expectedContentLength, downloadedLength = _downloadedLength;
65 |
66 | #pragma mark -
67 |
68 | - (id)initWithRequestMethod:(MJGHTTPRequestMethod)inMethod {
69 | if ((self = [self init])) {
70 | _method = inMethod;
71 | _postFormat = MJGHTTPRequestMethodPOSTFormatURLEncode;
72 | }
73 | return self;
74 | }
75 |
76 | + (MJGHTTPRequest*)requestWithRequestMethod:(MJGHTTPRequestMethod)method {
77 | return [[MJGHTTPRequest alloc] initWithRequestMethod:method];
78 | }
79 |
80 |
81 | #pragma mark -
82 |
83 | - (void)setPOSTBody:(NSData*)data type:(NSString*)type {
84 | // We need to set the post method to raw data if we're setting the post body
85 | _postFormat = MJGHTTPRequestMethodPOSTFormatRawData;
86 | _rawPostData = data;
87 | _rawPostType = type;
88 | }
89 |
90 | - (void)addFileData:(NSData*)data forKey:(NSString*)key withFilename:(NSString*)filename type:(NSString*)type {
91 | // We need to set the post method to form data if we're adding files
92 | _postFormat = MJGHTTPRequestMethodPOSTFormatFormData;
93 |
94 | NSDictionary *newFileData = [NSDictionary dictionaryWithObjectsAndKeys:
95 | data, @"data",
96 | key, @"key",
97 | filename, @"filename",
98 | type, @"type",
99 | nil];
100 | [_fileData addObject:newFileData];
101 | }
102 |
103 | - (void)startWithHandler:(MJGHTTPRequestHandler)inHandler {
104 | [self startWithHandler:inHandler progressHandler:nil];
105 | }
106 |
107 | - (void)startWithHandler:(MJGHTTPRequestHandler)inHandler progressHandler:(MJGHTTPRequestProgressHandler)inProgressHandler {
108 | self.handler = inHandler;
109 | self.progressHandler = inProgressHandler;
110 |
111 | NSMutableString *url = [NSMutableString stringWithString:[self url]];
112 |
113 | NSMutableDictionary *allGetParameters = [NSMutableDictionary dictionaryWithCapacity:0];
114 | [allGetParameters addEntriesFromDictionary:[self extraGetParameters]];
115 |
116 | if (_method == MJGHTTPRequestMethodGET) {
117 | [allGetParameters addEntriesFromDictionary:[self extraParameters]];
118 | [allGetParameters addEntriesFromDictionary:_parameters];
119 | }
120 |
121 | if (allGetParameters.count > 0) {
122 | [url appendFormat:@"?%@", [allGetParameters getQuery]];
123 | }
124 |
125 | NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]
126 | cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
127 | timeoutInterval:30.0];
128 |
129 | if (_method == MJGHTTPRequestMethodGET) {
130 | [request setHTTPMethod:@"GET"];
131 | } else if (_method == MJGHTTPRequestMethodPOST) {
132 | [request setHTTPMethod:@"POST"];
133 | if (_postFormat == MJGHTTPRequestMethodPOSTFormatRawData) {
134 | [request setHTTPBody:_rawPostData];
135 | if (_rawPostType) {
136 | [request setValue:_rawPostType forHTTPHeaderField:@"Content-Type"];
137 | }
138 | } else if (_postFormat == MJGHTTPRequestMethodPOSTFormatFormData) {
139 | [self generateFormDataPostBody:request];
140 | } else if (_postFormat == MJGHTTPRequestMethodPOSTFormatURLEncode) {
141 | [self generateUrlEncodedPostBody:request];
142 | }
143 | }
144 |
145 | _connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
146 | }
147 |
148 | - (void)cancel {
149 | [_connection cancel];
150 | _connection = nil;
151 | }
152 |
153 |
154 | #pragma mark -
155 |
156 | - (void)failWithError:(NSError*)error {
157 | if (_handler) {
158 | _handler(nil, _response, error);
159 | }
160 | }
161 |
162 | - (void)handleResponseData {
163 | NSError *error = nil;
164 | id result = [self handleResult:_responseData error:&error];
165 | if (_handler) {
166 | _handler(result, _response, error);
167 | }
168 | _responseData = nil;
169 | }
170 |
171 |
172 | #pragma mark - POST body generation
173 |
174 | - (void)generateFormDataPostBody:(NSMutableURLRequest*)request {
175 | NSString *httpBoundary = @"----MJGHTTPRequest0xce86d7d02a229acfaca4b63f01a1171b";
176 |
177 | [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", httpBoundary] forHTTPHeaderField:@"Content-Type"];
178 |
179 | NSMutableData *body = [[NSMutableData alloc] init];
180 |
181 | NSString *startLine = [NSString stringWithFormat:@"\r\n"];
182 | NSString *endLine = [NSString stringWithFormat:@"\r\n--%@", httpBoundary];
183 |
184 | [body appendData:[[NSString stringWithFormat:@"--%@", httpBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
185 |
186 | NSMutableDictionary *allParameters = [NSMutableDictionary dictionaryWithDictionary:_parameters];
187 | [allParameters addEntriesFromDictionary:[self extraParameters]];
188 |
189 | for (id key in [allParameters keyEnumerator]) {
190 | id value = [allParameters objectForKey:key];
191 | if ([value isKindOfClass:[NSString class]]) {
192 | [body appendData:[startLine dataUsingEncoding:NSUTF8StringEncoding]];
193 | [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
194 | [body appendData:[@"Content-Type: text/plain; charset=utf-8\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
195 | [body appendData:[(NSString*)value dataUsingEncoding:NSUTF8StringEncoding]];
196 | [body appendData:[endLine dataUsingEncoding:NSUTF8StringEncoding]];
197 | } else if ([value isKindOfClass:[NSNumber class]]) {
198 | [body appendData:[startLine dataUsingEncoding:NSUTF8StringEncoding]];
199 | [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
200 | [body appendData:[@"Content-Type: text/plain; charset=utf-8\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
201 | [body appendData:[[(NSNumber*)value stringValue] dataUsingEncoding:NSUTF8StringEncoding]];
202 | [body appendData:[endLine dataUsingEncoding:NSUTF8StringEncoding]];
203 | }
204 | }
205 |
206 | for (NSDictionary *dict in _fileData) {
207 | NSData *data = [dict objectForKey:@"data"];
208 | NSData *key = [dict objectForKey:@"key"];
209 | NSData *filename = [dict objectForKey:@"filename"];
210 | NSData *type = [dict objectForKey:@"type"];
211 |
212 | [body appendData:[startLine dataUsingEncoding:NSUTF8StringEncoding]];
213 |
214 | [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", key, filename] dataUsingEncoding:NSUTF8StringEncoding]];
215 | [body appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", type] dataUsingEncoding:NSUTF8StringEncoding]];
216 | [body appendData:data];
217 |
218 | [body appendData:[endLine dataUsingEncoding:NSUTF8StringEncoding]];
219 | }
220 |
221 | [body appendData:[@"--\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
222 |
223 | [request setHTTPBody:body];
224 | }
225 |
226 | - (void)generateUrlEncodedPostBody:(NSMutableURLRequest*)request {
227 | NSMutableDictionary *allParameters = [NSMutableDictionary dictionaryWithDictionary:_parameters];
228 | [allParameters addEntriesFromDictionary:[self extraParameters]];
229 |
230 | NSData *thisPostData = [allParameters formEncodedPostData];
231 | [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
232 | [request setHTTPBody:thisPostData];
233 | }
234 |
235 |
236 | #pragma mark - NSURLConnectionDelegate
237 |
238 | - (void)connection:(NSURLConnection*)aConnection didReceiveResponse:(NSURLResponse*)inResponse {
239 | _responseData = [[NSMutableData alloc] init];
240 | _expectedContentLength = [inResponse expectedContentLength];
241 | _downloadedLength = 0;
242 |
243 | if ([inResponse isKindOfClass:[NSHTTPURLResponse class]]) {
244 | _response = (NSHTTPURLResponse*)inResponse;
245 | }
246 | }
247 |
248 | - (void)connection:(NSURLConnection*)aConnection didReceiveData:(NSData*)data {
249 | _downloadedLength += [data length];
250 |
251 | [_responseData appendData:data];
252 |
253 | if (_expectedContentLength != NSURLResponseUnknownLength) {
254 | if (_progressHandler) {
255 | float p = (float)_downloadedLength / (float)_expectedContentLength;
256 | _progressHandler(NO, p);
257 | }
258 | }
259 | }
260 |
261 | - (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite {
262 | if (_progressHandler) {
263 | float p = (float)totalBytesWritten / (float)totalBytesExpectedToWrite;
264 | _progressHandler(YES, p);
265 | }
266 | }
267 |
268 | - (void)connectionDidFinishLoading:(NSURLConnection*)aConnection {
269 | [self handleResponseData];
270 | _responseData = nil;
271 | _connection = nil;
272 | }
273 |
274 | - (void)connection:(NSURLConnection*)aConnection didFailWithError:(NSError*)error {
275 | [self failWithError:error];
276 | _responseData = nil;
277 | _connection = nil;
278 | }
279 |
280 |
281 | #pragma mark - Default methods
282 |
283 | - (NSString*)url {
284 | @throw [NSException exceptionWithName:NSInternalInconsistencyException
285 | reason:[NSString stringWithFormat:@"Subclasses must override %@.", NSStringFromSelector(_cmd)]
286 | userInfo:nil];
287 | }
288 |
289 | - (NSDictionary*)extraParameters {
290 | return nil;
291 | }
292 |
293 | - (NSDictionary*)extraGetParameters {
294 | return nil;
295 | }
296 |
297 | - (id)handleResult:(NSData*)result error:(NSError**)error {
298 | return result;
299 | }
300 |
301 |
302 | #pragma mark -
303 |
304 | - (id)init {
305 | if ((self = [super init])) {
306 | _expectedContentLength = NSURLResponseUnknownLength;
307 | _downloadedLength = 0;
308 |
309 | _fileData = [[NSMutableArray alloc] initWithCapacity:0];
310 | }
311 | return self;
312 | }
313 |
314 | @end
315 |
--------------------------------------------------------------------------------
/Source/NSDictionary-HTTP.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSDictionary-HTTP.h
3 | // MJGHTTPRequest
4 | //
5 | // Copyright (c) 2011 Matt Galloway. All rights reserved.
6 | //
7 | // Redistribution and use in source and binary forms, with or without
8 | // modification, are permitted provided that the following conditions are met:
9 | //
10 | // 1. Redistributions of source code must retain the above copyright notice, this
11 | // list of conditions and the following disclaimer.
12 | //
13 | // 2. Redistributions in binary form must reproduce the above copyright notice,
14 | // this list of conditions and the following disclaimer in the documentation
15 | // and/or other materials provided with the distribution.
16 | //
17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 |
29 | #import
30 |
31 | @interface NSDictionary (HTTP)
32 |
33 | - (NSString*)getQuery;
34 | - (NSData*)formEncodedPostData;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/Source/NSDictionary-HTTP.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSDictionary-HTTP.m
3 | // MJGHTTPRequest
4 | //
5 | // Copyright (c) 2011 Matt Galloway. All rights reserved.
6 | //
7 | // Redistribution and use in source and binary forms, with or without
8 | // modification, are permitted provided that the following conditions are met:
9 | //
10 | // 1. Redistributions of source code must retain the above copyright notice, this
11 | // list of conditions and the following disclaimer.
12 | //
13 | // 2. Redistributions in binary form must reproduce the above copyright notice,
14 | // this list of conditions and the following disclaimer in the documentation
15 | // and/or other materials provided with the distribution.
16 | //
17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 |
29 | #if ! __has_feature(objc_arc)
30 | #error This file requires ARC to be enabled. Either enable ARC for the entire project or use -fobjc-arc flag.
31 | #endif
32 |
33 | #import "NSDictionary-HTTP.h"
34 |
35 | #import "NSString-HTTP.h"
36 |
37 | @implementation NSDictionary (HTTP)
38 |
39 | - (NSString*)getQuery {
40 | NSMutableArray *pairs = [[NSMutableArray alloc] initWithCapacity:0];
41 | for (NSString *key in [self keyEnumerator]) {
42 | id value = [self objectForKey:key];
43 |
44 | // TODO: Support more than just NSString and NSNumber
45 |
46 | if ([value isKindOfClass:[NSString class]]) {
47 | [pairs addObject:[NSString stringWithFormat:@"%@=%@",
48 | [key urlEncodedString],
49 | [(NSString*)value urlEncodedString]]];
50 | } else if ([value isKindOfClass:[NSNumber class]]) {
51 | [pairs addObject:[NSString stringWithFormat:@"%@=%@",
52 | [key urlEncodedString],
53 | [[(NSNumber*)value stringValue] urlEncodedString]]];
54 | }
55 | }
56 | return [pairs componentsJoinedByString:@"&"];
57 | }
58 |
59 | - (NSData*)formEncodedPostData {
60 | return [[self getQuery] dataUsingEncoding:NSUTF8StringEncoding];
61 | }
62 |
63 | @end
64 |
--------------------------------------------------------------------------------
/Source/NSString-HTTP.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSString-HTTP.h
3 | // MJGHTTPRequestDemo
4 | //
5 | // Copyright (c) 2011 Matt Galloway. All rights reserved.
6 | //
7 | // Redistribution and use in source and binary forms, with or without
8 | // modification, are permitted provided that the following conditions are met:
9 | //
10 | // 1. Redistributions of source code must retain the above copyright notice, this
11 | // list of conditions and the following disclaimer.
12 | //
13 | // 2. Redistributions in binary form must reproduce the above copyright notice,
14 | // this list of conditions and the following disclaimer in the documentation
15 | // and/or other materials provided with the distribution.
16 | //
17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 |
29 | #import
30 |
31 | @interface NSString (HTTP)
32 |
33 | - (NSString*)urlEncodedString;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/Source/NSString-HTTP.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString-HTTP.m
3 | // MJGHTTPRequestDemo
4 | //
5 | // Copyright (c) 2011 Matt Galloway. All rights reserved.
6 | //
7 | // Redistribution and use in source and binary forms, with or without
8 | // modification, are permitted provided that the following conditions are met:
9 | //
10 | // 1. Redistributions of source code must retain the above copyright notice, this
11 | // list of conditions and the following disclaimer.
12 | //
13 | // 2. Redistributions in binary form must reproduce the above copyright notice,
14 | // this list of conditions and the following disclaimer in the documentation
15 | // and/or other materials provided with the distribution.
16 | //
17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 |
29 | #if ! __has_feature(objc_arc)
30 | #error This file requires ARC to be enabled. Either enable ARC for the entire project or use -fobjc-arc flag.
31 | #endif
32 |
33 | #import "NSString-HTTP.h"
34 |
35 | @implementation NSString (HTTP)
36 |
37 | - (NSString*)urlEncodedString {
38 | NSString *encoded = (__bridge_transfer NSString*)CFURLCreateStringByAddingPercentEscapes(NULL,
39 | (__bridge CFStringRef)self,
40 | NULL,
41 | (CFStringRef)@"!*'();:@&=+$,/?%#[]",
42 | kCFStringEncodingUTF8);
43 | return encoded;
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------