AppRTCDemo: builds using ninja on iOS for simulator and device!

Things included in this CL:
- updated READMEs to provide an exact/reproable set of steps for getting the app
  running.
- gyp changes to build the iOS AppRTCDemo sample app using gyp+ninja instead of
  the hand-crafted Xcode project (which has never worked in its checked-in
  form), including a gyp action to sign the sample app for deployment to an iOS
  device (the app can also be used in the simulator)
- deleted the busted hand-crafted Xcode project for the sample app
- updated the sample app to match the PeerConnection API that ended up landing
  (in a surprising twist of fate, the API landed quite a bit later than the
  sample app and this is the first time the CR-time changes in the API are
  reflected in the sample app)
- updated the sample app to reflect apprtc.appspot.com HTML/JS changes (equiv to
  the AppRTCClient.java changes in http://s10/47299162)
- picked up the iossim DEPS to enable launching the sample app in the simulator
  from the command-line.
- renamed some files to match capitalization of the classes they contain (Ice ->
  ICE) per ObjC naming guidelines.
- ran the files involved in this CL through clang-format to deal with xcode
  formatting craxy.

BUG=2106
RISK=P2
TESTED=unittest builds with ninja and passes on OS=mac; sample app builds with ninja and runs on simulator and device, though no audio flows from simulator/device (will fix in a follow-up CL)
R=andrew@webrtc.org, justincohen@google.com, wu@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/1874005

git-svn-id: http://webrtc.googlecode.com/svn/trunk@4466 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
fischman@webrtc.org 2013-08-01 18:29:45 +00:00
parent 6abb750993
commit 1bc1954174
27 changed files with 416 additions and 905 deletions

1
.gitignore vendored
View File

@ -38,6 +38,7 @@
/chromium_deps
/google_apis/build
/gyp-mac-tool
/net/third_party/nss/
/out
/resources
/talk/examples/android/bin

17
DEPS
View File

@ -131,12 +131,29 @@ deps_os = {
# NSS, for SSLClientSocketNSS.
"third_party/nss":
From("chromium_deps", "src/third_party/nss"),
# TODO(fischman): delete this in favor of the copy in "ios" below, once the
# webrtc iOS bots are fixed to target_os=['ios'] in their .gclient
# https://code.google.com/p/webrtc/issues/detail?id=2152
"net/third_party/nss":
Var("chromium_trunk") + "/src/net/third_party/nss@" + Var("chromium_revision"),
},
"ios": {
# NSS, for SSLClientSocketNSS.
"third_party/nss":
From("chromium_deps", "src/third_party/nss"),
"net/third_party/nss":
Var("chromium_trunk") + "/src/net/third_party/nss@" + Var("chromium_revision"),
# class-dump utility to generate header files for undocumented SDKs.
"testing/iossim/third_party/class-dump":
From("chromium_deps", "src/testing/iossim/third_party/class-dump"),
# Helper for running under the simulator.
"testing/iossim":
Var("chromium_trunk") + "/src/testing/iossim@" + Var("chromium_revision"),
},
"unix": {

View File

@ -7,6 +7,7 @@
# be found in the AUTHORS file in the root of the source tree.
{
'includes': ['talk/build/common.gypi'],
'targets': [
{
'target_name': 'All',
@ -15,9 +16,9 @@
'webrtc/webrtc.gyp:*',
],
# TODO(henrike): fix build errors on 64 bit Mac for libjingle. See issue
# 2124
# 2124. Once done the entire conditional below can be removed.
'conditions': [
['OS!="mac" or target_arch!="x64"', {
['OS!="mac" or target_arch!="x64" or libjingle_objc==1', {
'dependencies': [
'talk/libjingle.gyp:*',
'talk/libjingle_examples.gyp:*',

View File

@ -1,45 +1,79 @@
This directory contains the ObjectiveC implementation of the
webrtc::PeerConnection API. This can be built for Mac or iOS.
webrtc::PeerConnection API. This can be built for Mac or iOS. This
file describes building the API, unit test, and AppRTCDemo sample app.
Prerequisites:
- Make sure gclient is checking out tools necessary to target iOS: your
.gclient file should contain a line like:
target_os = ['ios', 'mac']
Make sure to re-run gclient sync after adding this to download the tools.
- Set up webrtc-related GYP variables:
- For Mac:
export GYP_DEFINES="build_with_libjingle=1 build_with_chromium=0 OS=mac
target_arch=x64 libjingle_objc=1 libpeer_target_type=static_library
$GYP_DEFINES"
- For iOS:
export GYP_DEFINES="build_with_libjingle=1 build_with_chromium=0 OS=ios
libjingle_enable_video=0 libjingle_objc=1 enable_video=0 $GYP_DEFINES"
- Finally, run "gclient runhooks" to generate iOS or Mac targeting Xcode
projects.
Example of building & using the app:
- Set up webrtc-related $GYP_DEFINES; example shell functions that set
up for building for iOS-device, iOS-simulator, and Mac (resp) are:
function wrbase() {
cd /path/to/libjingle/trunk
export GYP_DEFINES="build_with_libjingle=1 build_with_chromium=0 libjingle_objc=1"
export GYP_GENERATORS="ninja"
}
cd <path/to/libjingle>/trunk/talk
- Open libjingle.xcproj. Select iPhone or iPad simulator and build everything.
Then switch to iOS device and build everything. This creates x86 and ARM
archives.
cd examples/ios
./makeLibs.sh
- This will generate fat archives containing both targets and copy them to
./libs.
- This step must be rerun every time you run gclient sync or build the API
libraries.
- Open AppRTCDemo.xcodeproj, select your device or simulator and run.
- If you have any problems deploying for the first time, check the project
properties to ensure that the Bundle Identifier matches your phone
provisioning profile. Or use the simulator as it doesn't require a profile.
function wrios() {
wrbase
export GYP_DEFINES="$GYP_DEFINES OS=ios target_arch=armv7"
export GYP_GENERATOR_FLAGS="$GYP_GENERATOR_FLAGS output_dir=out_ios"
export GYP_CROSSCOMPILE=1
}
- In desktop chrome, navigate to http://apprtc.appspot.com and note the r=<NNN>
room number in the resulting URL.
function wrsim() {
wrbase
export GYP_DEFINES="$GYP_DEFINES OS=ios target_arch=ia32"
export GYP_GENERATOR_FLAGS="$GYP_GENERATOR_FLAGS output_dir=out_sim"
export GYP_CROSSCOMPILE=1
}
- Enter that number into the text field on the phone.
function wrmac() {
wrbase
export GYP_DEFINES="$GYP_DEFINES OS=mac target_arch=x64"
export GYP_GENERATOR_FLAGS="$GYP_GENERATOR_FLAGS output_dir=out_mac"
}
- Alternatively, you can background the app and launch Safari. In Safari, open
the url apprtc://apprtc.appspot.com/?r=<NNN> where <NNN> is the room name.
Other options are to put the link in an email and send it to your self.
Clicking on it will launch AppRTCDemo and navigate to the room.
- Finally, run "gclient runhooks" to generate ninja files.
Example of building & using the unittest & app:
- To build & run the unittest (must target mac):
wrmac && gclient runhooks && \
ninja -C out_mac/Debug libjingle_peerconnection_objc_test && \
./out_mac/Debug/libjingle_peerconnection_objc_test.app/Contents/MacOS/libjingle_peerconnection_objc_test
- To build & launch the sample app on the iOS simulator:
wrsim && gclient runhooks && ninja -C out_sim/Debug iossim AppRTCDemo && \
./out_sim/Debug/iossim out_sim/Debug/AppRTCDemo.app
- To build & sign the sample app for an iOS device:
wrios && gclient runhooks && ninja -C out_ios/Debug AppRTCDemo
- To install the sample app on an iOS device:
ideviceinstaller -i out_ios/Debug/AppRTCDemo.app
(if installing ideviceinstaller from brew, use --HEAD to get support
for .app directories)
- Alternatively, use iPhone Configuration Utility:
- Open "iPhone Configuration Utility" (http://support.apple.com/kb/DL1465)
- Click the "Add" icon (command-o)
- Open the app under out_ios/Debug/AppRTCDemo (should be added to the Applications tab)
- Click the device's name in the left-hand panel and select the Applications tab
- Click Install on the AppRTCDemo line.
(If you have any problems deploying for the first time, check
the Info.plist file to ensure that the Bundle Identifier matches
your phone provisioning profile, or use a development wildcard
provisioning profile.)
- Once installed:
- Tap AppRTCDemo on the iOS device's home screen (might have to scroll to find it).
- In desktop chrome, navigate to http://apprtc.appspot.com and note
the r=<NNN> room number in the resulting URL; enter that number
into the text field on the phone.
- Alternatively, background the app and launch Safari. In Safari,
open the url apprtc://apprtc.appspot.com/?r=<NNN> where <NNN> is
the room name. Other options are to put the link in an email/chat
and send it to yourself. Clicking on it will launch AppRTCDemo
and navigate to the room.

View File

@ -32,8 +32,8 @@
@interface RTCICECandidate (Internal)
@property(nonatomic, assign, readonly) const
webrtc::IceCandidateInterface *candidate;
webrtc::IceCandidateInterface* candidate;
- (id)initWithCandidate:(const webrtc::IceCandidateInterface *)candidate;
- (id)initWithCandidate:(const webrtc::IceCandidateInterface*)candidate;
@end

View File

@ -78,7 +78,7 @@
return self;
}
- (const webrtc::IceCandidateInterface *)candidate {
- (const webrtc::IceCandidateInterface*)candidate {
return webrtc::CreateIceCandidate(
[self.sdpMid UTF8String], self.sdpMLineIndex, [self.sdp UTF8String]);
}

View File

@ -31,7 +31,8 @@
@interface RTCICEServer (Internal)
@property(nonatomic, assign, readonly)
webrtc::PeerConnectionInterface::IceServer iceServer;
@property(nonatomic,
assign,
readonly) webrtc::PeerConnectionInterface::IceServer iceServer;
@end

View File

@ -53,6 +53,7 @@
#include "talk/app/webrtc/videosourceinterface.h"
#include "talk/app/webrtc/videotrack.h"
#include "talk/base/logging.h"
#include "talk/base/ssladapter.h"
@interface RTCPeerConnectionFactory ()
@ -63,6 +64,16 @@
@implementation RTCPeerConnectionFactory
+ (void)initializeSSL {
BOOL initialized = talk_base::InitializeSSL();
NSAssert(initialized, @"Failed to initialize SSL library");
}
+ (void)deinitializeSSL {
BOOL deinitialized = talk_base::CleanupSSL();
NSAssert(deinitialized, @"Failed to deinitialize SSL library");
}
- (id)init {
if ((self = [super init])) {
_nativeFactory = webrtc::CreatePeerConnectionFactory();

View File

@ -33,24 +33,24 @@
// If present, this contains the identifier of the "media stream
// identification" as defined in [RFC 3388] for m-line this candidate is
// associated with.
@property(nonatomic, copy, readonly) NSString *sdpMid;
@property(nonatomic, copy, readonly) NSString* sdpMid;
// This indicates the index (starting at zero) of m-line in the SDP this
// candidate is associated with.
@property(nonatomic, assign, readonly) NSInteger sdpMLineIndex;
// Creates an SDP-ized form of this candidate.
@property(nonatomic, copy, readonly) NSString *sdp;
@property(nonatomic, copy, readonly) NSString* sdp;
// Creates an ICECandidateInterface based on SDP string.
- (id)initWithMid:(NSString *)sdpMid
- (id)initWithMid:(NSString*)sdpMid
index:(NSInteger)sdpMLineIndex
sdp:(NSString *)sdp;
sdp:(NSString*)sdp;
#ifndef DOXYGEN_SHOULD_SKIP_THIS
// Disallow init and don't add to documentation
- (id)init __attribute__(
(unavailable("init is not a supported initializer for this class.")));
- (id)init __attribute__((
unavailable("init is not a supported initializer for this class.")));
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
@end

View File

@ -31,18 +31,18 @@
@interface RTCICEServer : NSObject
// The server URI.
@property(nonatomic, strong, readonly) NSURL *URI;
@property(nonatomic, strong, readonly) NSURL* URI;
// The server password.
@property(nonatomic, copy, readonly) NSString *password;
@property(nonatomic, copy, readonly) NSString* password;
// Initializer for RTCICEServer taking uri and password.
- (id)initWithURI:(NSString *)URI password:(NSString *)password;
- (id)initWithURI:(NSString*)URI password:(NSString*)password;
#ifndef DOXYGEN_SHOULD_SKIP_THIS
// Disallow init and don't add to documentation
- (id)init __attribute__(
(unavailable("init is not a supported initializer for this class.")));
- (id)init __attribute__((
unavailable("init is not a supported initializer for this class.")));
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
@end

View File

@ -40,6 +40,10 @@
// It is the main entry point to the PeerConnection API for clients.
@interface RTCPeerConnectionFactory : NSObject
// Initialize & de-initialize the SSL subsystem. Failure is fatal.
+ (void)initializeSSL;
+ (void)deinitializeSSL;
// Create an RTCPeerConnection object. RTCPeerConnectionFactory will create
// required libjingle threads, socket and network manager factory classes for
// networking.

View File

@ -0,0 +1 @@
See ../objc/README for information on what this is and how to use it.

View File

@ -99,12 +99,12 @@
['OS=="ios"', {
'defines': [
'IOS',
'SSL_USE_NSS',
'HAVE_NSS_SSL_H=1',
'SSL_USE_NSS_RNG',
],
'variables': {
'use_nss%': 1,
},
'defines!': [
'HAVE_OPENSSL_SSL_H=1',
],
}],
['libjingle_objc==1', {
'defines': [

View File

@ -1,570 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
4F995B31173B6937007F179A /* libaudio_coding_module.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B01173B6937007F179A /* libaudio_coding_module.a */; };
4F995B32173B6937007F179A /* libaudio_conference_mixer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B02173B6937007F179A /* libaudio_conference_mixer.a */; };
4F995B33173B6937007F179A /* libaudio_device.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B03173B6937007F179A /* libaudio_device.a */; };
4F995B34173B6938007F179A /* libaudio_processing.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B04173B6937007F179A /* libaudio_processing.a */; };
4F995B35173B6938007F179A /* libaudioproc_debug_proto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B05173B6937007F179A /* libaudioproc_debug_proto.a */; };
4F995B36173B6938007F179A /* libbitrate_controller.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B06173B6937007F179A /* libbitrate_controller.a */; };
4F995B37173B6938007F179A /* libCNG.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B07173B6937007F179A /* libCNG.a */; };
4F995B38173B6938007F179A /* libcommon_video.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B08173B6937007F179A /* libcommon_video.a */; };
4F995B39173B6938007F179A /* libexpat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B09173B6937007F179A /* libexpat.a */; };
4F995B3A173B6938007F179A /* libG711.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B0A173B6937007F179A /* libG711.a */; };
4F995B3B173B6938007F179A /* libG722.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B0B173B6937007F179A /* libG722.a */; };
4F995B3C173B6938007F179A /* libgunit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B0C173B6937007F179A /* libgunit.a */; };
4F995B3D173B6938007F179A /* libiLBC.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B0D173B6937007F179A /* libiLBC.a */; };
4F995B3E173B6938007F179A /* libiSAC.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B0E173B6937007F179A /* libiSAC.a */; };
4F995B3F173B6938007F179A /* libiSACFix.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B0F173B6937007F179A /* libiSACFix.a */; };
4F995B40173B6938007F179A /* libjingle_media.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B10173B6937007F179A /* libjingle_media.a */; };
4F995B41173B6938007F179A /* libjingle_p2p.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B11173B6937007F179A /* libjingle_p2p.a */; };
4F995B42173B6938007F179A /* libjingle_peerconnection_objc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B12173B6937007F179A /* libjingle_peerconnection_objc.a */; };
4F995B43173B6938007F179A /* libjingle_peerconnection.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B13173B6937007F179A /* libjingle_peerconnection.a */; };
4F995B44173B6938007F179A /* libjingle_sound.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B14173B6937007F179A /* libjingle_sound.a */; };
4F995B45173B6938007F179A /* libjingle.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B15173B6937007F179A /* libjingle.a */; };
4F995B46173B6938007F179A /* libjsoncpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B16173B6937007F179A /* libjsoncpp.a */; };
4F995B47173B6938007F179A /* libmedia_file.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B17173B6937007F179A /* libmedia_file.a */; };
4F995B48173B6938007F179A /* libNetEq.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B18173B6937007F179A /* libNetEq.a */; };
4F995B49173B6938007F179A /* libopenssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B19173B6937007F179A /* libopenssl.a */; };
4F995B4A173B6938007F179A /* libopus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B1A173B6937007F179A /* libopus.a */; };
4F995B4B173B6938007F179A /* libpaced_sender.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B1B173B6937007F179A /* libpaced_sender.a */; };
4F995B4C173B6938007F179A /* libPCM16B.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B1C173B6937007F179A /* libPCM16B.a */; };
4F995B4D173B6938007F179A /* libprotobuf_lite.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B1D173B6937007F179A /* libprotobuf_lite.a */; };
4F995B4E173B6938007F179A /* libremote_bitrate_estimator.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B1E173B6937007F179A /* libremote_bitrate_estimator.a */; };
4F995B4F173B6938007F179A /* libresampler.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B1F173B6937007F179A /* libresampler.a */; };
4F995B50173B6938007F179A /* librtp_rtcp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B20173B6937007F179A /* librtp_rtcp.a */; };
4F995B51173B6938007F179A /* libsignal_processing.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B21173B6937007F179A /* libsignal_processing.a */; };
4F995B52173B6938007F179A /* libsrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B22173B6937007F179A /* libsrtp.a */; };
4F995B53173B6938007F179A /* libsystem_wrappers.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B23173B6937007F179A /* libsystem_wrappers.a */; };
4F995B54173B6938007F179A /* libudp_transport.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B24173B6937007F179A /* libudp_transport.a */; };
4F995B55173B6938007F179A /* libvad.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B25173B6937007F179A /* libvad.a */; };
4F995B56173B6938007F179A /* libvideo_capture_module.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B26173B6937007F179A /* libvideo_capture_module.a */; };
4F995B57173B6938007F179A /* libvideo_coding_utility.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B27173B6937007F179A /* libvideo_coding_utility.a */; };
4F995B58173B6938007F179A /* libvideo_engine_core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B28173B6937007F179A /* libvideo_engine_core.a */; };
4F995B59173B6938007F179A /* libvideo_processing.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B29173B6937007F179A /* libvideo_processing.a */; };
4F995B5A173B6938007F179A /* libvideo_render_module.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B2A173B6937007F179A /* libvideo_render_module.a */; };
4F995B5B173B6938007F179A /* libvoice_engine_core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B2B173B6937007F179A /* libvoice_engine_core.a */; };
4F995B5C173B6938007F179A /* libwebrtc_i420.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B2C173B6937007F179A /* libwebrtc_i420.a */; };
4F995B5D173B6938007F179A /* libwebrtc_opus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B2D173B6937007F179A /* libwebrtc_opus.a */; };
4F995B5E173B6938007F179A /* libwebrtc_utility.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B2E173B6937007F179A /* libwebrtc_utility.a */; };
4F995B5F173B6938007F179A /* libwebrtc_video_coding.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B2F173B6937007F179A /* libwebrtc_video_coding.a */; };
4F995B60173B6938007F179A /* libwebrtc_vp8.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B30173B6937007F179A /* libwebrtc_vp8.a */; };
4F995B62173B694B007F179A /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B61173B694B007F179A /* AVFoundation.framework */; };
4F995B64173B6956007F179A /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B63173B6956007F179A /* CoreMedia.framework */; };
4F995B66173B695C007F179A /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B65173B695C007F179A /* CoreVideo.framework */; };
4F995B68173B6970007F179A /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B67173B6970007F179A /* CoreAudio.framework */; };
4F995B91173C03A1007F179A /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F995B90173C03A1007F179A /* AudioToolbox.framework */; };
4F995B94173C0B82007F179A /* shim.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F995B92173C0819007F179A /* shim.mm */; };
4FBCC04F1728E929004C8C0B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4FBCC04E1728E929004C8C0B /* UIKit.framework */; };
4FBCC0511728E929004C8C0B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4FBCC0501728E929004C8C0B /* Foundation.framework */; };
4FBCC0531728E929004C8C0B /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4FBCC0521728E929004C8C0B /* CoreGraphics.framework */; };
4FBCC05B1728E929004C8C0B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4FBCC05A1728E929004C8C0B /* main.m */; };
4FBCC05F1728E929004C8C0B /* APPRTCAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4FBCC05E1728E929004C8C0B /* APPRTCAppDelegate.m */; };
4FBCC0611728E929004C8C0B /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 4FBCC0601728E929004C8C0B /* Default.png */; };
4FBCC0681728E929004C8C0B /* APPRTCViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4FBCC0671728E929004C8C0B /* APPRTCViewController.m */; };
4FBCC06B1728E929004C8C0B /* APPRTCViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4FBCC0691728E929004C8C0B /* APPRTCViewController.xib */; };
4FBCC0731729B780004C8C0B /* GAEChannelClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 4FBCC0721729B780004C8C0B /* GAEChannelClient.m */; };
4FD7F5011732E1C2009295E5 /* APPRTCAppClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 4FD7F5001732E1C2009295E5 /* APPRTCAppClient.m */; };
4FEE3E531743C94D0005814A /* ios_channel.html in Resources */ = {isa = PBXBuildFile; fileRef = 4FEE3E511743C92D0005814A /* ios_channel.html */; };
4FEE3EB71746A3810005814A /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4FEE3EB61746A3810005814A /* Icon.png */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
4F995B01173B6937007F179A /* libaudio_coding_module.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libaudio_coding_module.a; path = libs/libaudio_coding_module.a; sourceTree = "<group>"; };
4F995B02173B6937007F179A /* libaudio_conference_mixer.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libaudio_conference_mixer.a; path = libs/libaudio_conference_mixer.a; sourceTree = "<group>"; };
4F995B03173B6937007F179A /* libaudio_device.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libaudio_device.a; path = libs/libaudio_device.a; sourceTree = "<group>"; };
4F995B04173B6937007F179A /* libaudio_processing.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libaudio_processing.a; path = libs/libaudio_processing.a; sourceTree = "<group>"; };
4F995B05173B6937007F179A /* libaudioproc_debug_proto.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libaudioproc_debug_proto.a; path = libs/libaudioproc_debug_proto.a; sourceTree = "<group>"; };
4F995B06173B6937007F179A /* libbitrate_controller.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbitrate_controller.a; path = libs/libbitrate_controller.a; sourceTree = "<group>"; };
4F995B07173B6937007F179A /* libCNG.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libCNG.a; path = libs/libCNG.a; sourceTree = "<group>"; };
4F995B08173B6937007F179A /* libcommon_video.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcommon_video.a; path = libs/libcommon_video.a; sourceTree = "<group>"; };
4F995B09173B6937007F179A /* libexpat.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libexpat.a; path = libs/libexpat.a; sourceTree = "<group>"; };
4F995B0A173B6937007F179A /* libG711.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libG711.a; path = libs/libG711.a; sourceTree = "<group>"; };
4F995B0B173B6937007F179A /* libG722.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libG722.a; path = libs/libG722.a; sourceTree = "<group>"; };
4F995B0C173B6937007F179A /* libgunit.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgunit.a; path = libs/libgunit.a; sourceTree = "<group>"; };
4F995B0D173B6937007F179A /* libiLBC.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libiLBC.a; path = libs/libiLBC.a; sourceTree = "<group>"; };
4F995B0E173B6937007F179A /* libiSAC.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libiSAC.a; path = libs/libiSAC.a; sourceTree = "<group>"; };
4F995B0F173B6937007F179A /* libiSACFix.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libiSACFix.a; path = libs/libiSACFix.a; sourceTree = "<group>"; };
4F995B10173B6937007F179A /* libjingle_media.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libjingle_media.a; path = libs/libjingle_media.a; sourceTree = "<group>"; };
4F995B11173B6937007F179A /* libjingle_p2p.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libjingle_p2p.a; path = libs/libjingle_p2p.a; sourceTree = "<group>"; };
4F995B12173B6937007F179A /* libjingle_peerconnection_objc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libjingle_peerconnection_objc.a; path = libs/libjingle_peerconnection_objc.a; sourceTree = "<group>"; };
4F995B13173B6937007F179A /* libjingle_peerconnection.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libjingle_peerconnection.a; path = libs/libjingle_peerconnection.a; sourceTree = "<group>"; };
4F995B14173B6937007F179A /* libjingle_sound.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libjingle_sound.a; path = libs/libjingle_sound.a; sourceTree = "<group>"; };
4F995B15173B6937007F179A /* libjingle.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libjingle.a; path = libs/libjingle.a; sourceTree = "<group>"; };
4F995B16173B6937007F179A /* libjsoncpp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libjsoncpp.a; path = libs/libjsoncpp.a; sourceTree = "<group>"; };
4F995B17173B6937007F179A /* libmedia_file.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmedia_file.a; path = libs/libmedia_file.a; sourceTree = "<group>"; };
4F995B18173B6937007F179A /* libNetEq.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libNetEq.a; path = libs/libNetEq.a; sourceTree = "<group>"; };
4F995B19173B6937007F179A /* libopenssl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libopenssl.a; path = libs/libopenssl.a; sourceTree = "<group>"; };
4F995B1A173B6937007F179A /* libopus.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libopus.a; path = libs/libopus.a; sourceTree = "<group>"; };
4F995B1B173B6937007F179A /* libpaced_sender.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpaced_sender.a; path = libs/libpaced_sender.a; sourceTree = "<group>"; };
4F995B1C173B6937007F179A /* libPCM16B.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libPCM16B.a; path = libs/libPCM16B.a; sourceTree = "<group>"; };
4F995B1D173B6937007F179A /* libprotobuf_lite.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libprotobuf_lite.a; path = libs/libprotobuf_lite.a; sourceTree = "<group>"; };
4F995B1E173B6937007F179A /* libremote_bitrate_estimator.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libremote_bitrate_estimator.a; path = libs/libremote_bitrate_estimator.a; sourceTree = "<group>"; };
4F995B1F173B6937007F179A /* libresampler.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libresampler.a; path = libs/libresampler.a; sourceTree = "<group>"; };
4F995B20173B6937007F179A /* librtp_rtcp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = librtp_rtcp.a; path = libs/librtp_rtcp.a; sourceTree = "<group>"; };
4F995B21173B6937007F179A /* libsignal_processing.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsignal_processing.a; path = libs/libsignal_processing.a; sourceTree = "<group>"; };
4F995B22173B6937007F179A /* libsrtp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsrtp.a; path = libs/libsrtp.a; sourceTree = "<group>"; };
4F995B23173B6937007F179A /* libsystem_wrappers.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsystem_wrappers.a; path = libs/libsystem_wrappers.a; sourceTree = "<group>"; };
4F995B24173B6937007F179A /* libudp_transport.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libudp_transport.a; path = libs/libudp_transport.a; sourceTree = "<group>"; };
4F995B25173B6937007F179A /* libvad.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvad.a; path = libs/libvad.a; sourceTree = "<group>"; };
4F995B26173B6937007F179A /* libvideo_capture_module.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvideo_capture_module.a; path = libs/libvideo_capture_module.a; sourceTree = "<group>"; };
4F995B27173B6937007F179A /* libvideo_coding_utility.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvideo_coding_utility.a; path = libs/libvideo_coding_utility.a; sourceTree = "<group>"; };
4F995B28173B6937007F179A /* libvideo_engine_core.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvideo_engine_core.a; path = libs/libvideo_engine_core.a; sourceTree = "<group>"; };
4F995B29173B6937007F179A /* libvideo_processing.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvideo_processing.a; path = libs/libvideo_processing.a; sourceTree = "<group>"; };
4F995B2A173B6937007F179A /* libvideo_render_module.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvideo_render_module.a; path = libs/libvideo_render_module.a; sourceTree = "<group>"; };
4F995B2B173B6937007F179A /* libvoice_engine_core.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvoice_engine_core.a; path = libs/libvoice_engine_core.a; sourceTree = "<group>"; };
4F995B2C173B6937007F179A /* libwebrtc_i420.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libwebrtc_i420.a; path = libs/libwebrtc_i420.a; sourceTree = "<group>"; };
4F995B2D173B6937007F179A /* libwebrtc_opus.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libwebrtc_opus.a; path = libs/libwebrtc_opus.a; sourceTree = "<group>"; };
4F995B2E173B6937007F179A /* libwebrtc_utility.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libwebrtc_utility.a; path = libs/libwebrtc_utility.a; sourceTree = "<group>"; };
4F995B2F173B6937007F179A /* libwebrtc_video_coding.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libwebrtc_video_coding.a; path = libs/libwebrtc_video_coding.a; sourceTree = "<group>"; };
4F995B30173B6937007F179A /* libwebrtc_vp8.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libwebrtc_vp8.a; path = libs/libwebrtc_vp8.a; sourceTree = "<group>"; };
4F995B61173B694B007F179A /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
4F995B63173B6956007F179A /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
4F995B65173B695C007F179A /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; };
4F995B67173B6970007F179A /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
4F995B90173C03A1007F179A /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
4F995B92173C0819007F179A /* shim.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = shim.mm; path = ../../../app/webrtc/objctests/ios/shim.mm; sourceTree = "<group>"; };
4FBCC04B1728E929004C8C0B /* AppRTCDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AppRTCDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
4FBCC04E1728E929004C8C0B /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
4FBCC0501728E929004C8C0B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
4FBCC0521728E929004C8C0B /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
4FBCC0561728E929004C8C0B /* AppRTCDemo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "AppRTCDemo-Info.plist"; sourceTree = "<group>"; };
4FBCC05A1728E929004C8C0B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
4FBCC05C1728E929004C8C0B /* AppRTCDemo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AppRTCDemo-Prefix.pch"; sourceTree = "<group>"; };
4FBCC05D1728E929004C8C0B /* APPRTCAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = APPRTCAppDelegate.h; sourceTree = "<group>"; };
4FBCC05E1728E929004C8C0B /* APPRTCAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = APPRTCAppDelegate.m; sourceTree = "<group>"; };
4FBCC0601728E929004C8C0B /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = "<group>"; };
4FBCC0661728E929004C8C0B /* APPRTCViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = APPRTCViewController.h; sourceTree = "<group>"; };
4FBCC0671728E929004C8C0B /* APPRTCViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = APPRTCViewController.m; sourceTree = "<group>"; };
4FBCC06A1728E929004C8C0B /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/APPRTCViewController.xib; sourceTree = "<group>"; };
4FBCC0711729B780004C8C0B /* GAEChannelClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GAEChannelClient.h; sourceTree = "<group>"; };
4FBCC0721729B780004C8C0B /* GAEChannelClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GAEChannelClient.m; sourceTree = "<group>"; };
4FD7F4FF1732E1C1009295E5 /* APPRTCAppClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APPRTCAppClient.h; sourceTree = "<group>"; };
4FD7F5001732E1C2009295E5 /* APPRTCAppClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = APPRTCAppClient.m; sourceTree = "<group>"; };
4FEE3E511743C92D0005814A /* ios_channel.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ios_channel.html; sourceTree = "<group>"; };
4FEE3EB61746A3810005814A /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = ../Icon.png; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
4FBCC0481728E929004C8C0B /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
4F995B91173C03A1007F179A /* AudioToolbox.framework in Frameworks */,
4F995B62173B694B007F179A /* AVFoundation.framework in Frameworks */,
4F995B68173B6970007F179A /* CoreAudio.framework in Frameworks */,
4FBCC0531728E929004C8C0B /* CoreGraphics.framework in Frameworks */,
4F995B64173B6956007F179A /* CoreMedia.framework in Frameworks */,
4F995B66173B695C007F179A /* CoreVideo.framework in Frameworks */,
4FBCC0511728E929004C8C0B /* Foundation.framework in Frameworks */,
4FBCC04F1728E929004C8C0B /* UIKit.framework in Frameworks */,
4F995B31173B6937007F179A /* libaudio_coding_module.a in Frameworks */,
4F995B32173B6937007F179A /* libaudio_conference_mixer.a in Frameworks */,
4F995B33173B6937007F179A /* libaudio_device.a in Frameworks */,
4F995B34173B6938007F179A /* libaudio_processing.a in Frameworks */,
4F995B35173B6938007F179A /* libaudioproc_debug_proto.a in Frameworks */,
4F995B36173B6938007F179A /* libbitrate_controller.a in Frameworks */,
4F995B37173B6938007F179A /* libCNG.a in Frameworks */,
4F995B38173B6938007F179A /* libcommon_video.a in Frameworks */,
4F995B39173B6938007F179A /* libexpat.a in Frameworks */,
4F995B3A173B6938007F179A /* libG711.a in Frameworks */,
4F995B3B173B6938007F179A /* libG722.a in Frameworks */,
4F995B3C173B6938007F179A /* libgunit.a in Frameworks */,
4F995B3D173B6938007F179A /* libiLBC.a in Frameworks */,
4F995B3E173B6938007F179A /* libiSAC.a in Frameworks */,
4F995B40173B6938007F179A /* libjingle_media.a in Frameworks */,
4F995B41173B6938007F179A /* libjingle_p2p.a in Frameworks */,
4F995B42173B6938007F179A /* libjingle_peerconnection_objc.a in Frameworks */,
4F995B43173B6938007F179A /* libjingle_peerconnection.a in Frameworks */,
4F995B44173B6938007F179A /* libjingle_sound.a in Frameworks */,
4F995B45173B6938007F179A /* libjingle.a in Frameworks */,
4F995B46173B6938007F179A /* libjsoncpp.a in Frameworks */,
4F995B47173B6938007F179A /* libmedia_file.a in Frameworks */,
4F995B48173B6938007F179A /* libNetEq.a in Frameworks */,
4F995B49173B6938007F179A /* libopenssl.a in Frameworks */,
4F995B4A173B6938007F179A /* libopus.a in Frameworks */,
4F995B4B173B6938007F179A /* libpaced_sender.a in Frameworks */,
4F995B4C173B6938007F179A /* libPCM16B.a in Frameworks */,
4F995B4D173B6938007F179A /* libprotobuf_lite.a in Frameworks */,
4F995B4E173B6938007F179A /* libremote_bitrate_estimator.a in Frameworks */,
4F995B4F173B6938007F179A /* libresampler.a in Frameworks */,
4F995B50173B6938007F179A /* librtp_rtcp.a in Frameworks */,
4F995B51173B6938007F179A /* libsignal_processing.a in Frameworks */,
4F995B52173B6938007F179A /* libsrtp.a in Frameworks */,
4F995B53173B6938007F179A /* libsystem_wrappers.a in Frameworks */,
4F995B54173B6938007F179A /* libudp_transport.a in Frameworks */,
4F995B55173B6938007F179A /* libvad.a in Frameworks */,
4F995B56173B6938007F179A /* libvideo_capture_module.a in Frameworks */,
4F995B57173B6938007F179A /* libvideo_coding_utility.a in Frameworks */,
4F995B58173B6938007F179A /* libvideo_engine_core.a in Frameworks */,
4F995B59173B6938007F179A /* libvideo_processing.a in Frameworks */,
4F995B5A173B6938007F179A /* libvideo_render_module.a in Frameworks */,
4F995B5B173B6938007F179A /* libvoice_engine_core.a in Frameworks */,
4F995B5C173B6938007F179A /* libwebrtc_i420.a in Frameworks */,
4F995B5D173B6938007F179A /* libwebrtc_opus.a in Frameworks */,
4F995B5E173B6938007F179A /* libwebrtc_utility.a in Frameworks */,
4F995B5F173B6938007F179A /* libwebrtc_video_coding.a in Frameworks */,
4F995B60173B6938007F179A /* libwebrtc_vp8.a in Frameworks */,
4F995B3F173B6938007F179A /* libiSACFix.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
4F1CC122172F52E50090479F /* libs */ = {
isa = PBXGroup;
children = (
4F995B01173B6937007F179A /* libaudio_coding_module.a */,
4F995B02173B6937007F179A /* libaudio_conference_mixer.a */,
4F995B03173B6937007F179A /* libaudio_device.a */,
4F995B04173B6937007F179A /* libaudio_processing.a */,
4F995B05173B6937007F179A /* libaudioproc_debug_proto.a */,
4F995B06173B6937007F179A /* libbitrate_controller.a */,
4F995B07173B6937007F179A /* libCNG.a */,
4F995B08173B6937007F179A /* libcommon_video.a */,
4F995B09173B6937007F179A /* libexpat.a */,
4F995B0A173B6937007F179A /* libG711.a */,
4F995B0B173B6937007F179A /* libG722.a */,
4F995B0C173B6937007F179A /* libgunit.a */,
4F995B0D173B6937007F179A /* libiLBC.a */,
4F995B0E173B6937007F179A /* libiSAC.a */,
4F995B0F173B6937007F179A /* libiSACFix.a */,
4F995B10173B6937007F179A /* libjingle_media.a */,
4F995B11173B6937007F179A /* libjingle_p2p.a */,
4F995B12173B6937007F179A /* libjingle_peerconnection_objc.a */,
4F995B13173B6937007F179A /* libjingle_peerconnection.a */,
4F995B14173B6937007F179A /* libjingle_sound.a */,
4F995B15173B6937007F179A /* libjingle.a */,
4F995B16173B6937007F179A /* libjsoncpp.a */,
4F995B17173B6937007F179A /* libmedia_file.a */,
4F995B18173B6937007F179A /* libNetEq.a */,
4F995B19173B6937007F179A /* libopenssl.a */,
4F995B1A173B6937007F179A /* libopus.a */,
4F995B1B173B6937007F179A /* libpaced_sender.a */,
4F995B1C173B6937007F179A /* libPCM16B.a */,
4F995B1D173B6937007F179A /* libprotobuf_lite.a */,
4F995B1E173B6937007F179A /* libremote_bitrate_estimator.a */,
4F995B1F173B6937007F179A /* libresampler.a */,
4F995B20173B6937007F179A /* librtp_rtcp.a */,
4F995B21173B6937007F179A /* libsignal_processing.a */,
4F995B22173B6937007F179A /* libsrtp.a */,
4F995B23173B6937007F179A /* libsystem_wrappers.a */,
4F995B24173B6937007F179A /* libudp_transport.a */,
4F995B25173B6937007F179A /* libvad.a */,
4F995B26173B6937007F179A /* libvideo_capture_module.a */,
4F995B27173B6937007F179A /* libvideo_coding_utility.a */,
4F995B28173B6937007F179A /* libvideo_engine_core.a */,
4F995B29173B6937007F179A /* libvideo_processing.a */,
4F995B2A173B6937007F179A /* libvideo_render_module.a */,
4F995B2B173B6937007F179A /* libvoice_engine_core.a */,
4F995B2C173B6937007F179A /* libwebrtc_i420.a */,
4F995B2D173B6937007F179A /* libwebrtc_opus.a */,
4F995B2E173B6937007F179A /* libwebrtc_utility.a */,
4F995B2F173B6937007F179A /* libwebrtc_video_coding.a */,
4F995B30173B6937007F179A /* libwebrtc_vp8.a */,
);
name = libs;
sourceTree = "<group>";
};
4FBCC0421728E929004C8C0B = {
isa = PBXGroup;
children = (
4FBCC0541728E929004C8C0B /* AppRTCDemo */,
4FBCC04D1728E929004C8C0B /* Frameworks */,
4F1CC122172F52E50090479F /* libs */,
4FBCC04C1728E929004C8C0B /* Products */,
);
sourceTree = "<group>";
};
4FBCC04C1728E929004C8C0B /* Products */ = {
isa = PBXGroup;
children = (
4FBCC04B1728E929004C8C0B /* AppRTCDemo.app */,
);
name = Products;
sourceTree = "<group>";
};
4FBCC04D1728E929004C8C0B /* Frameworks */ = {
isa = PBXGroup;
children = (
4F995B90173C03A1007F179A /* AudioToolbox.framework */,
4F995B61173B694B007F179A /* AVFoundation.framework */,
4F995B67173B6970007F179A /* CoreAudio.framework */,
4FBCC0521728E929004C8C0B /* CoreGraphics.framework */,
4F995B63173B6956007F179A /* CoreMedia.framework */,
4F995B65173B695C007F179A /* CoreVideo.framework */,
4FBCC0501728E929004C8C0B /* Foundation.framework */,
4FBCC04E1728E929004C8C0B /* UIKit.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
4FBCC0541728E929004C8C0B /* AppRTCDemo */ = {
isa = PBXGroup;
children = (
4FBCC0711729B780004C8C0B /* GAEChannelClient.h */,
4FBCC0721729B780004C8C0B /* GAEChannelClient.m */,
4FD7F4FF1732E1C1009295E5 /* APPRTCAppClient.h */,
4FD7F5001732E1C2009295E5 /* APPRTCAppClient.m */,
4FBCC05D1728E929004C8C0B /* APPRTCAppDelegate.h */,
4FBCC05E1728E929004C8C0B /* APPRTCAppDelegate.m */,
4FBCC0661728E929004C8C0B /* APPRTCViewController.h */,
4FBCC0671728E929004C8C0B /* APPRTCViewController.m */,
4FBCC0691728E929004C8C0B /* APPRTCViewController.xib */,
4FBCC0551728E929004C8C0B /* Supporting Files */,
);
path = AppRTCDemo;
sourceTree = "<group>";
};
4FBCC0551728E929004C8C0B /* Supporting Files */ = {
isa = PBXGroup;
children = (
4FBCC0561728E929004C8C0B /* AppRTCDemo-Info.plist */,
4FBCC05C1728E929004C8C0B /* AppRTCDemo-Prefix.pch */,
4FBCC0601728E929004C8C0B /* Default.png */,
4FEE3EB61746A3810005814A /* Icon.png */,
4FEE3E511743C92D0005814A /* ios_channel.html */,
4FBCC05A1728E929004C8C0B /* main.m */,
4F995B92173C0819007F179A /* shim.mm */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
4FBCC04A1728E929004C8C0B /* AppRTCDemo */ = {
isa = PBXNativeTarget;
buildConfigurationList = 4FBCC06E1728E929004C8C0B /* Build configuration list for PBXNativeTarget "AppRTCDemo" */;
buildPhases = (
4FBCC0471728E929004C8C0B /* Sources */,
4FBCC0481728E929004C8C0B /* Frameworks */,
4FBCC0491728E929004C8C0B /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = AppRTCDemo;
productName = AppRTCDemo;
productReference = 4FBCC04B1728E929004C8C0B /* AppRTCDemo.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
4FBCC0431728E929004C8C0B /* Project object */ = {
isa = PBXProject;
attributes = {
CLASSPREFIX = RTC;
LastUpgradeCheck = 0460;
ORGANIZATIONNAME = Google;
};
buildConfigurationList = 4FBCC0461728E929004C8C0B /* Build configuration list for PBXProject "AppRTCDemo" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 4FBCC0421728E929004C8C0B;
productRefGroup = 4FBCC04C1728E929004C8C0B /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
4FBCC04A1728E929004C8C0B /* AppRTCDemo */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
4FBCC0491728E929004C8C0B /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4FEE3E531743C94D0005814A /* ios_channel.html in Resources */,
4FBCC0611728E929004C8C0B /* Default.png in Resources */,
4FBCC06B1728E929004C8C0B /* APPRTCViewController.xib in Resources */,
4FEE3EB71746A3810005814A /* Icon.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
4FBCC0471728E929004C8C0B /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4FBCC05B1728E929004C8C0B /* main.m in Sources */,
4FBCC05F1728E929004C8C0B /* APPRTCAppDelegate.m in Sources */,
4FBCC0681728E929004C8C0B /* APPRTCViewController.m in Sources */,
4FBCC0731729B780004C8C0B /* GAEChannelClient.m in Sources */,
4FD7F5011732E1C2009295E5 /* APPRTCAppClient.m in Sources */,
4F995B94173C0B82007F179A /* shim.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
4FBCC0691728E929004C8C0B /* APPRTCViewController.xib */ = {
isa = PBXVariantGroup;
children = (
4FBCC06A1728E929004C8C0B /* en */,
);
name = APPRTCViewController.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
4FBCC06C1728E929004C8C0B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 6.1;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
name = Debug;
};
4FBCC06D1728E929004C8C0B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 6.1;
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
4FBCC06F1728E929004C8C0B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)";
CLANG_CXX_LANGUAGE_STANDARD = "compiler-default";
CLANG_CXX_LIBRARY = "compiler-default";
GCC_CW_ASM_SYNTAX = NO;
GCC_C_LANGUAGE_STANDARD = c99;
GCC_ENABLE_CPP_EXCEPTIONS = NO;
GCC_ENABLE_CPP_RTTI = NO;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "AppRTCDemo/AppRTCDemo-Prefix.pch";
GCC_THREADSAFE_STATICS = NO;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
HEADER_SEARCH_PATHS = (
../../app/webrtc/objc/public,
../../..,
);
INFOPLIST_FILE = "AppRTCDemo/AppRTCDemo-Info.plist";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/libs\"",
);
ONLY_ACTIVE_ARCH = NO;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
VALID_ARCHS = "armv7 i386";
WRAPPER_EXTENSION = app;
};
name = Debug;
};
4FBCC0701728E929004C8C0B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)";
CLANG_CXX_LANGUAGE_STANDARD = "compiler-default";
CLANG_CXX_LIBRARY = "compiler-default";
GCC_CW_ASM_SYNTAX = NO;
GCC_C_LANGUAGE_STANDARD = c99;
GCC_ENABLE_CPP_EXCEPTIONS = NO;
GCC_ENABLE_CPP_RTTI = NO;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "AppRTCDemo/AppRTCDemo-Prefix.pch";
GCC_THREADSAFE_STATICS = NO;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
HEADER_SEARCH_PATHS = (
../../app/webrtc/objc/public,
../../..,
);
INFOPLIST_FILE = "AppRTCDemo/AppRTCDemo-Info.plist";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/libs\"",
);
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
VALID_ARCHS = "armv7 i386";
WRAPPER_EXTENSION = app;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
4FBCC0461728E929004C8C0B /* Build configuration list for PBXProject "AppRTCDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
4FBCC06C1728E929004C8C0B /* Debug */,
4FBCC06D1728E929004C8C0B /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
4FBCC06E1728E929004C8C0B /* Build configuration list for PBXNativeTarget "AppRTCDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
4FBCC06F1728E929004C8C0B /* Debug */,
4FBCC0701728E929004C8C0B /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 4FBCC0431728E929004C8C0B /* Project object */;
}

