diff --git a/README.md b/README.md index e1382c1..4836ece 100644 --- a/README.md +++ b/README.md @@ -150,66 +150,6 @@ println("Visit \(webServer.serverURL) in your web browser") #import "GCDWebServerDataResponse.h" ``` -Asynchronous HTTP Responses -=========================== - -New in GCDWebServer 3.0 is the ability to process HTTP requests aysnchronously i.e. add handlers to the server which generate their ```GCDWebServerResponse``` asynchronously. This is achieved by adding handlers that use a ```GCDWebServerAsyncProcessBlock``` instead of a ```GCDWebServerProcessBlock```. Here's an example: - -**(Synchronous version)** The handler blocks while generating the HTTP response: -```objectivec -[webServer addDefaultHandlerForMethod:@"GET" - requestClass:[GCDWebServerRequest class] - processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { - - GCDWebServerDataResponse* response = [GCDWebServerDataResponse responseWithHTML:@"

Hello World

"]; - return response; - -}]; -``` - -**(Asynchronous version)** The handler returns immediately and calls back GCDWebServer later with the generated HTTP response: -```objectivec -[webServer addDefaultHandlerForMethod:@"GET" - requestClass:[GCDWebServerRequest class] - asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) { - - // Do some async operation like network access or file I/O (simulated here using dispatch_after()) - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - GCDWebServerDataResponse* response = [GCDWebServerDataResponse responseWithHTML:@"

Hello World

"]; - completionBlock(response); - }); - -}]; -``` - -**(Advanced asynchronous version)** The handler returns immediately a streamed HTTP response which itself generates its contents asynchronously: -```objectivec -[webServer addDefaultHandlerForMethod:@"GET" - requestClass:[GCDWebServerRequest class] - processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { - - NSMutableArray* contents = [NSMutableArray arrayWithObjects:@"

\n", @"Hello World!\n", @"

\n", nil]; // Fake data source we are reading from - GCDWebServerStreamedResponse* response = [GCDWebServerStreamedResponse responseWithContentType:@"text/html" asyncStreamBlock:^(GCDWebServerBodyReaderCompletionBlock completionBlock) { - - // Simulate a delay reading from the fake data source - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - NSString* string = contents.firstObject; - if (string) { - [contents removeObjectAtIndex:0]; - completionBlock([string dataUsingEncoding:NSUTF8StringEncoding], nil); // Generate the 2nd part of the stream data - } else { - completionBlock([NSData data], nil); // Must pass an empty NSData to signal the end of the stream - } - }); - - }]; - return response; - -}]; -``` - -*Note that you can even combine both the asynchronous and advanced asynchronous versions to return asynchronously an asynchronous HTTP response!* - Web Based Uploads in iOS Apps ============================= @@ -317,6 +257,66 @@ Handlers require 2 GCD blocks: Note that most methods on ```GCDWebServer``` to add handlers only require the ```GCDWebServerProcessBlock``` or ```GCDWebServerAsyncProcessBlock``` as they already provide a built-in ```GCDWebServerMatchBlock``` e.g. to match a URL path with a Regex. +Asynchronous HTTP Responses +=========================== + +New in GCDWebServer 3.0 is the ability to process HTTP requests aysnchronously i.e. add handlers to the server which generate their ```GCDWebServerResponse``` asynchronously. This is achieved by adding handlers that use a ```GCDWebServerAsyncProcessBlock``` instead of a ```GCDWebServerProcessBlock```. Here's an example: + +**(Synchronous version)** The handler blocks while generating the HTTP response: +```objectivec +[webServer addDefaultHandlerForMethod:@"GET" + requestClass:[GCDWebServerRequest class] + processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { + + GCDWebServerDataResponse* response = [GCDWebServerDataResponse responseWithHTML:@"

Hello World

"]; + return response; + +}]; +``` + +**(Asynchronous version)** The handler returns immediately and calls back GCDWebServer later with the generated HTTP response: +```objectivec +[webServer addDefaultHandlerForMethod:@"GET" + requestClass:[GCDWebServerRequest class] + asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) { + + // Do some async operation like network access or file I/O (simulated here using dispatch_after()) + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + GCDWebServerDataResponse* response = [GCDWebServerDataResponse responseWithHTML:@"

Hello World

"]; + completionBlock(response); + }); + +}]; +``` + +**(Advanced asynchronous version)** The handler returns immediately a streamed HTTP response which itself generates its contents asynchronously: +```objectivec +[webServer addDefaultHandlerForMethod:@"GET" + requestClass:[GCDWebServerRequest class] + processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { + + NSMutableArray* contents = [NSMutableArray arrayWithObjects:@"

\n", @"Hello World!\n", @"

\n", nil]; // Fake data source we are reading from + GCDWebServerStreamedResponse* response = [GCDWebServerStreamedResponse responseWithContentType:@"text/html" asyncStreamBlock:^(GCDWebServerBodyReaderCompletionBlock completionBlock) { + + // Simulate a delay reading from the fake data source + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSString* string = contents.firstObject; + if (string) { + [contents removeObjectAtIndex:0]; + completionBlock([string dataUsingEncoding:NSUTF8StringEncoding], nil); // Generate the 2nd part of the stream data + } else { + completionBlock([NSData data], nil); // Must pass an empty NSData to signal the end of the stream + } + }); + + }]; + return response; + +}]; +``` + +*Note that you can even combine both the asynchronous and advanced asynchronous versions to return asynchronously an asynchronous HTTP response!* + GCDWebServer & Background Mode for iOS Apps ===========================================