diff options
author | tkchin@webrtc.org <tkchin@webrtc.org> | 2014-11-27 00:52:38 +0000 |
---|---|---|
committer | tkchin@webrtc.org <tkchin@webrtc.org> | 2014-11-27 00:52:38 +0000 |
commit | 3e9ad26112c5341aebf54ff8d43216acf7099063 (patch) | |
tree | eaedca294713cf640c0721e868408be8b3542947 /talk | |
parent | 79b9eba3abbf02f7a569280d8a735847ce09ec25 (diff) | |
download | webrtc-3e9ad26112c5341aebf54ff8d43216acf7099063.tar.gz |
Refactor iOS AppRTC parsing code.
Moved parsing code to JSON categories for the relevant objects.
No longer prefer ISAC as audio codec.
BUG=
R=glaznev@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/31989005
git-svn-id: http://webrtc.googlecode.com/svn/trunk@7755 4adac7df-926f-26a2-2b94-8c16560cd09d
Diffstat (limited to 'talk')
16 files changed, 734 insertions, 258 deletions
diff --git a/talk/examples/objc/AppRTCDemo/APPRTCAppClient.h b/talk/examples/objc/AppRTCDemo/APPRTCAppClient.h index 8b21db5858..880d5f8a48 100644 --- a/talk/examples/objc/AppRTCDemo/APPRTCAppClient.h +++ b/talk/examples/objc/AppRTCDemo/APPRTCAppClient.h @@ -27,6 +27,7 @@ #import <Foundation/Foundation.h> +#import "ARDSignalingParams.h" #import "GAEChannelClient.h" @class APPRTCAppClient; @@ -50,14 +51,13 @@ // for the registered handler to be called with received messages. @interface APPRTCAppClient : NSObject -@property(nonatomic) BOOL initiator; -@property(nonatomic, copy, readonly) RTCMediaConstraints* videoConstraints; +@property(nonatomic, readonly) ARDSignalingParams *params; @property(nonatomic, weak) id<APPRTCAppClientDelegate> delegate; - (instancetype)initWithDelegate:(id<APPRTCAppClientDelegate>)delegate messageHandler:(id<GAEMessageHandler>)handler; -- (void)connectToRoom:(NSURL*)room; -- (void)sendData:(NSData*)data; +- (void)connectToRoom:(NSURL *)room; +- (void)sendData:(NSData *)data; #ifndef DOXYGEN_SHOULD_SKIP_THIS // Disallow init and don't add to documentation diff --git a/talk/examples/objc/AppRTCDemo/APPRTCAppClient.m b/talk/examples/objc/AppRTCDemo/APPRTCAppClient.m index 853496f81b..20e708de35 100644 --- a/talk/examples/objc/AppRTCDemo/APPRTCAppClient.m +++ b/talk/examples/objc/AppRTCDemo/APPRTCAppClient.m @@ -33,8 +33,11 @@ #import <dispatch/dispatch.h> +#import "ARDSignalingParams.h" +#import "ARDUtilities.h" #import "GAEChannelClient.h" #import "RTCICEServer.h" +#import "RTCICEServer+JSON.h" #import "RTCMediaConstraints.h" #import "RTCPair.h" @@ -60,14 +63,15 @@ } - (void)connectToRoom:(NSURL*)url { - NSString* urlString = + 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) { + NSURL *requestURL = [NSURL URLWithString:urlString]; + NSURLRequest *request = [NSURLRequest requestWithURL:requestURL]; + [NSURLConnection sendAsynchronousRequest:request + completionHandler:^(NSURLResponse *response, + NSData *data, + NSError *error) { + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; int statusCode = [httpResponse statusCode]; [self logVerbose:[NSString stringWithFormat: @"Response received\nURL\n%@\nStatus [%d]\nHeaders\n%@", @@ -81,116 +85,74 @@ if (statusCode != 200) { return; } - [self handleResponseData:responseData - forRoomRequest:request]; + [self handleResponseData:data forRoomRequest:request]; }]; } - (void)sendData:(NSData*)data { NSParameterAssert([data length] > 0); - NSString* message = [NSString stringWithUTF8String:[data bytes]]; + NSString *message = [NSString stringWithUTF8String:[data bytes]]; [self logVerbose:[NSString stringWithFormat:@"Send message:\n%@", message]]; if (!_postMessageURL) { return; } - NSMutableURLRequest* request = + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:_postMessageURL]; request.HTTPMethod = @"POST"; [request setHTTPBody:data]; - [self sendURLRequest:request - completionHandler:^(NSError* error, - NSHTTPURLResponse* httpResponse, - NSData* responseData) { + [NSURLConnection sendAsynchronousRequest:request + completionHandler:^(NSURLResponse *response, + NSData *data, + NSError *error) { + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; int status = [httpResponse statusCode]; - NSString* response = [responseData length] > 0 ? - [NSString stringWithUTF8String:[responseData bytes]] : + NSString *responseString = [data length] > 0 ? + [NSString stringWithUTF8String:[data bytes]] : nil; NSAssert(status == 200, @"Bad response [%d] to message: %@\n\n%@", status, message, - response); + responseString); }]; } #pragma mark - Private -- (void)logVerbose:(NSString*)message { +- (void)logVerbose:(NSString *)message { if (_verboseLogging) { NSLog(@"%@", message); } } -- (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) { +- (void)handleResponseData:(NSData *)responseData + forRoomRequest:(NSURLRequest *)request { + ARDSignalingParams *params = + [ARDSignalingParams paramsFromJSONData:responseData]; + if (params.errorMessages.count > 0) { + NSMutableString *message = [NSMutableString string]; + for (NSString *errorMessage in params.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 requestTURNServerForICEServers:params.iceServers + turnServerUrl:[params.turnRequestURL absoluteString]]; + NSString *token = params.channelToken; [self logVerbose: [NSString stringWithFormat:@"About to open GAE with token: %@", token]]; _gaeChannel = [[GAEChannelClient alloc] initWithToken:token delegate:_messageHandler]; -} - -- (NSDictionary*)parseJSONData:(NSData*)data { - NSError* error = nil; - NSDictionary* json = - [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; - NSAssert(!error, @"Unable to parse. %@", error.localizedDescription); - 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]; - [result addObject:server]; - } - return result; + _params = params; + // Generate URL for posting data. + NSDictionary *roomJSON = [NSDictionary dictionaryWithJSONData:responseData]; + _postMessageURL = [self parsePostMessageURLForRoomJSON:roomJSON + request:request]; + [self logVerbose:[NSString stringWithFormat:@"POST message URL:\n%@", + _postMessageURL]]; } - (NSURL*)parsePostMessageURLForRoomJSON:(NSDictionary*)roomJSON @@ -207,63 +169,26 @@ return [NSURL URLWithString:postMessageUrl]; } -- (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 = - [NSMutableArray arrayWithCapacity:[mandatory count]]; - [mandatory enumerateKeysAndObjectsUsingBlock:^( - id key, id obj, BOOL* stop) { - [mandatoryContraints addObject:[[RTCPair alloc] initWithKey:key - value:obj]]; - }]; - // TODO(tkchin): figure out json formats for optional constraints. - constraints = - [[RTCMediaConstraints alloc] - initWithMandatoryConstraints:mandatoryContraints - optionalConstraints:nil]; - } else if ([video isKindOfClass:[NSNumber class]] && [video boolValue]) { - constraints = [[RTCMediaConstraints alloc] init]; - } - } - return constraints; -} - -- (void)requestTURNServerWithUrl:(NSString*)turnServerUrl +- (void)requestTURNServerWithUrl:(NSString *)turnServerUrl completionHandler: - (void (^)(RTCICEServer* turnServer))completionHandler { - NSURL* turnServerURL = [NSURL URLWithString:turnServerUrl]; - NSMutableURLRequest* request = + (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) { + [NSURLConnection sendAsynchronousRequest:request + completionHandler:^(NSURLResponse *response, + NSData *data, + NSError *error) { 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]; + NSDictionary *json = [NSDictionary dictionaryWithJSONData:data]; + RTCICEServer *turnServer = [RTCICEServer serverFromCEODJSONDictionary:json]; completionHandler(turnServer); }]; } @@ -295,26 +220,4 @@ } } -- (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/talk/examples/objc/AppRTCDemo/APPRTCConnectionManager.m b/talk/examples/objc/AppRTCDemo/APPRTCConnectionManager.m index 9a39528dff..9134e4dcb9 100644 --- a/talk/examples/objc/AppRTCDemo/APPRTCConnectionManager.m +++ b/talk/examples/objc/AppRTCDemo/APPRTCConnectionManager.m @@ -31,6 +31,7 @@ #import "APPRTCAppClient.h" #import "GAEChannelClient.h" #import "RTCICECandidate.h" +#import "RTCICECandidate+JSON.h" #import "RTCMediaConstraints.h" #import "RTCMediaStream.h" #import "RTCPair.h" @@ -38,6 +39,7 @@ #import "RTCPeerConnectionDelegate.h" #import "RTCPeerConnectionFactory.h" #import "RTCSessionDescription.h" +#import "RTCSessionDescription+JSON.h" #import "RTCSessionDescriptionDelegate.h" #import "RTCStatsDelegate.h" #import "RTCVideoCapturer.h" @@ -158,7 +160,7 @@ [RTCVideoCapturer capturerWithDeviceName:cameraID]; self.videoSource = [self.peerConnectionFactory videoSourceWithCapturer:capturer - constraints:self.client.videoConstraints]; + constraints:self.client.params.mediaConstraints]; localVideoTrack = [self.peerConnectionFactory videoTrackWithID:@"ARDAMSv0" source:self.videoSource]; @@ -177,7 +179,7 @@ #pragma mark - GAEMessageHandler methods - (void)onOpen { - if (!self.client.initiator) { + if (!self.client.params.isInitiator) { [self.logger logMessage:@"Callee; waiting for remote offer"]; return; } @@ -200,13 +202,8 @@ [self.logger logMessage:[NSString stringWithFormat:@"GAE onMessage type - %@", type]]; if ([type isEqualToString:@"candidate"]) { - NSString* mid = messageData[@"id"]; - NSNumber* sdpLineIndex = messageData[@"label"]; - NSString* sdp = messageData[@"candidate"]; RTCICECandidate* candidate = - [[RTCICECandidate alloc] initWithMid:mid - index:sdpLineIndex.intValue - sdp:sdp]; + [RTCICECandidate candidateFromJSONDictionary:messageData]; if (self.queuedRemoteCandidates) { [self.queuedRemoteCandidates addObject:candidate]; } else { @@ -214,10 +211,8 @@ } } else if ([type isEqualToString:@"offer"] || [type isEqualToString:@"answer"]) { - NSString* sdpString = messageData[@"sdp"]; - RTCSessionDescription* sdp = [[RTCSessionDescription alloc] - initWithType:type - sdp:[[self class] preferISAC:sdpString]]; + RTCSessionDescription* sdp = + [RTCSessionDescription descriptionFromJSONDictionary:messageData]; [self.peerConnection setRemoteDescriptionWithDelegate:self sessionDescription:sdp]; [self.logger logMessage:@"PC - setRemoteDescription."]; @@ -283,26 +278,8 @@ - (void)peerConnection:(RTCPeerConnection*)peerConnection gotICECandidate:(RTCICECandidate*)candidate { dispatch_async(dispatch_get_main_queue(), ^{ - NSLog(@"PCO onICECandidate.\n Mid[%@] Index[%li] Sdp[%@]", - candidate.sdpMid, - (long)candidate.sdpMLineIndex, - candidate.sdp); - NSDictionary* json = @{ - @"type" : @"candidate", - @"label" : @(candidate.sdpMLineIndex), - @"id" : candidate.sdpMid, - @"candidate" : candidate.sdp - }; - NSError* error; - NSData* data = - [NSJSONSerialization dataWithJSONObject:json options:0 error:&error]; - if (!error) { - [self.client sendData:data]; - } else { - NSAssert(NO, - @"Unable to serialize JSON object with error: %@", - error.localizedDescription); - } + NSLog(@"PCO onICECandidate.\n%@", candidate); + [self.client sendData:[candidate JSONData]]; }); } @@ -330,7 +307,7 @@ #pragma mark - RTCSessionDescriptionDelegate - (void)peerConnection:(RTCPeerConnection*)peerConnection - didCreateSessionDescription:(RTCSessionDescription*)origSdp + didCreateSessionDescription:(RTCSessionDescription*)sdp error:(NSError*)error { dispatch_async(dispatch_get_main_queue(), ^{ if (error) { @@ -339,19 +316,10 @@ return; } [self.logger logMessage:@"SDP onSuccess(SDP) - set local description."]; - RTCSessionDescription* sdp = [[RTCSessionDescription alloc] - initWithType:origSdp.type - sdp:[[self class] preferISAC:origSdp.description]]; [self.peerConnection setLocalDescriptionWithDelegate:self sessionDescription:sdp]; [self.logger logMessage:@"PC setLocalDescription."]; - NSDictionary* json = @{@"type" : sdp.type, @"sdp" : sdp.description}; - NSError* jsonError; - NSData* data = [NSJSONSerialization dataWithJSONObject:json - options:0 - error:&jsonError]; - NSAssert(!jsonError, @"Error: %@", jsonError.description); - [self.client sendData:data]; + [self.client sendData:[sdp JSONData]]; }); } @@ -364,7 +332,7 @@ return; } [self.logger logMessage:@"SDP onSuccess() - possibly drain candidates"]; - if (!self.client.initiator) { + if (!self.client.params.isInitiator) { if (self.peerConnection.remoteDescription && !self.peerConnection.localDescription) { [self.logger logMessage:@"Callee, setRemoteDescription succeeded"]; @@ -404,69 +372,6 @@ #pragma mark - Private -// Match |pattern| to |string| and return the first group of the first -// match, or nil if no match was found. -+ (NSString*)firstMatch:(NSRegularExpression*)pattern - withString:(NSString*)string { - NSTextCheckingResult* result = - [pattern firstMatchInString:string - options:0 - range:NSMakeRange(0, [string length])]; - if (!result) - return nil; - return [string substringWithRange:[result rangeAtIndex:1]]; -} - -// Mangle |origSDP| to prefer the ISAC/16k audio codec. -+ (NSString*)preferISAC:(NSString*)origSDP { - int mLineIndex = -1; - NSString* isac16kRtpMap = nil; - NSArray* lines = [origSDP componentsSeparatedByString:@"\n"]; - NSRegularExpression* isac16kRegex = [NSRegularExpression - regularExpressionWithPattern:@"^a=rtpmap:(\\d+) ISAC/16000[\r]?$" - options:0 - error:nil]; - for (int i = 0; - (i < [lines count]) && (mLineIndex == -1 || isac16kRtpMap == nil); - ++i) { - NSString* line = [lines objectAtIndex:i]; - if ([line hasPrefix:@"m=audio "]) { - mLineIndex = i; - continue; - } - isac16kRtpMap = [self firstMatch:isac16kRegex withString:line]; - } - if (mLineIndex == -1) { - NSLog(@"No m=audio line, so can't prefer iSAC"); - return origSDP; - } - if (isac16kRtpMap == nil) { - NSLog(@"No ISAC/16000 line, so can't prefer iSAC"); - return origSDP; - } - NSArray* origMLineParts = - [[lines objectAtIndex:mLineIndex] componentsSeparatedByString:@" "]; - NSMutableArray* newMLine = - [NSMutableArray arrayWithCapacity:[origMLineParts count]]; - int origPartIndex = 0; - // Format is: m=<media> <port> <proto> <fmt> ... - [newMLine addObject:[origMLineParts objectAtIndex:origPartIndex++]]; - [newMLine addObject:[origMLineParts objectAtIndex:origPartIndex++]]; - [newMLine addObject:[origMLineParts objectAtIndex:origPartIndex++]]; - [newMLine addObject:isac16kRtpMap]; - for (; origPartIndex < [origMLineParts count]; ++origPartIndex) { - if (![isac16kRtpMap - isEqualToString:[origMLineParts objectAtIndex:origPartIndex]]) { - [newMLine addObject:[origMLineParts objectAtIndex:origPartIndex]]; - } - } - NSMutableArray* newLines = [NSMutableArray arrayWithCapacity:[lines count]]; - [newLines addObjectsFromArray:lines]; - [newLines replaceObjectAtIndex:mLineIndex - withObject:[newMLine componentsJoinedByString:@" "]]; - return [newLines componentsJoinedByString:@"\n"]; -} - - (void)drainRemoteCandidates { for (RTCICECandidate* candidate in self.queuedRemoteCandidates) { [self.peerConnection addICECandidate:candidate]; diff --git a/talk/examples/objc/AppRTCDemo/ARDSignalingParams.h b/talk/examples/objc/AppRTCDemo/ARDSignalingParams.h new file mode 100644 index 0000000000..df2114c384 --- /dev/null +++ b/talk/examples/objc/AppRTCDemo/ARDSignalingParams.h @@ -0,0 +1,46 @@ +/* + * libjingle + * Copyright 2014, Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import <Foundation/Foundation.h> + +#import "RTCMediaConstraints.h" + +// Struct for holding the signaling parameters of an AppRTC room. +@interface ARDSignalingParams : NSObject + +@property(nonatomic, assign) BOOL isInitiator; +@property(nonatomic, readonly) NSArray *errorMessages; +@property(nonatomic, readonly) RTCMediaConstraints *offerConstraints; +@property(nonatomic, readonly) RTCMediaConstraints *mediaConstraints; +@property(nonatomic, readonly) NSMutableArray *iceServers; +@property(nonatomic, readonly) NSURL *signalingServerURL; +@property(nonatomic, readonly) NSURL *turnRequestURL; +@property(nonatomic, readonly) NSString *channelToken; + ++ (ARDSignalingParams *)paramsFromJSONData:(NSData *)data; + +@end diff --git a/talk/examples/objc/AppRTCDemo/ARDSignalingParams.m b/talk/examples/objc/AppRTCDemo/ARDSignalingParams.m new file mode 100644 index 0000000000..58c8684b8a --- /dev/null +++ b/talk/examples/objc/AppRTCDemo/ARDSignalingParams.m @@ -0,0 +1,130 @@ +/* + * libjingle + * Copyright 2014, Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "ARDSignalingParams.h" + +#import "ARDUtilities.h" +#import "RTCICEServer+JSON.h" +#import "RTCMediaConstraints+JSON.h" + +static NSString const *kARDSignalingParamsErrorKey = @"error"; +static NSString const *kARDSignalingParamsErrorMessagesKey = @"error_messages"; +static NSString const *kARDSignalingParamsInitiatorKey = @"initiator"; +static NSString const *kARDSignalingParamsPeerConnectionConfigKey = + @"pc_config"; +static NSString const *kARDSignalingParamsICEServersKey = @"iceServers"; +static NSString const *kARDSignalingParamsMediaConstraintsKey = + @"media_constraints"; +static NSString const *kARDSignalingParamsMediaConstraintsVideoKey = + @"video"; +static NSString const *kARDSignalingParamsTokenKey = @"token"; +static NSString const *kARDSignalingParamsTurnRequestUrlKey = @"turn_url"; + +@interface ARDSignalingParams () + +@property(nonatomic, strong) NSArray *errorMessages; +@property(nonatomic, strong) RTCMediaConstraints *offerConstraints; +@property(nonatomic, strong) RTCMediaConstraints *mediaConstraints; +@property(nonatomic, strong) NSMutableArray *iceServers; +@property(nonatomic, strong) NSURL *signalingServerURL; +@property(nonatomic, strong) NSURL *turnRequestURL; +@property(nonatomic, strong) NSString *channelToken; + +@end + +@implementation ARDSignalingParams + +@synthesize errorMessages = _errorMessages; +@synthesize isInitiator = _isInitiator; +@synthesize offerConstraints = _offerConstraints; +@synthesize mediaConstraints = _mediaConstraints; +@synthesize iceServers = _iceServers; +@synthesize signalingServerURL = _signalingServerURL; + ++ (ARDSignalingParams *)paramsFromJSONData:(NSData *)data { + NSDictionary *paramsJSON = [NSDictionary dictionaryWithJSONData:data]; + if (!paramsJSON) { + return nil; + } + ARDSignalingParams *params = [[ARDSignalingParams alloc] init]; + + // Parse errors. + BOOL hasError = NO; + NSArray *errorMessages = paramsJSON[kARDSignalingParamsErrorMessagesKey]; + if (errorMessages.count > 0) { + params.errorMessages = errorMessages; + return params; + } + + // Parse ICE servers. + NSString *peerConnectionConfigString = + paramsJSON[kARDSignalingParamsPeerConnectionConfigKey]; + NSDictionary *peerConnectionConfig = + [NSDictionary dictionaryWithJSONString:peerConnectionConfigString]; + NSArray *iceServerJSONArray = + peerConnectionConfig[kARDSignalingParamsICEServersKey]; + NSMutableArray *iceServers = [NSMutableArray array]; + for (NSDictionary *iceServerJSON in iceServerJSONArray) { + RTCICEServer *iceServer = + [RTCICEServer serverFromJSONDictionary:iceServerJSON]; + [iceServers addObject:iceServer]; + } + params.iceServers = iceServers; + + // Parse initiator. + BOOL isInitiator = [paramsJSON[kARDSignalingParamsInitiatorKey] boolValue]; + params.isInitiator = isInitiator; + + // Parse video constraints. + RTCMediaConstraints *videoConstraints = nil; + NSString *mediaConstraintsJSONString = + paramsJSON[kARDSignalingParamsMediaConstraintsKey]; + NSDictionary *mediaConstraintsJSON = + [NSDictionary dictionaryWithJSONString:mediaConstraintsJSONString]; + id videoJSON = + mediaConstraintsJSON[kARDSignalingParamsMediaConstraintsVideoKey]; + if ([videoJSON isKindOfClass:[NSDictionary class]]) { + videoConstraints = + [RTCMediaConstraints constraintsFromJSONDictionary:videoJSON]; + } else if ([videoJSON isKindOfClass:[NSNumber class]] && + [videoJSON boolValue]) { + videoConstraints = [[RTCMediaConstraints alloc] init]; + } + params.mediaConstraints = videoConstraints; + + // Parse channel token. + NSString *token = paramsJSON[kARDSignalingParamsTokenKey]; + params.channelToken = token; + + // Parse turn request url. + params.turnRequestURL = + [NSURL URLWithString:paramsJSON[kARDSignalingParamsTurnRequestUrlKey]]; + + return params; +} + +@end diff --git a/talk/examples/objc/AppRTCDemo/ARDUtilities.h b/talk/examples/objc/AppRTCDemo/ARDUtilities.h new file mode 100644 index 0000000000..ca4d1d7304 --- /dev/null +++ b/talk/examples/objc/AppRTCDemo/ARDUtilities.h @@ -0,0 +1,46 @@ +/* + * libjingle + * Copyright 2014, Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import <Foundation/Foundation.h> + +@interface NSDictionary (ARDUtilites) + +// Creates a dictionary with the keys and values in the JSON object. ++ (NSDictionary *)dictionaryWithJSONString:(NSString *)jsonString; ++ (NSDictionary *)dictionaryWithJSONData:(NSData *)jsonData; + +@end + +@interface NSURLConnection (ARDUtilities) + +// Issues an asynchronous request that calls back on main queue. ++ (void)sendAsynchronousRequest:(NSURLRequest *)request + completionHandler:(void (^)(NSURLResponse *response, + NSData *data, + NSError *error))completionHandler; + +@end diff --git a/talk/examples/objc/AppRTCDemo/ARDUtilities.m b/talk/examples/objc/AppRTCDemo/ARDUtilities.m new file mode 100644 index 0000000000..937013ea65 --- /dev/null +++ b/talk/examples/objc/AppRTCDemo/ARDUtilities.m @@ -0,0 +1,72 @@ +/* + * libjingle + * Copyright 2014, Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "ARDUtilities.h" + +@implementation NSDictionary (ARDUtilites) + ++ (NSDictionary *)dictionaryWithJSONString:(NSString *)jsonString { + NSParameterAssert(jsonString.length > 0); + NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; + NSError *error = nil; + NSDictionary *dict = + [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; + if (error) { + NSLog(@"Error parsing JSON: %@", error.localizedDescription); + } + return dict; +} + ++ (NSDictionary *)dictionaryWithJSONData:(NSData *)jsonData { + NSError *error = nil; + NSDictionary *dict = + [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error]; + if (error) { + NSLog(@"Error parsing JSON: %@", error.localizedDescription); + } + return dict; +} + +@end + +@implementation NSURLConnection (ARDUtilities) + ++ (void)sendAsynchronousRequest:(NSURLRequest *)request + completionHandler:(void (^)(NSURLResponse *response, + NSData *data, + NSError *error))completionHandler { + // Kick off an async request which will call back on main thread. + [NSURLConnection sendAsynchronousRequest:request + queue:[NSOperationQueue mainQueue] + completionHandler:^(NSURLResponse *response, + NSData *data, + NSError *error) { + completionHandler(response, data, error); + }]; +} + +@end diff --git a/talk/examples/objc/AppRTCDemo/RTCICECandidate+JSON.h b/talk/examples/objc/AppRTCDemo/RTCICECandidate+JSON.h new file mode 100644 index 0000000000..f0673cdb0a --- /dev/null +++ b/talk/examples/objc/AppRTCDemo/RTCICECandidate+JSON.h @@ -0,0 +1,35 @@ +/* + * libjingle + * Copyright 2014, Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "RTCICECandidate.h" + +@interface RTCICECandidate (JSON) + ++ (RTCICECandidate *)candidateFromJSONDictionary:(NSDictionary *)dictionary; +- (NSData *)JSONData; + +@end diff --git a/talk/examples/objc/AppRTCDemo/RTCICECandidate+JSON.m b/talk/examples/objc/AppRTCDemo/RTCICECandidate+JSON.m new file mode 100644 index 0000000000..62817a5fed --- /dev/null +++ b/talk/examples/objc/AppRTCDemo/RTCICECandidate+JSON.m @@ -0,0 +1,56 @@ +/* + * libjingle + * Copyright 2014, Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "RTCICECandidate+JSON.h" + +static NSString const *kRTCICECandidateTypeKey = @"type"; +static NSString const *kRTCICECandidateTypeValue = @"candidate"; +static NSString const *kRTCICECandidateMidKey = @"id"; +static NSString const *kRTCICECandidateMLineIndexKey = @"label"; +static NSString const *kRTCICECandidateSdpKey = @"candidate"; + +@implementation RTCICECandidate (JSON) + ++ (RTCICECandidate *)candidateFromJSONDictionary:(NSDictionary *)dictionary { + NSString *mid = dictionary[kRTCICECandidateMidKey]; + NSString *sdp = dictionary[kRTCICECandidateSdpKey]; + NSNumber *num = dictionary[kRTCICECandidateMLineIndexKey]; + NSInteger mLineIndex = [num integerValue]; + return [[RTCICECandidate alloc] initWithMid:mid index:mLineIndex sdp:sdp]; +} + +- (NSData *)JSONData { + NSDictionary *json = @{ + kRTCICECandidateTypeKey : kRTCICECandidateTypeValue, + kRTCICECandidateMLineIndexKey : @(self.sdpMLineIndex), + kRTCICECandidateMidKey : self.sdpMid, + kRTCICECandidateSdpKey : self.sdp + }; + return [NSJSONSerialization dataWithJSONObject:json options:0 error:nil]; +} + +@end diff --git a/talk/examples/objc/AppRTCDemo/RTCICEServer+JSON.h b/talk/examples/objc/AppRTCDemo/RTCICEServer+JSON.h new file mode 100644 index 0000000000..d8a72076ca --- /dev/null +++ b/talk/examples/objc/AppRTCDemo/RTCICEServer+JSON.h @@ -0,0 +1,36 @@ +/* + * libjingle + * Copyright 2014, Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "RTCICEServer.h" + +@interface RTCICEServer (JSON) + ++ (RTCICEServer *)serverFromJSONDictionary:(NSDictionary *)dictionary; +// CEOD provides different JSON, and this parses that. ++ (RTCICEServer *)serverFromCEODJSONDictionary:(NSDictionary *)dictionary; + +@end diff --git a/talk/examples/objc/AppRTCDemo/RTCICEServer+JSON.m b/talk/examples/objc/AppRTCDemo/RTCICEServer+JSON.m new file mode 100644 index 0000000000..29321f65ff --- /dev/null +++ b/talk/examples/objc/AppRTCDemo/RTCICEServer+JSON.m @@ -0,0 +1,59 @@ +/* + * libjingle + * Copyright 2014, Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "RTCICEServer+JSON.h" + +static NSString const *kRTCICEServerUsernameKey = @"username"; +static NSString const *kRTCICEServerPasswordKey = @"password"; +static NSString const *kRTCICEServerUrisKey = @"uris"; +static NSString const *kRTCICEServerUrlKey = @"urls"; +static NSString const *kRTCICEServerCredentialKey = @"credential"; + +@implementation RTCICEServer (JSON) + ++ (RTCICEServer *)serverFromJSONDictionary:(NSDictionary *)dictionary { + NSString *url = dictionary[kRTCICEServerUrlKey]; + NSString *username = dictionary[kRTCICEServerUsernameKey]; + NSString *credential = dictionary[kRTCICEServerCredentialKey]; + username = username ? username : @""; + credential = credential ? credential : @""; + return [[RTCICEServer alloc] initWithURI:[NSURL URLWithString:url] + username:username + password:credential]; +} + ++ (RTCICEServer *)serverFromCEODJSONDictionary:(NSDictionary *)dictionary { + NSString *username = dictionary[kRTCICEServerUsernameKey]; + NSString *password = dictionary[kRTCICEServerPasswordKey]; + NSArray *uris = dictionary[kRTCICEServerUrisKey]; + NSParameterAssert(uris.count > 0); + return [[RTCICEServer alloc] initWithURI:[NSURL URLWithString:uris[0]] + username:username + password:password]; +} + +@end diff --git a/talk/examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.h b/talk/examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.h new file mode 100644 index 0000000000..c0c660f350 --- /dev/null +++ b/talk/examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.h @@ -0,0 +1,36 @@ +/* + * libjingle + * Copyright 2014, Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "RTCMediaConstraints.h" + +@interface RTCMediaConstraints (JSON) + ++ (RTCMediaConstraints *)constraintsFromJSONDictionary: + (NSDictionary *)dictionary; + +@end + diff --git a/talk/examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.m b/talk/examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.m new file mode 100644 index 0000000000..6588eb94aa --- /dev/null +++ b/talk/examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.m @@ -0,0 +1,54 @@ +/* + * libjingle + * Copyright 2014, Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "RTCMediaConstraints+JSON.h" + +#import "RTCPair.h" + +static NSString const *kRTCMediaConstraintsMandatoryKey = @"mandatory"; + +@implementation RTCMediaConstraints (JSON) + ++ (RTCMediaConstraints *)constraintsFromJSONDictionary: + (NSDictionary *)dictionary { + NSDictionary *mandatory = dictionary[kRTCMediaConstraintsMandatoryKey]; + NSMutableArray *mandatoryContraints = + [NSMutableArray arrayWithCapacity:[mandatory count]]; + [mandatory enumerateKeysAndObjectsUsingBlock:^( + id key, id obj, BOOL *stop) { + [mandatoryContraints addObject:[[RTCPair alloc] initWithKey:key + value:obj]]; + }]; + // TODO(tkchin): figure out json formats for optional constraints. + RTCMediaConstraints *constraints = + [[RTCMediaConstraints alloc] + initWithMandatoryConstraints:mandatoryContraints + optionalConstraints:nil]; + return constraints; +} + +@end diff --git a/talk/examples/objc/AppRTCDemo/RTCSessionDescription+JSON.h b/talk/examples/objc/AppRTCDemo/RTCSessionDescription+JSON.h new file mode 100644 index 0000000000..2c18d25e4f --- /dev/null +++ b/talk/examples/objc/AppRTCDemo/RTCSessionDescription+JSON.h @@ -0,0 +1,36 @@ +/* + * libjingle + * Copyright 2014, Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "RTCSessionDescription.h" + +@interface RTCSessionDescription (JSON) + ++ (RTCSessionDescription *)descriptionFromJSONDictionary: + (NSDictionary *)dictionary; +- (NSData *)JSONData; + +@end diff --git a/talk/examples/objc/AppRTCDemo/RTCSessionDescription+JSON.m b/talk/examples/objc/AppRTCDemo/RTCSessionDescription+JSON.m new file mode 100644 index 0000000000..0c1d39cddd --- /dev/null +++ b/talk/examples/objc/AppRTCDemo/RTCSessionDescription+JSON.m @@ -0,0 +1,50 @@ +/* + * libjingle + * Copyright 2014, Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "RTCSessionDescription+JSON.h" + +static NSString const *kRTCSessionDescriptionTypeKey = @"type"; +static NSString const *kRTCSessionDescriptionSdpKey = @"sdp"; + +@implementation RTCSessionDescription (JSON) + ++ (RTCSessionDescription *)descriptionFromJSONDictionary: + (NSDictionary *)dictionary { + NSString *type = dictionary[kRTCSessionDescriptionTypeKey]; + NSString *sdp = dictionary[kRTCSessionDescriptionSdpKey]; + return [[RTCSessionDescription alloc] initWithType:type sdp:sdp]; +} + +- (NSData *)JSONData { + NSDictionary *json = @{ + kRTCSessionDescriptionTypeKey : self.type, + kRTCSessionDescriptionSdpKey : self.description + }; + return [NSJSONSerialization dataWithJSONObject:json options:0 error:nil]; +} + +@end diff --git a/talk/libjingle_examples.gyp b/talk/libjingle_examples.gyp index 740452d183..f17fbfe7a4 100755 --- a/talk/libjingle_examples.gyp +++ b/talk/libjingle_examples.gyp @@ -283,8 +283,20 @@ 'examples/objc/AppRTCDemo/APPRTCAppClient.m', 'examples/objc/AppRTCDemo/APPRTCConnectionManager.h', 'examples/objc/AppRTCDemo/APPRTCConnectionManager.m', + 'examples/objc/AppRTCDemo/ARDSignalingParams.h', + 'examples/objc/AppRTCDemo/ARDSignalingParams.m', + 'examples/objc/AppRTCDemo/ARDUtilities.h', + 'examples/objc/AppRTCDemo/ARDUtilities.m', 'examples/objc/AppRTCDemo/GAEChannelClient.h', 'examples/objc/AppRTCDemo/GAEChannelClient.m', + 'examples/objc/AppRTCDemo/RTCICECandidate+JSON.h', + 'examples/objc/AppRTCDemo/RTCICECandidate+JSON.m', + 'examples/objc/AppRTCDemo/RTCICEServer+JSON.h', + 'examples/objc/AppRTCDemo/RTCICEServer+JSON.m', + 'examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.h', + 'examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.m', + 'examples/objc/AppRTCDemo/RTCSessionDescription+JSON.h', + 'examples/objc/AppRTCDemo/RTCSessionDescription+JSON.m', ], 'xcode_settings': { 'CLANG_ENABLE_OBJC_ARC': 'YES', |