View File

@ -29,10 +29,10 @@
#import "GAEChannelClient.h"
// Called when there are RTCIceServers.
@protocol IceServerDelegate <NSObject>
// Called when there are RTCICEServers.
@protocol ICEServerDelegate<NSObject>
- (void)onIceServers:(NSArray *)servers;
- (void)onICEServers:(NSArray*)servers;
@end
@ -45,8 +45,8 @@
// for the registered handler to be called with received messages.
@interface APPRTCAppClient : NSObject<NSURLConnectionDataDelegate>
@property(nonatomic, assign) id<IceServerDelegate>iceServerDelegate;
@property(nonatomic, assign) id<GAEMessageHandler>messageHandler;
@property(nonatomic, assign) id<ICEServerDelegate> ICEServerDelegate;
@property(nonatomic, assign) id<GAEMessageHandler> messageHandler;
- (void)connectToRoom:(NSURL *)room;
- (void)sendData:(NSData *)data;

View File

@ -30,16 +30,16 @@
#import <dispatch/dispatch.h>
#import "GAEChannelClient.h"
#import "RTCIceServer.h"
#import "RTCICEServer.h"
@interface APPRTCAppClient ()
@property(nonatomic, strong) dispatch_queue_t backgroundQueue;
@property(nonatomic, assign) dispatch_queue_t backgroundQueue;
@property(nonatomic, copy) NSString *baseURL;
@property(nonatomic, strong) GAEChannelClient *gaeChannel;
@property(nonatomic, copy) NSString *postMessageUrl;
@property(nonatomic, copy) NSString *pcConfig;
@property(nonatomic, strong) NSMutableString *receivedData;
@property(nonatomic, strong) NSMutableString *roomHtml;
@property(atomic, strong) NSMutableArray *sendQueue;
@property(nonatomic, copy) NSString *token;
@ -52,13 +52,18 @@
- (id)init {
if (self = [super init]) {
_backgroundQueue = dispatch_queue_create("RTCBackgroundQueue", NULL);
dispatch_retain(_backgroundQueue);
_sendQueue = [NSMutableArray array];
// Uncomment to see Request/Response logging.
//_verboseLogging = YES;
// _verboseLogging = YES;
}
return self;
}
- (void)dealloc {
dispatch_release(_backgroundQueue);
}
#pragma mark - Public methods
- (void)connectToRoom:(NSURL *)url {
@ -76,42 +81,41 @@
#pragma mark - Internal methods
- (NSTextCheckingResult *)findMatch:(NSString *)regexpPattern
withString:(NSString *)string
errorMessage:(NSString *)errorMessage {
NSError *error;
- (NSString*)findVar:(NSString*)name
strippingQuotes:(BOOL)strippingQuotes {
NSError* error;
NSString* pattern =
[NSString stringWithFormat:@".*\n *var %@ = ([^\n]*);\n.*", name];
NSRegularExpression *regexp =
[NSRegularExpression regularExpressionWithPattern:regexpPattern
[NSRegularExpression regularExpressionWithPattern:pattern
options:0
error:&error];
if (error) {
[self maybeLogMessage:
[NSString stringWithFormat:@"Failed to create regexp - %@",
[error description]]];
NSAssert(!error, @"Unexpected error compiling regex: ",
error.localizedDescription);
NSRange fullRange = NSMakeRange(0, [self.roomHtml length]);
NSArray *matches =
[regexp matchesInString:self.roomHtml options:0 range:fullRange];
if ([matches count] != 1) {
[self showMessage:[NSString stringWithFormat:@"%d matches for %@ in %@",
[matches count], name, self.roomHtml]];
return nil;
}
NSRange fullRange = NSMakeRange(0, [string length]);
NSArray *matches = [regexp matchesInString:string options:0 range:fullRange];
if ([matches count] == 0) {
if ([errorMessage length] > 0) {
[self maybeLogMessage:string];
[self showMessage:
[NSString stringWithFormat:@"Missing %@ in HTML.", errorMessage]];
}
return nil;
} else if ([matches count] > 1) {
if ([errorMessage length] > 0) {
[self maybeLogMessage:string];
[self showMessage:[NSString stringWithFormat:@"Too many %@s in HTML.",
errorMessage]];
}
return nil;
NSRange matchRange = [matches[0] rangeAtIndex:1];
NSString* value = [self.roomHtml substringWithRange:matchRange];
if (strippingQuotes) {
NSAssert([value length] > 2,
@"Can't strip quotes from short string: [%@]", value);
NSAssert(([value characterAtIndex:0] == '\'' &&
[value characterAtIndex:[value length] - 1] == '\''),
@"Can't strip quotes from unquoted string: [%@]", value);
value = [value substringWithRange:NSMakeRange(1, [value length] - 2)];
}
return matches[0];
return value;
}
- (NSURLRequest *)getRequestFromUrl:(NSURL *)url {
self.receivedData = [NSMutableString stringWithCapacity:20000];
self.roomHtml = [NSMutableString stringWithCapacity:20000];
NSString *path =
[NSString stringWithFormat:@"https:%@", [url resourceSpecifier]];
NSURLRequest *request =
@ -172,10 +176,10 @@
[alertView show];
}
- (void)updateIceServers:(NSMutableArray *)iceServers
- (void)updateICEServers:(NSMutableArray *)ICEServers
withTurnServer:(NSString *)turnServerUrl {
if ([turnServerUrl length] < 1) {
[self.iceServerDelegate onIceServers:iceServers];
[self.ICEServerDelegate onICEServers:ICEServers];
return;
}
dispatch_async(self.backgroundQueue, ^(void) {
@ -199,16 +203,16 @@
NSString *password = json[@"password"];
NSString *fullUrl =
[NSString stringWithFormat:@"turn:%@@%@", username, turnServer];
RTCIceServer *iceServer =
[[RTCIceServer alloc] initWithUri:[NSURL URLWithString:fullUrl]
RTCICEServer *ICEServer =
[[RTCICEServer alloc] initWithURI:[NSURL URLWithString:fullUrl]
password:password];
[iceServers addObject:iceServer];
[ICEServers addObject:ICEServer];
} else {
NSLog(@"Unable to get TURN server. Error: %@", error.description);
}
dispatch_async(dispatch_get_main_queue(), ^(void) {
[self.iceServerDelegate onIceServers:iceServers];
[self.ICEServerDelegate onICEServers:ICEServers];
});
});
}
@ -219,7 +223,7 @@
NSString *roomHtml = [NSString stringWithUTF8String:[data bytes]];
[self maybeLogMessage:
[NSString stringWithFormat:@"Received %d chars", [roomHtml length]]];
[self.receivedData appendString:roomHtml];
[self.roomHtml appendString:roomHtml];
}
- (void)connection:(NSURLConnection *)connection
@ -237,64 +241,48 @@
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[self maybeLogMessage:[NSString stringWithFormat:@"finished loading %d chars",
[self.receivedData length]]];
NSTextCheckingResult *result =
[self findMatch:@".*\n *Sorry, this room is full\\..*"
withString:self.receivedData
errorMessage:nil];
if (result) {
[self.roomHtml length]]];
NSRegularExpression* fullRegex =
[NSRegularExpression regularExpressionWithPattern:@"room is full"
options:0
error:nil];
if ([fullRegex numberOfMatchesInString:self.roomHtml
options:0
range:NSMakeRange(0, [self.roomHtml length])]) {
[self showMessage:@"Room full"];
return;
}
NSString *fullUrl = [[[connection originalRequest] URL] absoluteString];
NSRange queryRange = [fullUrl rangeOfString:@"?"];
self.baseURL = [fullUrl substringToIndex:queryRange.location];
[self maybeLogMessage:[NSString stringWithFormat:@"URL\n%@", self.baseURL]];
[self maybeLogMessage:[NSString stringWithFormat:@"Base URL: %@", self.baseURL]];
result = [self findMatch:@".*\n *openChannel\\('([^']*)'\\);\n.*"
withString:self.receivedData
errorMessage:@"channel token"];
if (!result) {
self.token = [self findVar:@"channelToken" strippingQuotes:YES];
if (!self.token)
return;
}
self.token = [self.receivedData substringWithRange:[result rangeAtIndex:1]];
[self maybeLogMessage:[NSString stringWithFormat:@"Token\n%@", self.token]];
[self maybeLogMessage:[NSString stringWithFormat:@"Token: %@", self.token]];
result =
[self findMatch:@".*\n *path = '/(message\\?r=.+)' \\+ '(&u=[0-9]+)';\n.*"
withString:self.receivedData
errorMessage:@"postMessage URL"];
if (!result) {
NSString* roomKey = [self findVar:@"roomKey" strippingQuotes:YES];
NSString* me = [self findVar:@"me" strippingQuotes:YES];
if (!roomKey || !me)
return;
}
self.postMessageUrl =
[NSString stringWithFormat:@"%@%@",
[self.receivedData substringWithRange:[result rangeAtIndex:1]],
[self.receivedData substringWithRange:[result rangeAtIndex:2]]];
[self maybeLogMessage:[NSString stringWithFormat:@"POST message URL\n%@",
self.postMessageUrl]];
[NSString stringWithFormat:@"/message?r=%@&u=%@", roomKey, me];
[self maybeLogMessage:[NSString stringWithFormat:@"POST message URL: %@",
self.postMessageUrl]];
result = [self findMatch:@".*\n *var pc_config = (\\{[^\n]*\\});\n.*"
withString:self.receivedData
errorMessage:@"pc_config"];
if (!result) {
NSString* pcConfig = [self findVar:@"pcConfig" strippingQuotes:NO];
if (!pcConfig)
return;
}
NSString *pcConfig =
[self.receivedData substringWithRange:[result rangeAtIndex:1]];
[self maybeLogMessage:
[NSString stringWithFormat:@"PC Config JSON\n%@", pcConfig]];
[NSString stringWithFormat:@"PC Config JSON: %@", pcConfig]];
result = [self findMatch:@".*\n *requestTurn\\('([^\n]*)'\\);\n.*"
withString:self.receivedData
errorMessage:@"channel token"];
NSString *turnServerUrl;
if (result) {
turnServerUrl =
[self.receivedData substringWithRange:[result rangeAtIndex:1]];
NSString *turnServerUrl = [self findVar:@"turnUrl" strippingQuotes:YES];
if (turnServerUrl) {
[self maybeLogMessage:
[NSString stringWithFormat:@"TURN server request URL\n%@",
[NSString stringWithFormat:@"TURN server request URL: %@",
turnServerUrl]];
}
@ -303,8 +291,8 @@
NSDictionary *json =
[NSJSONSerialization JSONObjectWithData:pcData options:0 error:&error];
NSAssert(!error, @"Unable to parse. %@", error.localizedDescription);
NSArray *servers = [json objectForKey:@"iceServers"];
NSMutableArray *iceServers = [NSMutableArray array];
NSArray *servers = [json objectForKey:@"ICEServers"];
NSMutableArray *ICEServers = [NSMutableArray array];
for (NSDictionary *server in servers) {
NSString *url = [server objectForKey:@"url"];
NSString *credential = [server objectForKey:@"credential"];
@ -315,12 +303,12 @@
[NSString stringWithFormat:@"url [%@] - credential [%@]",
url,
credential]];
RTCIceServer *iceServer =
[[RTCIceServer alloc] initWithUri:[NSURL URLWithString:url]
RTCICEServer *ICEServer =
[[RTCICEServer alloc] initWithURI:[NSURL URLWithString:url]
password:credential];
[iceServers addObject:iceServer];
[ICEServers addObject:ICEServer];
}
[self updateIceServers:iceServers withTurnServer:turnServerUrl];
[self updateICEServers:ICEServers withTurnServer:turnServerUrl];
[self maybeLogMessage:
[NSString stringWithFormat:@"About to open GAE with token: %@",

View File

@ -43,9 +43,11 @@
// The main application class of the AppRTCDemo iOS app demonstrating
// interoperability between the Objcective C implementation of PeerConnection
// and the apprtc.appspot.com demo webapp.
@interface APPRTCAppDelegate : UIResponder<IceServerDelegate,
GAEMessageHandler, APPRTCSendMessage, RTCSessionDescriptonDelegate,
UIApplicationDelegate>
@interface APPRTCAppDelegate : UIResponder<ICEServerDelegate,
GAEMessageHandler,
APPRTCSendMessage,
RTCSessionDescriptonDelegate,
UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) APPRTCViewController *viewController;

View File

@ -28,8 +28,8 @@
#import "APPRTCAppDelegate.h"
#import "APPRTCViewController.h"
#import "RTCIceCandidate.h"
#import "RTCIceServer.h"
#import "RTCICECandidate.h"
#import "RTCICEServer.h"
#import "RTCMediaConstraints.h"
#import "RTCMediaStream.h"
#import "RTCPair.h"
@ -61,12 +61,12 @@
}
- (void)peerConnection:(RTCPeerConnection *)peerConnection
onSignalingStateChange:(RTCSignalingState)stateChanged {
signalingStateChanged:(RTCSignalingState)stateChanged {
NSLog(@"PCO onSignalingStateChange.");
}
- (void)peerConnection:(RTCPeerConnection *)peerConnection
onAddStream:(RTCMediaStream *)stream {
addedStream:(RTCMediaStream *)stream {
NSLog(@"PCO onAddStream.");
dispatch_async(dispatch_get_main_queue(), ^(void) {
NSAssert([stream.audioTracks count] >= 1,
@ -78,7 +78,7 @@
}
- (void)peerConnection:(RTCPeerConnection *)peerConnection
onRemoveStream:(RTCMediaStream *)stream {
removedStream:(RTCMediaStream *)stream {
NSLog(@"PCO onRemoveStream.");
// TODO(hughv): Remove video track.
}
@ -90,8 +90,8 @@
}
- (void)peerConnection:(RTCPeerConnection *)peerConnection
onIceCandidate:(RTCIceCandidate *)candidate {
NSLog(@"PCO onIceCandidate.\n Mid[%@] Index[%d] Sdp[%@]",
gotICECandidate:(RTCICECandidate *)candidate {
NSLog(@"PCO onICECandidate.\n Mid[%@] Index[%d] Sdp[%@]",
candidate.sdpMid,
candidate.sdpMLineIndex,
candidate.sdp);
@ -112,12 +112,12 @@
}
- (void)peerConnection:(RTCPeerConnection *)peerConnection
onIceGatheringChange:(RTCIceGatheringState)newState {
iceGatheringChanged:(RTCICEGatheringState)newState {
NSLog(@"PCO onIceGatheringChange. %d", newState);
}
- (void)peerConnection:(RTCPeerConnection *)peerConnection
onIceConnectionChange:(RTCIceConnectionState)newState {
iceConnectionChanged:(RTCICEConnectionState)newState {
NSLog(@"PCO onIceConnectionChange. %d", newState);
}
@ -139,9 +139,10 @@
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[RTCPeerConnectionFactory initializeSSL];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController =
[[APPRTCViewController alloc] initWithNibName:@"RTCViewController"
[[APPRTCViewController alloc] initWithNibName:@"APPRTCViewController"
bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
@ -174,7 +175,7 @@
return NO;
}
self.client = [[APPRTCAppClient alloc] init];
self.client.iceServerDelegate = self;
self.client.ICEServerDelegate = self;
self.client.messageHandler = self;
[self.client connectToRoom:url];
return YES;
@ -191,23 +192,23 @@
[self.client sendData:data];
}
#pragma mark - IceServerDelegate method
#pragma mark - ICEServerDelegate method
- (void)onIceServers:(NSArray *)servers {
- (void)onICEServers:(NSArray *)servers {
self.queuedRemoteCandidates = [NSMutableArray array];
self.peerConnectionFactory = [[RTCPeerConnectionFactory alloc] init];
RTCMediaConstraints *constraints = [[RTCMediaConstraints alloc] init];
self.pcObserver = [[PCObserver alloc] initWithDelegate:self];
self.peerConnection =
[self.peerConnectionFactory peerConnectionWithIceServers:servers
[self.peerConnectionFactory peerConnectionWithICEServers:servers
constraints:constraints
delegate:self.pcObserver];
RTCMediaStream *lms =
[self.peerConnectionFactory mediaStreamWithLabel:@"ARDAMS"];
// TODO(hughv): Add video.
[lms addAudioTrack:[self.peerConnectionFactory audioTrackWithId:@"ARDAMSa0"]];
[self.peerConnection addStream:lms withConstraints:constraints];
[self displayLogMessage:@"onIceServers - add local stream."];
[lms addAudioTrack:[self.peerConnectionFactory audioTrackWithID:@"ARDAMSa0"]];
[self.peerConnection addStream:lms constraints:constraints];
[self displayLogMessage:@"onICEServers - add local stream."];
}
#pragma mark - GAEMessageHandler methods
@ -245,14 +246,14 @@
NSString *mid = [objects objectForKey:@"id"];
NSNumber *sdpLineIndex = [objects objectForKey:@"label"];
NSString *sdp = [objects objectForKey:@"candidate"];
RTCIceCandidate *candidate =
[[RTCIceCandidate alloc] initWithMid:mid
RTCICECandidate *candidate =
[[RTCICECandidate alloc] initWithMid:mid
index:sdpLineIndex.intValue
sdp:sdp];
if (self.queuedRemoteCandidates) {
[self.queuedRemoteCandidates addObject:candidate];
} else {
[self.peerConnection addIceCandidate:candidate];
[self.peerConnection addICECandidate:candidate];
}
} else if (([value compare:@"offer"] == NSOrderedSame) ||
([value compare:@"answer"] == NSOrderedSame)) {
@ -283,8 +284,8 @@
#pragma mark - RTCSessionDescriptonDelegate methods
- (void)peerConnection:(RTCPeerConnection *)peerConnection
createSessionDescriptionCompleted:(RTCSessionDescription *)sdp
withError:(NSError *)error {
didCreateSessionDescription:(RTCSessionDescription *)sdp
error:(NSError *)error {
if (error) {
[self displayLogMessage:@"SDP onFailure."];
NSAssert(NO, error.description);
@ -308,7 +309,7 @@
}
- (void)peerConnection:(RTCPeerConnection *)peerConnection
setSessionDescriptionCompletedWithError:(NSError *)error {
didSetSessionDescriptionWithError:(NSError *)error {
if (error) {
[self displayLogMessage:@"SDP onFailure."];
NSAssert(NO, error.description);
@ -333,14 +334,15 @@
self.peerConnection = nil;
self.peerConnectionFactory = nil;
self.pcObserver = nil;
self.client.iceServerDelegate = nil;
self.client.ICEServerDelegate = nil;
self.client.messageHandler = nil;
self.client = nil;
[RTCPeerConnectionFactory deinitializeSSL];
}
- (void)drainRemoteCandidates {
for (RTCIceCandidate *candidate in self.queuedRemoteCandidates) {
[self.peerConnection addIceCandidate:candidate];
for (RTCICECandidate *candidate in self.queuedRemoteCandidates) {
[self.peerConnection addICECandidate:candidate];
}
self.queuedRemoteCandidates = nil;
}

View File

@ -1,71 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIcons</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>Icon.png</string>
</array>
</dict>
</dict>
<key>CFBundleIdentifier</key>
<string>com.Google.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>com.google.apprtcdemo</string>
<key>CFBundleURLSchemes</key>
<array>
<string>apprtc</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UIStatusBarTintParameters</key>
<dict>
<key>UINavigationBar</key>
<dict>
<key>Style</key>
<string>UIBarStyleDefault</string>
<key>Translucent</key>
<false/>
</dict>
</dict>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>12E55</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>AppRTCDemo</string>
<key>CFBundleExecutable</key>
<string>AppRTCDemo</string>
<key>CFBundleIcons</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>Icon.png</string>
</array>
</dict>
</dict>
<key>CFBundleIdentifier</key>
<string>com.google.AppRTCDemo</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>AppRTCDemo</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleResourceSpecification</key>
<string>ResourceRules.plist</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>iPhoneOS</string>
</array>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>com.google.apprtcdemo</string>
<key>CFBundleURLSchemes</key>
<array>
<string>apprtc</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UIStatusBarTintParameters</key>
<dict>
<key>UINavigationBar</key>
<dict>
<key>Style</key>
<string>UIBarStyleDefault</string>
<key>Translucent</key>
<false/>
</dict>
</dict>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>rules</key>
<dict>
<key>.*</key>
<true/>
<key>Info.plist</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>ResourceRules.plist</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>100</real>
</dict>
</dict>
</dict>
</plist>

View File

@ -1,28 +1,3 @@
This directory contains an example iOS client for http://apprtc.appspot.com
Example of building & using the app:
cd <path/to/libjingle>/trunk/talk
- Open libjingle.xcproj. Select iPhone or iPad simulator and build everything.
Then switch to iOS device and build everything. This creates x86 and ARM
archives.
cd examples/ios
./makeLibs.sh
- This will generate fat archives containing both targets and copy them to
./libs.
- This step must be rerun every time you run gclient sync or build the API
libraries.
- Open AppRTCDemo.xcodeproj, select your device or simulator and run.
- If you have any problems deploying for the first time, check the project
properties to ensure that the Bundle Identifier matches your phone
provisioning profile. Or use the simulator as it doesn't require a profile.
- In desktop chrome, navigate to http://apprtc.appspot.com and note the r=<NNN>
room number in the resulting URL.
- Enter that number into the text field on the phone.
- Alternatively, you can background the app and launch Safari. In Safari, open
the url apprtc://apprtc.appspot.com/?r=<NNN> where <NNN> is the room name.
Other options are to put the link in an email and send it to your self.
Clicking on it will launch AppRTCDemo and navigate to the room.
See ../../app/webrtc/objc/README for information on how to use it.

View File

@ -1,30 +0,0 @@
#!/bin/bash -e
if [ "$(dirname $0)" != "." ]; then
echo "$(basename $0) must be run from talk/examples/ios as ./$(basename $0)"
exit 1
fi
rm -rf libs
mkdir libs
cd ../../../xcodebuild/Debug-iphoneos
for f in *.a; do
if [ -f "../Debug-iphonesimulator/$f" ]; then
echo "creating fat static library $f"
lipo -create "$f" "../Debug-iphonesimulator/$f" -output "../../talk/examples/ios/libs/$f"
else
echo ""
echo "$f was not built for the simulator."
echo ""
fi
done
cd ../Debug-iphonesimulator
for f in *.a; do
if [ ! -f "../Debug-iphoneos/$f" ]; then
echo ""
echo "$f was not built for the iPhone."
echo ""
fi
done

View File

@ -163,10 +163,10 @@
'app/webrtc/objc/RTCEnumConverter.h',
'app/webrtc/objc/RTCEnumConverter.mm',
'app/webrtc/objc/RTCI420Frame.mm',
'app/webrtc/objc/RTCIceCandidate+Internal.h',
'app/webrtc/objc/RTCIceCandidate.mm',
'app/webrtc/objc/RTCIceServer+Internal.h',
'app/webrtc/objc/RTCIceServer.mm',
'app/webrtc/objc/RTCICECandidate+Internal.h',
'app/webrtc/objc/RTCICECandidate.mm',
'app/webrtc/objc/RTCICEServer+Internal.h',
'app/webrtc/objc/RTCICEServer.mm',
'app/webrtc/objc/RTCMediaConstraints+Internal.h',
'app/webrtc/objc/RTCMediaConstraints.mm',
'app/webrtc/objc/RTCMediaConstraintsNative.cc',
@ -196,8 +196,8 @@
'app/webrtc/objc/public/RTCAudioSource.h',
'app/webrtc/objc/public/RTCAudioTrack.h',
'app/webrtc/objc/public/RTCI420Frame.h',
'app/webrtc/objc/public/RTCIceCandidate.h',
'app/webrtc/objc/public/RTCIceServer.h',
'app/webrtc/objc/public/RTCICECandidate.h',
'app/webrtc/objc/public/RTCICEServer.h',
'app/webrtc/objc/public/RTCMediaConstraints.h',
'app/webrtc/objc/public/RTCMediaSource.h',
'app/webrtc/objc/public/RTCMediaStream.h',
@ -215,6 +215,11 @@
'app/webrtc/objc/public/RTCVideoSource.h',
'app/webrtc/objc/public/RTCVideoTrack.h',
],
'direct_dependent_settings': {
'include_dirs': [
'<(DEPTH)/talk/app/webrtc/objc/public',
],
},
'include_dirs': [
'<(DEPTH)/talk/app/webrtc',
'<(DEPTH)/talk/app/webrtc/objc',
@ -227,8 +232,6 @@
},
'xcode_settings': {
'CLANG_ENABLE_OBJC_ARC': 'YES',
'CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS': 'NO',
'CLANG_LINK_OBJC_RUNTIME': 'YES',
},
}
]
@ -629,15 +632,12 @@
},
}],
['OS=="ios"', {
# 'dependencies': [
# '<(DEPTH)/third_party/openssl/openssl.gyp:openssl',
# ],
# 'include_dirs': [
# '<(DEPTH)/third_party/openssl/openssl/include',
# ],
'sources': [
'base/scoped_autorelease_pool.mm',
],
'dependencies': [
'../net/third_party/nss/ssl.gyp:libssl',
],
'xcode_settings': {
'OTHER_LDFLAGS': [
'-framework IOKit',
@ -646,9 +646,6 @@
'-framework UIKit',
],
},
'defines': [
'SSL_USE_NSS',
],
}],
['OS=="win"', {
'sources': [

View File

@ -218,6 +218,65 @@
], # targets
}], # OS=="linux" or OS=="win"
['libjingle_objc==1 and OS=="ios"', {
'targets': [
{
'target_name': 'AppRTCDemo',
'type': 'executable',
'product_name': 'AppRTCDemo',
'mac_bundle': 1,
'mac_bundle_resources': [
'examples/ios/AppRTCDemo/ResourceRules.plist',
'examples/ios/AppRTCDemo/en.lproj/APPRTCViewController.xib',
'examples/ios/AppRTCDemo/ios_channel.html',
'examples/ios/Icon.png',
],
'dependencies': [
'libjingle.gyp:libjingle_peerconnection_objc',
],
'conditions': [
['target_arch=="ia32"', {
'dependencies' : [
'<(DEPTH)/testing/iossim/iossim.gyp:iossim#host',
],
}],
],
'sources': [
'examples/ios/AppRTCDemo/APPRTCAppClient.h',
'examples/ios/AppRTCDemo/APPRTCAppClient.m',
'examples/ios/AppRTCDemo/APPRTCAppDelegate.h',
'examples/ios/AppRTCDemo/APPRTCAppDelegate.m',
'examples/ios/AppRTCDemo/APPRTCViewController.h',
'examples/ios/AppRTCDemo/APPRTCViewController.m',
'examples/ios/AppRTCDemo/AppRTCDemo-Prefix.pch',
'examples/ios/AppRTCDemo/GAEChannelClient.h',
'examples/ios/AppRTCDemo/GAEChannelClient.m',
'examples/ios/AppRTCDemo/main.m',
],
'xcode_settings': {
'CLANG_ENABLE_OBJC_ARC': 'YES',
'INFOPLIST_FILE': 'examples/ios/AppRTCDemo/Info.plist',
'OTHER_LDFLAGS': [
'-framework Foundation',
'-framework UIKit',
],
},
'postbuilds': [
{
# Ideally app signing would be a part of gyp.
# Delete if/when that comes to pass.
'postbuild_name': 'Sign AppRTCDemo',
'action': [
'/usr/bin/codesign', '-v', '--force', '--sign',
'<!(security find-identity -p codesigning -v | grep "iPhone Developer" | awk \'{print $2}\')',
'${BUILT_PRODUCTS_DIR}/AppRTCDemo.app',
],
},
],
}, # target AppRTCDemo
], # targets
}], # libjingle_objc==1
['OS=="android"', {
'targets': [
{

View File

@ -480,6 +480,7 @@
'<(infoplist_file)',
],
'xcode_settings': {
'CLANG_ENABLE_OBJC_ARC': 'YES',
'INFOPLIST_FILE': '<(infoplist_file)',
},
'dependencies': [
@ -498,27 +499,13 @@
'app/webrtc/objctests/RTCSessionDescriptionSyncObserver.h',
'app/webrtc/objctests/RTCSessionDescriptionSyncObserver.m',
],
'include_dirs': [
'<(DEPTH)/talk/app/webrtc/objc/public',
],
'conditions': [
[ 'OS=="mac"', {
['OS=="mac" or OS=="ios"', {
'sources': [
# TODO(fischman): figure out if this works for ios or if it
# needs a GUI driver.
'app/webrtc/objctests/mac/main.mm',
],
'xcode_settings': {
'CLANG_ENABLE_OBJC_ARC': 'YES',
'CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS': 'NO',
'CLANG_LINK_OBJC_RUNTIME': 'YES',
# build/common.gypi disables ARC by default for back-compat
# reasons with OSX 10.6. Enabling OBJC runtime and clearing
# LDPLUSPLUS and CC re-enables it. Setting deployment target to
# 10.7 as there are no back-compat issues with ARC.
# https://code.google.com/p/chromium/issues/detail?id=156530
'CC': '',
'LDPLUSPLUS': '',
'macosx_deployment_target': '10.7',
},
}],
],
},