summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authortkchin@webrtc.org <tkchin@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d>2014-06-06 22:29:10 +0000
committertkchin@webrtc.org <tkchin@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d>2014-06-06 22:29:10 +0000
commit596929a99d1d5191866a038aab5dd451e76213ad (patch)
treedd94c16bcdb98e9fb5e17f9ff43c157e327d4192 /examples
parent50af306dbdc1248470aac424d889dde4f952625d (diff)
downloadtalk-596929a99d1d5191866a038aab5dd451e76213ad.tar.gz
APPRTCDemo(objc): Remove regex parsing in favor of JSON struct.
Also some cleanup/refactoring of APPRTCAppClient. R=fischman@webrtc.org, glaznev@webrtc.org BUG=3407 Review URL: https://webrtc-codereview.appspot.com/18499004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@6362 4adac7df-926f-26a2-2b94-8c16560cd09d
Diffstat (limited to 'examples')
-rw-r--r--examples/objc/AppRTCDemo/APPRTCAppClient.h8
-rw-r--r--examples/objc/AppRTCDemo/APPRTCAppClient.m473
-rw-r--r--examples/objc/AppRTCDemo/GAEChannelClient.h5
-rw-r--r--examples/objc/AppRTCDemo/GAEChannelClient.m8
4 files changed, 232 insertions, 262 deletions
diff --git a/examples/objc/AppRTCDemo/APPRTCAppClient.h b/examples/objc/AppRTCDemo/APPRTCAppClient.h
index b69b517..8b21db5 100644
--- a/examples/objc/AppRTCDemo/APPRTCAppClient.h
+++ b/examples/objc/AppRTCDemo/APPRTCAppClient.h
@@ -48,20 +48,20 @@
// call connectToRoom(). apprtc.appspot.com will signal that is successful via
// onOpen through the browser channel. Then you should call sendData() and wait
// for the registered handler to be called with received messages.
-@interface APPRTCAppClient : NSObject<NSURLConnectionDataDelegate>
+@interface APPRTCAppClient : NSObject
@property(nonatomic) BOOL initiator;
@property(nonatomic, copy, readonly) RTCMediaConstraints* videoConstraints;
@property(nonatomic, weak) id<APPRTCAppClientDelegate> delegate;
-- (id)initWithDelegate:(id<APPRTCAppClientDelegate>)delegate
- messageHandler:(id<GAEMessageHandler>)handler;
+- (instancetype)initWithDelegate:(id<APPRTCAppClientDelegate>)delegate
+ messageHandler:(id<GAEMessageHandler>)handler;
- (void)connectToRoom:(NSURL*)room;
- (void)sendData:(NSData*)data;
#ifndef DOXYGEN_SHOULD_SKIP_THIS
// Disallow init and don't add to documentation
-- (id)init __attribute__((
+- (instancetype)init __attribute__((
unavailable("init is not a supported initializer for this class.")));
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
diff --git a/examples/objc/AppRTCDemo/APPRTCAppClient.m b/examples/objc/AppRTCDemo/APPRTCAppClient.m
index c412aef..853496f 100644
--- a/examples/objc/AppRTCDemo/APPRTCAppClient.m
+++ b/examples/objc/AppRTCDemo/APPRTCAppClient.m
@@ -38,290 +38,184 @@
#import "RTCMediaConstraints.h"
#import "RTCPair.h"
-@interface APPRTCAppClient ()
-
-@property(nonatomic, weak, readonly) id<GAEMessageHandler> messageHandler;
-@property(nonatomic, copy) NSString* baseURL;
-@property(nonatomic, strong) GAEChannelClient* gaeChannel;
-@property(nonatomic, copy) NSString* postMessageUrl;
-@property(nonatomic, copy) NSString* pcConfig;
-@property(nonatomic, strong) NSMutableString* roomHtml;
-@property(atomic, strong) NSMutableArray* sendQueue;
-@property(nonatomic, copy) NSString* token;
-
-@property(nonatomic, assign) BOOL verboseLogging;
-
-@end
-
@implementation APPRTCAppClient {
dispatch_queue_t _backgroundQueue;
+ GAEChannelClient* _gaeChannel;
+ NSURL* _postMessageURL;
+ BOOL _verboseLogging;
+ __weak id<GAEMessageHandler> _messageHandler;
}
-- (id)initWithDelegate:(id<APPRTCAppClientDelegate>)delegate
- messageHandler:(id<GAEMessageHandler>)handler {
+- (instancetype)initWithDelegate:(id<APPRTCAppClientDelegate>)delegate
+ messageHandler:(id<GAEMessageHandler>)handler {
if (self = [super init]) {
_delegate = delegate;
_messageHandler = handler;
_backgroundQueue = dispatch_queue_create("RTCBackgroundQueue",
DISPATCH_QUEUE_SERIAL);
- _sendQueue = [NSMutableArray array];
// Uncomment to see Request/Response logging.
// _verboseLogging = YES;
}
return self;
}
-#pragma mark - Public methods
-
- (void)connectToRoom:(NSURL*)url {
- self.roomHtml = [NSMutableString stringWithCapacity:20000];
- NSURLRequest* request = [NSURLRequest requestWithURL:url];
- [NSURLConnection connectionWithRequest:request delegate:self];
-}
-
-- (void)sendData:(NSData*)data {
- [self maybeLogMessage:@"Send message"];
-
- dispatch_async(_backgroundQueue, ^{
- [self.sendQueue addObject:[data copy]];
-
- if ([self.postMessageUrl length] < 1) {
+ NSString* urlString =
+ [[url absoluteString] stringByAppendingString:@"&t=json"];
+ NSURL* requestURL = [NSURL URLWithString:urlString];
+ NSURLRequest* request = [NSURLRequest requestWithURL:requestURL];
+ [self sendURLRequest:request
+ completionHandler:^(NSError* error,
+ NSHTTPURLResponse* httpResponse,
+ NSData* responseData) {
+ int statusCode = [httpResponse statusCode];
+ [self logVerbose:[NSString stringWithFormat:
+ @"Response received\nURL\n%@\nStatus [%d]\nHeaders\n%@",
+ [httpResponse URL],
+ statusCode,
+ [httpResponse allHeaderFields]]];
+ NSAssert(statusCode == 200,
+ @"Invalid response of %d received while connecting to: %@",
+ statusCode,
+ urlString);
+ if (statusCode != 200) {
return;
}
- for (NSData* data in self.sendQueue) {
- NSString* url =
- [NSString stringWithFormat:@"%@/%@",
- self.baseURL, self.postMessageUrl];
- [self sendData:data withUrl:url];
- }
- [self.sendQueue removeAllObjects];
- });
+ [self handleResponseData:responseData
+ forRoomRequest:request];
+ }];
}
-#pragma mark - Internal methods
-
-- (NSString*)findVar:(NSString*)name strippingQuotes:(BOOL)strippingQuotes {
- NSError* error;
- NSString* pattern =
- [NSString stringWithFormat:@".*\n *var %@ = ([^\n]*);\n.*", name];
- NSRegularExpression* regexp =
- [NSRegularExpression regularExpressionWithPattern:pattern
- options:0
- error:&error];
- NSAssert(!error,
- @"Unexpected error compiling regex: ",
- error.localizedDescription);
-
- NSRange fullRange = NSMakeRange(0, [self.roomHtml length]);
- NSArray* matches =
- [regexp matchesInString:self.roomHtml options:0 range:fullRange];
- if ([matches count] != 1) {
- NSString* format = @"%lu matches for %@ in %@";
- NSString* message = [NSString stringWithFormat:format,
- (unsigned long)[matches count], name, self.roomHtml];
- [self.delegate appClient:self didErrorWithMessage:message];
- return nil;
- }
- NSRange matchRange = [matches[0] rangeAtIndex:1];
- NSString* value = [self.roomHtml substringWithRange:matchRange];
- if (strippingQuotes) {
- NSAssert([value length] > 2,
- @"Can't strip quotes from short string: [%@]",
- value);
- NSAssert(([value characterAtIndex:0] == '\'' &&
- [value characterAtIndex:[value length] - 1] == '\''),
- @"Can't strip quotes from unquoted string: [%@]",
- value);
- value = [value substringWithRange:NSMakeRange(1, [value length] - 2)];
- }
- return value;
-}
-
-- (void)maybeLogMessage:(NSString*)message {
- if (self.verboseLogging) {
- NSLog(@"%@", message);
+- (void)sendData:(NSData*)data {
+ NSParameterAssert([data length] > 0);
+ NSString* message = [NSString stringWithUTF8String:[data bytes]];
+ [self logVerbose:[NSString stringWithFormat:@"Send message:\n%@", message]];
+ if (!_postMessageURL) {
+ return;
}
-}
-
-- (void)sendData:(NSData*)data withUrl:(NSString*)url {
NSMutableURLRequest* request =
- [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
+ [NSMutableURLRequest requestWithURL:_postMessageURL];
request.HTTPMethod = @"POST";
[request setHTTPBody:data];
- NSURLResponse* response;
- NSError* error;
- NSData* responseData = [NSURLConnection sendSynchronousRequest:request
- returningResponse:&response
- error:&error];
- NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
- int status = [httpResponse statusCode];
- NSAssert(status == 200,
- @"Bad response [%d] to message: %@\n\n%@",
- status,
- [NSString stringWithUTF8String:[data bytes]],
- [NSString stringWithUTF8String:[responseData bytes]]);
-}
-
-- (void)updateICEServers:(NSMutableArray*)ICEServers
- withTurnServer:(NSString*)turnServerUrl {
- if ([turnServerUrl length] < 1) {
- [self.delegate appClient:self didReceiveICEServers:ICEServers];
- return;
- }
- dispatch_async(_backgroundQueue, ^(void) {
- NSMutableURLRequest* request = [NSMutableURLRequest
- requestWithURL:[NSURL URLWithString:turnServerUrl]];
- [request addValue:@"Mozilla/5.0" forHTTPHeaderField:@"user-agent"];
- [request addValue:@"https://apprtc.appspot.com"
- forHTTPHeaderField:@"origin"];
- NSURLResponse* response;
- NSError* error;
- NSData* responseData = [NSURLConnection sendSynchronousRequest:request
- returningResponse:&response
- error:&error];
- if (!error) {
- NSDictionary* json =
- [NSJSONSerialization JSONObjectWithData:responseData
- options:0
- error:&error];
- NSAssert(!error, @"Unable to parse. %@", error.localizedDescription);
- NSString* username = json[@"username"];
- NSString* password = json[@"password"];
- NSArray* uris = json[@"uris"];
- for (int i = 0; i < [uris count]; ++i) {
- NSString* turnServer = [uris objectAtIndex:i];
- RTCICEServer* ICEServer =
- [[RTCICEServer alloc] initWithURI:[NSURL URLWithString:turnServer]
- username:username
- password:password];
- NSLog(@"Added ICE Server: %@", ICEServer);
- [ICEServers addObject:ICEServer];
- }
- } else {
- NSLog(@"Unable to get TURN server. Error: %@", error.description);
- }
-
- dispatch_async(dispatch_get_main_queue(), ^(void) {
- [self.delegate appClient:self didReceiveICEServers:ICEServers];
- });
- });
+ [self sendURLRequest:request
+ completionHandler:^(NSError* error,
+ NSHTTPURLResponse* httpResponse,
+ NSData* responseData) {
+ int status = [httpResponse statusCode];
+ NSString* response = [responseData length] > 0 ?
+ [NSString stringWithUTF8String:[responseData bytes]] :
+ nil;
+ NSAssert(status == 200,
+ @"Bad response [%d] to message: %@\n\n%@",
+ status,
+ message,
+ response);
+ }];
}
-#pragma mark - NSURLConnectionDataDelegate methods
+#pragma mark - Private
-- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data {
- NSString* roomHtml = [NSString stringWithUTF8String:[data bytes]];
- NSString* message =
- [NSString stringWithFormat:@"Received %lu chars",
- (unsigned long)[roomHtml length]];
- [self maybeLogMessage:message];
- [self.roomHtml appendString:roomHtml];
-}
-
-- (void)connection:(NSURLConnection*)connection
- didReceiveResponse:(NSURLResponse*)response {
- NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
- int statusCode = [httpResponse statusCode];
- [self
- maybeLogMessage:
- [NSString stringWithFormat:
- @"Response received\nURL\n%@\nStatus [%d]\nHeaders\n%@",
- [httpResponse URL],
- statusCode,
- [httpResponse allHeaderFields]]];
- NSAssert(statusCode == 200, @"Invalid response of %d received.", statusCode);
+- (void)logVerbose:(NSString*)message {
+ if (_verboseLogging) {
+ NSLog(@"%@", message);
+ }
}
-- (void)connectionDidFinishLoading:(NSURLConnection*)connection {
- NSString* message =
- [NSString stringWithFormat:@"finished loading %lu chars",
- (unsigned long)[self.roomHtml length]];
- [self maybeLogMessage:message];
- NSRegularExpression* fullRegex =
- [NSRegularExpression regularExpressionWithPattern:@"room is full"
- options:0
- error:nil];
- if ([fullRegex
- numberOfMatchesInString:self.roomHtml
- options:0
- range:NSMakeRange(0, [self.roomHtml length])]) {
- NSString* message = @"Room full, dropping peerconnection.";
+- (void)handleResponseData:(NSData*)responseData
+ forRoomRequest:(NSURLRequest*)request {
+ NSDictionary* roomJSON = [self parseJSONData:responseData];
+ [self logVerbose:[NSString stringWithFormat:@"Room JSON:\n%@", roomJSON]];
+ NSParameterAssert(roomJSON);
+ if (roomJSON[@"error"]) {
+ NSArray* errorMessages = roomJSON[@"error_messages"];
+ NSMutableString* message = [NSMutableString string];
+ for (NSString* errorMessage in errorMessages) {
+ [message appendFormat:@"%@\n", errorMessage];
+ }
[self.delegate appClient:self didErrorWithMessage:message];
return;
}
+ NSString* pcConfig = roomJSON[@"pc_config"];
+ NSData* pcConfigData = [pcConfig dataUsingEncoding:NSUTF8StringEncoding];
+ NSDictionary* pcConfigJSON = [self parseJSONData:pcConfigData];
+ [self logVerbose:[NSString stringWithFormat:@"PCConfig JSON:\n%@",
+ pcConfigJSON]];
+ NSParameterAssert(pcConfigJSON);
+
+ NSArray* iceServers = [self parseICEServersForPCConfigJSON:pcConfigJSON];
+ [self requestTURNServerForICEServers:iceServers
+ turnServerUrl:roomJSON[@"turn_url"]];
+
+ _initiator = [roomJSON[@"initiator"] boolValue];
+ [self logVerbose:[NSString stringWithFormat:@"Initiator: %d", _initiator]];
+ _postMessageURL = [self parsePostMessageURLForRoomJSON:roomJSON
+ request:request];
+ [self logVerbose:[NSString stringWithFormat:@"POST message URL:\n%@",
+ _postMessageURL]];
+ _videoConstraints = [self parseVideoConstraintsForRoomJSON:roomJSON];
+ [self logVerbose:[NSString stringWithFormat:@"Media constraints:\n%@",
+ _videoConstraints]];
+ NSString* token = roomJSON[@"token"];
+ [self logVerbose:
+ [NSString stringWithFormat:@"About to open GAE with token: %@",
+ token]];
+ _gaeChannel =
+ [[GAEChannelClient alloc] initWithToken:token
+ delegate:_messageHandler];
+}
- NSString* fullUrl = [[[connection originalRequest] URL] absoluteString];
- NSRange queryRange = [fullUrl rangeOfString:@"?"];
- self.baseURL = [fullUrl substringToIndex:queryRange.location];
- [self maybeLogMessage:[NSString
- stringWithFormat:@"Base URL: %@", self.baseURL]];
-
- self.initiator = [[self findVar:@"initiator" strippingQuotes:NO] boolValue];
- self.token = [self findVar:@"channelToken" strippingQuotes:YES];
- if (!self.token)
- return;
- [self maybeLogMessage:[NSString stringWithFormat:@"Token: %@", self.token]];
-
- NSString* roomKey = [self findVar:@"roomKey" strippingQuotes:YES];
- NSString* me = [self findVar:@"me" strippingQuotes:YES];
- if (!roomKey || !me)
- return;
- self.postMessageUrl =
- [NSString stringWithFormat:@"/message?r=%@&u=%@", roomKey, me];
- [self maybeLogMessage:[NSString stringWithFormat:@"POST message URL: %@",
- self.postMessageUrl]];
-
- NSString* pcConfig = [self findVar:@"pcConfig" strippingQuotes:NO];
- if (!pcConfig)
- return;
- [self maybeLogMessage:[NSString
- stringWithFormat:@"PC Config JSON: %@", pcConfig]];
-
- NSString* turnServerUrl = [self findVar:@"turnUrl" strippingQuotes:YES];
- if (turnServerUrl) {
- [self maybeLogMessage:[NSString
- stringWithFormat:@"TURN server request URL: %@",
- turnServerUrl]];
- }
-
- NSError* error;
- NSData* pcData = [pcConfig dataUsingEncoding:NSUTF8StringEncoding];
+- (NSDictionary*)parseJSONData:(NSData*)data {
+ NSError* error = nil;
NSDictionary* json =
- [NSJSONSerialization JSONObjectWithData:pcData options:0 error:&error];
+ [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSAssert(!error, @"Unable to parse. %@", error.localizedDescription);
- NSArray* servers = [json objectForKey:@"iceServers"];
- NSMutableArray* ICEServers = [NSMutableArray array];
- for (NSDictionary* server in servers) {
- NSString* url = [server objectForKey:@"urls"];
- NSString* username = json[@"username"];
- NSString* credential = [server objectForKey:@"credential"];
- if (!username) {
- username = @"";
- }
- if (!credential) {
- credential = @"";
- }
- [self maybeLogMessage:[NSString
- stringWithFormat:@"url [%@] - credential [%@]",
- url,
- credential]];
- RTCICEServer* ICEServer =
+ return json;
+}
+
+- (NSArray*)parseICEServersForPCConfigJSON:(NSDictionary*)pcConfigJSON {
+ NSMutableArray* result = [NSMutableArray array];
+ NSArray* iceServers = pcConfigJSON[@"iceServers"];
+ for (NSDictionary* iceServer in iceServers) {
+ NSString* url = iceServer[@"urls"];
+ NSString* username = pcConfigJSON[@"username"];
+ NSString* credential = iceServer[@"credential"];
+ username = username ? username : @"";
+ credential = credential ? credential : @"";
+ [self logVerbose:[NSString stringWithFormat:@"url [%@] - credential [%@]",
+ url,
+ credential]];
+ RTCICEServer* server =
[[RTCICEServer alloc] initWithURI:[NSURL URLWithString:url]
username:username
password:credential];
- NSLog(@"Added ICE Server: %@", ICEServer);
- [ICEServers addObject:ICEServer];
+ [result addObject:server];
}
- [self updateICEServers:ICEServers withTurnServer:turnServerUrl];
+ return result;
+}
+
+- (NSURL*)parsePostMessageURLForRoomJSON:(NSDictionary*)roomJSON
+ request:(NSURLRequest*)request {
+ NSString* requestUrl = [[request URL] absoluteString];
+ NSRange queryRange = [requestUrl rangeOfString:@"?"];
+ NSString* baseUrl = [requestUrl substringToIndex:queryRange.location];
+ NSString* roomKey = roomJSON[@"room_key"];
+ NSParameterAssert([roomKey length] > 0);
+ NSString* me = roomJSON[@"me"];
+ NSParameterAssert([me length] > 0);
+ NSString* postMessageUrl =
+ [NSString stringWithFormat:@"%@/message?r=%@&u=%@", baseUrl, roomKey, me];
+ return [NSURL URLWithString:postMessageUrl];
+}
- NSString* mc = [self findVar:@"mediaConstraints" strippingQuotes:NO];
- if (mc) {
- error = nil;
- NSData* mcData = [mc dataUsingEncoding:NSUTF8StringEncoding];
- json =
- [NSJSONSerialization JSONObjectWithData:mcData options:0 error:&error];
- NSAssert(!error, @"Unable to parse. %@", error.localizedDescription);
- id video = json[@"video"];
+- (RTCMediaConstraints*)parseVideoConstraintsForRoomJSON:
+ (NSDictionary*)roomJSON {
+ NSString* mediaConstraints = roomJSON[@"media_constraints"];
+ RTCMediaConstraints* constraints = nil;
+ if ([mediaConstraints length] > 0) {
+ NSData* constraintsData =
+ [mediaConstraints dataUsingEncoding:NSUTF8StringEncoding];
+ NSDictionary* constraintsJSON = [self parseJSONData:constraintsData];
+ id video = constraintsJSON[@"video"];
if ([video isKindOfClass:[NSDictionary class]]) {
NSDictionary* mandatory = video[@"mandatory"];
NSMutableArray* mandatoryContraints =
@@ -332,22 +226,95 @@
value:obj]];
}];
// TODO(tkchin): figure out json formats for optional constraints.
- _videoConstraints =
+ constraints =
[[RTCMediaConstraints alloc]
initWithMandatoryConstraints:mandatoryContraints
optionalConstraints:nil];
} else if ([video isKindOfClass:[NSNumber class]] && [video boolValue]) {
- _videoConstraints = [[RTCMediaConstraints alloc] init];
+ constraints = [[RTCMediaConstraints alloc] init];
+ }
+ }
+ return constraints;
+}
+
+- (void)requestTURNServerWithUrl:(NSString*)turnServerUrl
+ completionHandler:
+ (void (^)(RTCICEServer* turnServer))completionHandler {
+ NSURL* turnServerURL = [NSURL URLWithString:turnServerUrl];
+ NSMutableURLRequest* request =
+ [NSMutableURLRequest requestWithURL:turnServerURL];
+ [request addValue:@"Mozilla/5.0" forHTTPHeaderField:@"user-agent"];
+ [request addValue:@"https://apprtc.appspot.com"
+ forHTTPHeaderField:@"origin"];
+ [self sendURLRequest:request
+ completionHandler:^(NSError* error,
+ NSHTTPURLResponse* response,
+ NSData* responseData) {
+ if (error) {
+ NSLog(@"Unable to get TURN server.");
+ completionHandler(nil);
+ return;
+ }
+ NSDictionary* json = [self parseJSONData:responseData];
+ NSString* username = json[@"username"];
+ NSString* password = json[@"password"];
+ NSArray* uris = json[@"uris"];
+ NSParameterAssert([uris count] > 0);
+ RTCICEServer* turnServer =
+ [[RTCICEServer alloc] initWithURI:[NSURL URLWithString:uris[0]]
+ username:username
+ password:password];
+ completionHandler(turnServer);
+ }];
+}
+
+- (void)requestTURNServerForICEServers:(NSArray*)iceServers
+ turnServerUrl:(NSString*)turnServerUrl {
+ BOOL isTurnPresent = NO;
+ for (RTCICEServer* iceServer in iceServers) {
+ if ([[iceServer.URI scheme] isEqualToString:@"turn"]) {
+ isTurnPresent = YES;
+ break;
}
}
+ if (!isTurnPresent) {
+ [self requestTURNServerWithUrl:turnServerUrl
+ completionHandler:^(RTCICEServer* turnServer) {
+ NSArray* servers = iceServers;
+ if (turnServer) {
+ servers = [servers arrayByAddingObject:turnServer];
+ }
+ NSLog(@"ICE servers:\n%@", servers);
+ [self.delegate appClient:self didReceiveICEServers:servers];
+ }];
+ } else {
+ NSLog(@"ICE servers:\n%@", iceServers);
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self.delegate appClient:self didReceiveICEServers:iceServers];
+ });
+ }
+}
- [self
- maybeLogMessage:[NSString
- stringWithFormat:@"About to open GAE with token: %@",
- self.token]];
- self.gaeChannel =
- [[GAEChannelClient alloc] initWithToken:self.token
- delegate:self.messageHandler];
+- (void)sendURLRequest:(NSURLRequest*)request
+ completionHandler:(void (^)(NSError* error,
+ NSHTTPURLResponse* httpResponse,
+ NSData* responseData))completionHandler {
+ dispatch_async(_backgroundQueue, ^{
+ NSError* error = nil;
+ NSURLResponse* response = nil;
+ NSData* responseData = [NSURLConnection sendSynchronousRequest:request
+ returningResponse:&response
+ error:&error];
+ NSParameterAssert(!response ||
+ [response isKindOfClass:[NSHTTPURLResponse class]]);
+ if (error) {
+ NSLog(@"Failed URL request for:%@\nError:%@", request, error);
+ }
+ dispatch_async(dispatch_get_main_queue(), ^{
+ NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
+ completionHandler(error, httpResponse, responseData);
+ });
+ });
}
@end
diff --git a/examples/objc/AppRTCDemo/GAEChannelClient.h b/examples/objc/AppRTCDemo/GAEChannelClient.h
index 2eac214..dbaeceb 100644
--- a/examples/objc/AppRTCDemo/GAEChannelClient.h
+++ b/examples/objc/AppRTCDemo/GAEChannelClient.h
@@ -44,6 +44,9 @@
// application and AppEngine.
@interface GAEChannelClient : NSObject
-- (id)initWithToken:(NSString*)token delegate:(id<GAEMessageHandler>)delegate;
+@property(nonatomic, weak) id<GAEMessageHandler> delegate;
+
+- (instancetype)initWithToken:(NSString*)token
+ delegate:(id<GAEMessageHandler>)delegate;
@end
diff --git a/examples/objc/AppRTCDemo/GAEChannelClient.m b/examples/objc/AppRTCDemo/GAEChannelClient.m
index 6146043..a95e99a 100644
--- a/examples/objc/AppRTCDemo/GAEChannelClient.m
+++ b/examples/objc/AppRTCDemo/GAEChannelClient.m
@@ -47,13 +47,14 @@
#endif
-@property(nonatomic, assign) id<GAEMessageHandler> delegate;
-
@end
@implementation GAEChannelClient
-- (id)initWithToken:(NSString*)token delegate:(id<GAEMessageHandler>)delegate {
+- (instancetype)initWithToken:(NSString*)token
+ delegate:(id<GAEMessageHandler>)delegate {
+ NSParameterAssert([token length] > 0);
+ NSParameterAssert(delegate);
self = [super init];
if (self) {
#if TARGET_OS_IPHONE
@@ -69,7 +70,6 @@
NSURL* htmlUrl = [NSURL fileURLWithPath:htmlPath];
NSString* path = [NSString
stringWithFormat:@"%@?token=%@", [htmlUrl absoluteString], token];
-
#if TARGET_OS_IPHONE
[_webView
#else