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
This commit is contained in:
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import "ARDSignalingParams.h"
|
||||||
#import "GAEChannelClient.h"
|
#import "GAEChannelClient.h"
|
||||||
|
|
||||||
@class APPRTCAppClient;
|
@class APPRTCAppClient;
|
||||||
@@ -50,14 +51,13 @@
|
|||||||
// for the registered handler to be called with received messages.
|
// for the registered handler to be called with received messages.
|
||||||
@interface APPRTCAppClient : NSObject
|
@interface APPRTCAppClient : NSObject
|
||||||
|
|
||||||
@property(nonatomic) BOOL initiator;
|
@property(nonatomic, readonly) ARDSignalingParams *params;
|
||||||
@property(nonatomic, copy, readonly) RTCMediaConstraints* videoConstraints;
|
|
||||||
@property(nonatomic, weak) id<APPRTCAppClientDelegate> delegate;
|
@property(nonatomic, weak) id<APPRTCAppClientDelegate> delegate;
|
||||||
|
|
||||||
- (instancetype)initWithDelegate:(id<APPRTCAppClientDelegate>)delegate
|
- (instancetype)initWithDelegate:(id<APPRTCAppClientDelegate>)delegate
|
||||||
messageHandler:(id<GAEMessageHandler>)handler;
|
messageHandler:(id<GAEMessageHandler>)handler;
|
||||||
- (void)connectToRoom:(NSURL*)room;
|
- (void)connectToRoom:(NSURL *)room;
|
||||||
- (void)sendData:(NSData*)data;
|
- (void)sendData:(NSData *)data;
|
||||||
|
|
||||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||||
// Disallow init and don't add to documentation
|
// Disallow init and don't add to documentation
|
||||||
|
@@ -33,8 +33,11 @@
|
|||||||
|
|
||||||
#import <dispatch/dispatch.h>
|
#import <dispatch/dispatch.h>
|
||||||
|
|
||||||
|
#import "ARDSignalingParams.h"
|
||||||
|
#import "ARDUtilities.h"
|
||||||
#import "GAEChannelClient.h"
|
#import "GAEChannelClient.h"
|
||||||
#import "RTCICEServer.h"
|
#import "RTCICEServer.h"
|
||||||
|
#import "RTCICEServer+JSON.h"
|
||||||
#import "RTCMediaConstraints.h"
|
#import "RTCMediaConstraints.h"
|
||||||
#import "RTCPair.h"
|
#import "RTCPair.h"
|
||||||
|
|
||||||
@@ -60,14 +63,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)connectToRoom:(NSURL*)url {
|
- (void)connectToRoom:(NSURL*)url {
|
||||||
NSString* urlString =
|
NSString *urlString =
|
||||||
[[url absoluteString] stringByAppendingString:@"&t=json"];
|
[[url absoluteString] stringByAppendingString:@"&t=json"];
|
||||||
NSURL* requestURL = [NSURL URLWithString:urlString];
|
NSURL *requestURL = [NSURL URLWithString:urlString];
|
||||||
NSURLRequest* request = [NSURLRequest requestWithURL:requestURL];
|
NSURLRequest *request = [NSURLRequest requestWithURL:requestURL];
|
||||||
[self sendURLRequest:request
|
[NSURLConnection sendAsynchronousRequest:request
|
||||||
completionHandler:^(NSError* error,
|
completionHandler:^(NSURLResponse *response,
|
||||||
NSHTTPURLResponse* httpResponse,
|
NSData *data,
|
||||||
NSData* responseData) {
|
NSError *error) {
|
||||||
|
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
|
||||||
int statusCode = [httpResponse statusCode];
|
int statusCode = [httpResponse statusCode];
|
||||||
[self logVerbose:[NSString stringWithFormat:
|
[self logVerbose:[NSString stringWithFormat:
|
||||||
@"Response received\nURL\n%@\nStatus [%d]\nHeaders\n%@",
|
@"Response received\nURL\n%@\nStatus [%d]\nHeaders\n%@",
|
||||||
@@ -81,116 +85,74 @@
|
|||||||
if (statusCode != 200) {
|
if (statusCode != 200) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
[self handleResponseData:responseData
|
[self handleResponseData:data forRoomRequest:request];
|
||||||
forRoomRequest:request];
|
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)sendData:(NSData*)data {
|
- (void)sendData:(NSData*)data {
|
||||||
NSParameterAssert([data length] > 0);
|
NSParameterAssert([data length] > 0);
|
||||||
NSString* message = [NSString stringWithUTF8String:[data bytes]];
|
NSString *message = [NSString stringWithUTF8String:[data bytes]];
|
||||||
[self logVerbose:[NSString stringWithFormat:@"Send message:\n%@", message]];
|
[self logVerbose:[NSString stringWithFormat:@"Send message:\n%@", message]];
|
||||||
if (!_postMessageURL) {
|
if (!_postMessageURL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NSMutableURLRequest* request =
|
NSMutableURLRequest *request =
|
||||||
[NSMutableURLRequest requestWithURL:_postMessageURL];
|
[NSMutableURLRequest requestWithURL:_postMessageURL];
|
||||||
request.HTTPMethod = @"POST";
|
request.HTTPMethod = @"POST";
|
||||||
[request setHTTPBody:data];
|
[request setHTTPBody:data];
|
||||||
[self sendURLRequest:request
|
[NSURLConnection sendAsynchronousRequest:request
|
||||||
completionHandler:^(NSError* error,
|
completionHandler:^(NSURLResponse *response,
|
||||||
NSHTTPURLResponse* httpResponse,
|
NSData *data,
|
||||||
NSData* responseData) {
|
NSError *error) {
|
||||||
|
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
|
||||||
int status = [httpResponse statusCode];
|
int status = [httpResponse statusCode];
|
||||||
NSString* response = [responseData length] > 0 ?
|
NSString *responseString = [data length] > 0 ?
|
||||||
[NSString stringWithUTF8String:[responseData bytes]] :
|
[NSString stringWithUTF8String:[data bytes]] :
|
||||||
nil;
|
nil;
|
||||||
NSAssert(status == 200,
|
NSAssert(status == 200,
|
||||||
@"Bad response [%d] to message: %@\n\n%@",
|
@"Bad response [%d] to message: %@\n\n%@",
|
||||||
status,
|
status,
|
||||||
message,
|
message,
|
||||||
response);
|
responseString);
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Private
|
#pragma mark - Private
|
||||||
|
|
||||||
- (void)logVerbose:(NSString*)message {
|
- (void)logVerbose:(NSString *)message {
|
||||||
if (_verboseLogging) {
|
if (_verboseLogging) {
|
||||||
NSLog(@"%@", message);
|
NSLog(@"%@", message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)handleResponseData:(NSData*)responseData
|
- (void)handleResponseData:(NSData *)responseData
|
||||||
forRoomRequest:(NSURLRequest*)request {
|
forRoomRequest:(NSURLRequest *)request {
|
||||||
NSDictionary* roomJSON = [self parseJSONData:responseData];
|
ARDSignalingParams *params =
|
||||||
[self logVerbose:[NSString stringWithFormat:@"Room JSON:\n%@", roomJSON]];
|
[ARDSignalingParams paramsFromJSONData:responseData];
|
||||||
NSParameterAssert(roomJSON);
|
if (params.errorMessages.count > 0) {
|
||||||
if (roomJSON[@"error"]) {
|
NSMutableString *message = [NSMutableString string];
|
||||||
NSArray* errorMessages = roomJSON[@"error_messages"];
|
for (NSString *errorMessage in params.errorMessages) {
|
||||||
NSMutableString* message = [NSMutableString string];
|
|
||||||
for (NSString* errorMessage in errorMessages) {
|
|
||||||
[message appendFormat:@"%@\n", errorMessage];
|
[message appendFormat:@"%@\n", errorMessage];
|
||||||
}
|
}
|
||||||
[self.delegate appClient:self didErrorWithMessage:message];
|
[self.delegate appClient:self didErrorWithMessage:message];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NSString* pcConfig = roomJSON[@"pc_config"];
|
[self requestTURNServerForICEServers:params.iceServers
|
||||||
NSData* pcConfigData = [pcConfig dataUsingEncoding:NSUTF8StringEncoding];
|
turnServerUrl:[params.turnRequestURL absoluteString]];
|
||||||
NSDictionary* pcConfigJSON = [self parseJSONData:pcConfigData];
|
NSString *token = params.channelToken;
|
||||||
[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:
|
[self logVerbose:
|
||||||
[NSString stringWithFormat:@"About to open GAE with token: %@",
|
[NSString stringWithFormat:@"About to open GAE with token: %@",
|
||||||
token]];
|
token]];
|
||||||
_gaeChannel =
|
_gaeChannel =
|
||||||
[[GAEChannelClient alloc] initWithToken:token
|
[[GAEChannelClient alloc] initWithToken:token
|
||||||
delegate:_messageHandler];
|
delegate:_messageHandler];
|
||||||
}
|
_params = params;
|
||||||
|
// Generate URL for posting data.
|
||||||
- (NSDictionary*)parseJSONData:(NSData*)data {
|
NSDictionary *roomJSON = [NSDictionary dictionaryWithJSONData:responseData];
|
||||||
NSError* error = nil;
|
_postMessageURL = [self parsePostMessageURLForRoomJSON:roomJSON
|
||||||
NSDictionary* json =
|
request:request];
|
||||||
[NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
|
[self logVerbose:[NSString stringWithFormat:@"POST message URL:\n%@",
|
||||||
NSAssert(!error, @"Unable to parse. %@", error.localizedDescription);
|
_postMessageURL]];
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSURL*)parsePostMessageURLForRoomJSON:(NSDictionary*)roomJSON
|
- (NSURL*)parsePostMessageURLForRoomJSON:(NSDictionary*)roomJSON
|
||||||
@@ -207,63 +169,26 @@
|
|||||||
return [NSURL URLWithString:postMessageUrl];
|
return [NSURL URLWithString:postMessageUrl];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (RTCMediaConstraints*)parseVideoConstraintsForRoomJSON:
|
- (void)requestTURNServerWithUrl:(NSString *)turnServerUrl
|
||||||
(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
|
|
||||||
completionHandler:
|
completionHandler:
|
||||||
(void (^)(RTCICEServer* turnServer))completionHandler {
|
(void (^)(RTCICEServer *turnServer))completionHandler {
|
||||||
NSURL* turnServerURL = [NSURL URLWithString:turnServerUrl];
|
NSURL *turnServerURL = [NSURL URLWithString:turnServerUrl];
|
||||||
NSMutableURLRequest* request =
|
NSMutableURLRequest *request =
|
||||||
[NSMutableURLRequest requestWithURL:turnServerURL];
|
[NSMutableURLRequest requestWithURL:turnServerURL];
|
||||||
[request addValue:@"Mozilla/5.0" forHTTPHeaderField:@"user-agent"];
|
[request addValue:@"Mozilla/5.0" forHTTPHeaderField:@"user-agent"];
|
||||||
[request addValue:@"https://apprtc.appspot.com"
|
[request addValue:@"https://apprtc.appspot.com"
|
||||||
forHTTPHeaderField:@"origin"];
|
forHTTPHeaderField:@"origin"];
|
||||||
[self sendURLRequest:request
|
[NSURLConnection sendAsynchronousRequest:request
|
||||||
completionHandler:^(NSError* error,
|
completionHandler:^(NSURLResponse *response,
|
||||||
NSHTTPURLResponse* response,
|
NSData *data,
|
||||||
NSData* responseData) {
|
NSError *error) {
|
||||||
if (error) {
|
if (error) {
|
||||||
NSLog(@"Unable to get TURN server.");
|
NSLog(@"Unable to get TURN server.");
|
||||||
completionHandler(nil);
|
completionHandler(nil);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NSDictionary* json = [self parseJSONData:responseData];
|
NSDictionary *json = [NSDictionary dictionaryWithJSONData:data];
|
||||||
NSString* username = json[@"username"];
|
RTCICEServer *turnServer = [RTCICEServer serverFromCEODJSONDictionary:json];
|
||||||
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);
|
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
|
@end
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
#import "APPRTCAppClient.h"
|
#import "APPRTCAppClient.h"
|
||||||
#import "GAEChannelClient.h"
|
#import "GAEChannelClient.h"
|
||||||
#import "RTCICECandidate.h"
|
#import "RTCICECandidate.h"
|
||||||
|
#import "RTCICECandidate+JSON.h"
|
||||||
#import "RTCMediaConstraints.h"
|
#import "RTCMediaConstraints.h"
|
||||||
#import "RTCMediaStream.h"
|
#import "RTCMediaStream.h"
|
||||||
#import "RTCPair.h"
|
#import "RTCPair.h"
|
||||||
@@ -38,6 +39,7 @@
|
|||||||
#import "RTCPeerConnectionDelegate.h"
|
#import "RTCPeerConnectionDelegate.h"
|
||||||
#import "RTCPeerConnectionFactory.h"
|
#import "RTCPeerConnectionFactory.h"
|
||||||
#import "RTCSessionDescription.h"
|
#import "RTCSessionDescription.h"
|
||||||
|
#import "RTCSessionDescription+JSON.h"
|
||||||
#import "RTCSessionDescriptionDelegate.h"
|
#import "RTCSessionDescriptionDelegate.h"
|
||||||
#import "RTCStatsDelegate.h"
|
#import "RTCStatsDelegate.h"
|
||||||
#import "RTCVideoCapturer.h"
|
#import "RTCVideoCapturer.h"
|
||||||
@@ -158,7 +160,7 @@
|
|||||||
[RTCVideoCapturer capturerWithDeviceName:cameraID];
|
[RTCVideoCapturer capturerWithDeviceName:cameraID];
|
||||||
self.videoSource = [self.peerConnectionFactory
|
self.videoSource = [self.peerConnectionFactory
|
||||||
videoSourceWithCapturer:capturer
|
videoSourceWithCapturer:capturer
|
||||||
constraints:self.client.videoConstraints];
|
constraints:self.client.params.mediaConstraints];
|
||||||
localVideoTrack =
|
localVideoTrack =
|
||||||
[self.peerConnectionFactory videoTrackWithID:@"ARDAMSv0"
|
[self.peerConnectionFactory videoTrackWithID:@"ARDAMSv0"
|
||||||
source:self.videoSource];
|
source:self.videoSource];
|
||||||
@@ -177,7 +179,7 @@
|
|||||||
#pragma mark - GAEMessageHandler methods
|
#pragma mark - GAEMessageHandler methods
|
||||||
|
|
||||||
- (void)onOpen {
|
- (void)onOpen {
|
||||||
if (!self.client.initiator) {
|
if (!self.client.params.isInitiator) {
|
||||||
[self.logger logMessage:@"Callee; waiting for remote offer"];
|
[self.logger logMessage:@"Callee; waiting for remote offer"];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -200,13 +202,8 @@
|
|||||||
[self.logger logMessage:[NSString stringWithFormat:@"GAE onMessage type - %@",
|
[self.logger logMessage:[NSString stringWithFormat:@"GAE onMessage type - %@",
|
||||||
type]];
|
type]];
|
||||||
if ([type isEqualToString:@"candidate"]) {
|
if ([type isEqualToString:@"candidate"]) {
|
||||||
NSString* mid = messageData[@"id"];
|
|
||||||
NSNumber* sdpLineIndex = messageData[@"label"];
|
|
||||||
NSString* sdp = messageData[@"candidate"];
|
|
||||||
RTCICECandidate* candidate =
|
RTCICECandidate* candidate =
|
||||||
[[RTCICECandidate alloc] initWithMid:mid
|
[RTCICECandidate candidateFromJSONDictionary:messageData];
|
||||||
index:sdpLineIndex.intValue
|
|
||||||
sdp:sdp];
|
|
||||||
if (self.queuedRemoteCandidates) {
|
if (self.queuedRemoteCandidates) {
|
||||||
[self.queuedRemoteCandidates addObject:candidate];
|
[self.queuedRemoteCandidates addObject:candidate];
|
||||||
} else {
|
} else {
|
||||||
@@ -214,10 +211,8 @@
|
|||||||
}
|
}
|
||||||
} else if ([type isEqualToString:@"offer"] ||
|
} else if ([type isEqualToString:@"offer"] ||
|
||||||
[type isEqualToString:@"answer"]) {
|
[type isEqualToString:@"answer"]) {
|
||||||
NSString* sdpString = messageData[@"sdp"];
|
RTCSessionDescription* sdp =
|
||||||
RTCSessionDescription* sdp = [[RTCSessionDescription alloc]
|
[RTCSessionDescription descriptionFromJSONDictionary:messageData];
|
||||||
initWithType:type
|
|
||||||
sdp:[[self class] preferISAC:sdpString]];
|
|
||||||
[self.peerConnection setRemoteDescriptionWithDelegate:self
|
[self.peerConnection setRemoteDescriptionWithDelegate:self
|
||||||
sessionDescription:sdp];
|
sessionDescription:sdp];
|
||||||
[self.logger logMessage:@"PC - setRemoteDescription."];
|
[self.logger logMessage:@"PC - setRemoteDescription."];
|
||||||
@@ -283,26 +278,8 @@
|
|||||||
- (void)peerConnection:(RTCPeerConnection*)peerConnection
|
- (void)peerConnection:(RTCPeerConnection*)peerConnection
|
||||||
gotICECandidate:(RTCICECandidate*)candidate {
|
gotICECandidate:(RTCICECandidate*)candidate {
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
NSLog(@"PCO onICECandidate.\n Mid[%@] Index[%li] Sdp[%@]",
|
NSLog(@"PCO onICECandidate.\n%@", candidate);
|
||||||
candidate.sdpMid,
|
[self.client sendData:[candidate JSONData]];
|
||||||
(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);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,7 +307,7 @@
|
|||||||
#pragma mark - RTCSessionDescriptionDelegate
|
#pragma mark - RTCSessionDescriptionDelegate
|
||||||
|
|
||||||
- (void)peerConnection:(RTCPeerConnection*)peerConnection
|
- (void)peerConnection:(RTCPeerConnection*)peerConnection
|
||||||
didCreateSessionDescription:(RTCSessionDescription*)origSdp
|
didCreateSessionDescription:(RTCSessionDescription*)sdp
|
||||||
error:(NSError*)error {
|
error:(NSError*)error {
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
if (error) {
|
if (error) {
|
||||||
@@ -339,19 +316,10 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
[self.logger logMessage:@"SDP onSuccess(SDP) - set local description."];
|
[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
|
[self.peerConnection setLocalDescriptionWithDelegate:self
|
||||||
sessionDescription:sdp];
|
sessionDescription:sdp];
|
||||||
[self.logger logMessage:@"PC setLocalDescription."];
|
[self.logger logMessage:@"PC setLocalDescription."];
|
||||||
NSDictionary* json = @{@"type" : sdp.type, @"sdp" : sdp.description};
|
[self.client sendData:[sdp JSONData]];
|
||||||
NSError* jsonError;
|
|
||||||
NSData* data = [NSJSONSerialization dataWithJSONObject:json
|
|
||||||
options:0
|
|
||||||
error:&jsonError];
|
|
||||||
NSAssert(!jsonError, @"Error: %@", jsonError.description);
|
|
||||||
[self.client sendData:data];
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,7 +332,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
[self.logger logMessage:@"SDP onSuccess() - possibly drain candidates"];
|
[self.logger logMessage:@"SDP onSuccess() - possibly drain candidates"];
|
||||||
if (!self.client.initiator) {
|
if (!self.client.params.isInitiator) {
|
||||||
if (self.peerConnection.remoteDescription &&
|
if (self.peerConnection.remoteDescription &&
|
||||||
!self.peerConnection.localDescription) {
|
!self.peerConnection.localDescription) {
|
||||||
[self.logger logMessage:@"Callee, setRemoteDescription succeeded"];
|
[self.logger logMessage:@"Callee, setRemoteDescription succeeded"];
|
||||||
@@ -404,69 +372,6 @@
|
|||||||
|
|
||||||
#pragma mark - Private
|
#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 {
|
- (void)drainRemoteCandidates {
|
||||||
for (RTCICECandidate* candidate in self.queuedRemoteCandidates) {
|
for (RTCICECandidate* candidate in self.queuedRemoteCandidates) {
|
||||||
[self.peerConnection addICECandidate:candidate];
|
[self.peerConnection addICECandidate:candidate];
|
||||||
|
46
talk/examples/objc/AppRTCDemo/ARDSignalingParams.h
Normal file
46
talk/examples/objc/AppRTCDemo/ARDSignalingParams.h
Normal file
@@ -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
|
130
talk/examples/objc/AppRTCDemo/ARDSignalingParams.m
Normal file
130
talk/examples/objc/AppRTCDemo/ARDSignalingParams.m
Normal file
@@ -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
|
46
talk/examples/objc/AppRTCDemo/ARDUtilities.h
Normal file
46
talk/examples/objc/AppRTCDemo/ARDUtilities.h
Normal file
@@ -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
|
72
talk/examples/objc/AppRTCDemo/ARDUtilities.m
Normal file
72
talk/examples/objc/AppRTCDemo/ARDUtilities.m
Normal file
@@ -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
|
35
talk/examples/objc/AppRTCDemo/RTCICECandidate+JSON.h
Normal file
35
talk/examples/objc/AppRTCDemo/RTCICECandidate+JSON.h
Normal file
@@ -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
|
56
talk/examples/objc/AppRTCDemo/RTCICECandidate+JSON.m
Normal file
56
talk/examples/objc/AppRTCDemo/RTCICECandidate+JSON.m
Normal file
@@ -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
|
36
talk/examples/objc/AppRTCDemo/RTCICEServer+JSON.h
Normal file
36
talk/examples/objc/AppRTCDemo/RTCICEServer+JSON.h
Normal file
@@ -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
|
59
talk/examples/objc/AppRTCDemo/RTCICEServer+JSON.m
Normal file
59
talk/examples/objc/AppRTCDemo/RTCICEServer+JSON.m
Normal file
@@ -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
|
36
talk/examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.h
Normal file
36
talk/examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.h
Normal file
@@ -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
|
||||||
|
|
54
talk/examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.m
Normal file
54
talk/examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.m
Normal file
@@ -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
|
36
talk/examples/objc/AppRTCDemo/RTCSessionDescription+JSON.h
Normal file
36
talk/examples/objc/AppRTCDemo/RTCSessionDescription+JSON.h
Normal file
@@ -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
|
50
talk/examples/objc/AppRTCDemo/RTCSessionDescription+JSON.m
Normal file
50
talk/examples/objc/AppRTCDemo/RTCSessionDescription+JSON.m
Normal file
@@ -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
|
@@ -283,8 +283,20 @@
|
|||||||
'examples/objc/AppRTCDemo/APPRTCAppClient.m',
|
'examples/objc/AppRTCDemo/APPRTCAppClient.m',
|
||||||
'examples/objc/AppRTCDemo/APPRTCConnectionManager.h',
|
'examples/objc/AppRTCDemo/APPRTCConnectionManager.h',
|
||||||
'examples/objc/AppRTCDemo/APPRTCConnectionManager.m',
|
'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.h',
|
||||||
'examples/objc/AppRTCDemo/GAEChannelClient.m',
|
'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': {
|
'xcode_settings': {
|
||||||
'CLANG_ENABLE_OBJC_ARC': 'YES',
|
'CLANG_ENABLE_OBJC_ARC': 'YES',
|
||||||
|
Reference in New Issue
Block a user