├── .gitignore ├── LICENSE ├── Podfile ├── Podfile.lock ├── Pods ├── AFNetworking │ ├── AFNetworking │ │ ├── AFHTTPRequestOperation.h │ │ ├── AFHTTPRequestOperation.m │ │ ├── AFNetworking.h │ │ ├── AFURLConnectionOperation.h │ │ └── AFURLConnectionOperation.m │ ├── LICENSE │ └── README.md ├── AZSocketIO │ ├── AZSocketIO │ │ ├── AZSocketIO.h │ │ ├── AZSocketIO.m │ │ ├── AZSocketIOPacket.h │ │ ├── AZSocketIOPacket.m │ │ ├── Protocols │ │ │ ├── AZSocketIOTransport.h │ │ │ └── AZSocketIOTransportDelegate.h │ │ └── Transports │ │ │ ├── AZWebsocketTransport.h │ │ │ ├── AZWebsocketTransport.m │ │ │ ├── AZxhrTransport.h │ │ │ └── AZxhrTransport.m │ ├── LICENSE │ └── README.md ├── Manifest.lock ├── Pods.xcodeproj │ └── project.pbxproj ├── SocketRocket │ ├── LICENSE │ ├── README.rst │ └── SocketRocket │ │ ├── SRWebSocket.h │ │ └── SRWebSocket.m ├── TLKSimpleWebRTC │ ├── LICENSE │ └── README.md └── TLKWebRTC │ ├── Classes │ ├── TLKWebRTC.h │ └── TLKWebRTC.m │ ├── LICENSE │ └── README.md ├── ios-demo.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── nigel.xcuserdatad │ └── xcschemes │ ├── ios-demo.xcscheme │ └── xcschememanagement.plist ├── ios-demo.xcworkspace └── contents.xcworkspacedata ├── ios-demo ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ └── Main.storyboard ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json ├── ViewController.h ├── ViewController.m ├── en.lproj │ └── InfoPlist.strings ├── ios-demo-Info.plist ├── ios-demo-Prefix.pch └── main.m └── ios-demoTests ├── en.lproj └── InfoPlist.strings ├── ios-demoTests-Info.plist └── ios_demoTests.m /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | */build/* 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | profile 14 | *.moved-aside 15 | DerivedData 16 | .idea/ 17 | *.hmap 18 | *.xccheckout 19 | *.xcscmblueprint 20 | 21 | Pods/* 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2014 &yet, LLC and otalk contributors 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, "7.0" 3 | 4 | target "ios-demo" do 5 | 6 | pod 'libjingle_peerconnection' 7 | pod 'TLKWebRTC', :git => 'https://github.com/otalk/TLKWebRTC.git' 8 | pod 'TLKSimpleWebRTC', :git => 'https://github.com/otalk/TLKSimpleWebRTC.git' 9 | 10 | end 11 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - AFNetworking (2.6.3): 3 | - AFNetworking/NSURLConnection (= 2.6.3) 4 | - AFNetworking/NSURLSession (= 2.6.3) 5 | - AFNetworking/Reachability (= 2.6.3) 6 | - AFNetworking/Security (= 2.6.3) 7 | - AFNetworking/Serialization (= 2.6.3) 8 | - AFNetworking/UIKit (= 2.6.3) 9 | - AFNetworking/NSURLConnection (2.6.3): 10 | - AFNetworking/Reachability 11 | - AFNetworking/Security 12 | - AFNetworking/Serialization 13 | - AFNetworking/NSURLSession (2.6.3): 14 | - AFNetworking/Reachability 15 | - AFNetworking/Security 16 | - AFNetworking/Serialization 17 | - AFNetworking/Reachability (2.6.3) 18 | - AFNetworking/Security (2.6.3) 19 | - AFNetworking/Serialization (2.6.3) 20 | - AFNetworking/UIKit (2.6.3): 21 | - AFNetworking/NSURLConnection 22 | - AFNetworking/NSURLSession 23 | - AZSocketIO (0.0.6): 24 | - AFNetworking (~> 2.x) 25 | - SocketRocket (~> 0.x) 26 | - libjingle_peerconnection (10604.2.2) 27 | - SocketRocket (0.4.2) 28 | - TLKSimpleWebRTC (1.0.0): 29 | - AZSocketIO (= 0.0.6) 30 | - TLKWebRTC (2.1.0) 31 | 32 | DEPENDENCIES: 33 | - libjingle_peerconnection 34 | - TLKSimpleWebRTC (from `https://github.com/otalk/TLKSimpleWebRTC.git`) 35 | - TLKWebRTC (from `https://github.com/otalk/TLKWebRTC.git`) 36 | 37 | EXTERNAL SOURCES: 38 | TLKSimpleWebRTC: 39 | :git: https://github.com/otalk/TLKSimpleWebRTC.git 40 | TLKWebRTC: 41 | :git: https://github.com/otalk/TLKWebRTC.git 42 | 43 | CHECKOUT OPTIONS: 44 | TLKSimpleWebRTC: 45 | :commit: a459335423e98e4540222a86e457f7778c0d9b05 46 | :git: https://github.com/otalk/TLKSimpleWebRTC.git 47 | TLKWebRTC: 48 | :commit: 9d5f8dfc9791fe9e541a5ad69b8b763fdbbc94d3 49 | :git: https://github.com/otalk/TLKWebRTC.git 50 | 51 | SPEC CHECKSUMS: 52 | AFNetworking: cb8d14a848e831097108418f5d49217339d4eb60 53 | AZSocketIO: 135d76d11e90a0b7509f0f64d448fc8d0cd96e4f 54 | libjingle_peerconnection: e2068e7c6859c64409345931ee035616c893c107 55 | SocketRocket: ffe08119b00ef982f6c37052a4705a057c8494ad 56 | TLKSimpleWebRTC: be2ec60106ed78c034c2a85a2945c49ccf92131f 57 | TLKWebRTC: ac347a4b53024a2e81ff843d3e984bb1337d3d79 58 | 59 | COCOAPODS: 0.39.0 60 | -------------------------------------------------------------------------------- /Pods/AFNetworking/AFNetworking/AFHTTPRequestOperation.h: -------------------------------------------------------------------------------- 1 | // AFHTTPRequestOperation.h 2 | // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | // THE SOFTWARE. 21 | 22 | #import 23 | #import "AFURLConnectionOperation.h" 24 | 25 | NS_ASSUME_NONNULL_BEGIN 26 | 27 | /** 28 | `AFHTTPRequestOperation` is a subclass of `AFURLConnectionOperation` for requests using the HTTP or HTTPS protocols. It encapsulates the concept of acceptable status codes and content types, which determine the success or failure of a request. 29 | */ 30 | @interface AFHTTPRequestOperation : AFURLConnectionOperation 31 | 32 | ///------------------------------------------------ 33 | /// @name Getting HTTP URL Connection Information 34 | ///------------------------------------------------ 35 | 36 | /** 37 | The last HTTP response received by the operation's connection. 38 | */ 39 | @property (readonly, nonatomic, strong, nullable) NSHTTPURLResponse *response; 40 | 41 | /** 42 | Responses sent from the server in data tasks created with `dataTaskWithRequest:success:failure:` and run using the `GET` / `POST` / et al. convenience methods are automatically validated and serialized by the response serializer. By default, this property is set to an AFHTTPResponse serializer, which uses the raw data as its response object. The serializer validates the status code to be in the `2XX` range, denoting success. If the response serializer generates an error in `-responseObjectForResponse:data:error:`, the `failure` callback of the session task or request operation will be executed; otherwise, the `success` callback will be executed. 43 | 44 | @warning `responseSerializer` must not be `nil`. Setting a response serializer will clear out any cached value 45 | */ 46 | @property (nonatomic, strong) AFHTTPResponseSerializer * responseSerializer; 47 | 48 | /** 49 | An object constructed by the `responseSerializer` from the response and response data. Returns `nil` unless the operation `isFinished`, has a `response`, and has `responseData` with non-zero content length. If an error occurs during serialization, `nil` will be returned, and the `error` property will be populated with the serialization error. 50 | */ 51 | @property (readonly, nonatomic, strong, nullable) id responseObject; 52 | 53 | ///----------------------------------------------------------- 54 | /// @name Setting Completion Block Success / Failure Callbacks 55 | ///----------------------------------------------------------- 56 | 57 | /** 58 | Sets the `completionBlock` property with a block that executes either the specified success or failure block, depending on the state of the request on completion. If `error` returns a value, which can be caused by an unacceptable status code or content type, then `failure` is executed. Otherwise, `success` is executed. 59 | 60 | This method should be overridden in subclasses in order to specify the response object passed into the success block. 61 | 62 | @param success The block to be executed on the completion of a successful request. This block has no return value and takes two arguments: the receiver operation and the object constructed from the response data of the request. 63 | @param failure The block to be executed on the completion of an unsuccessful request. This block has no return value and takes two arguments: the receiver operation and the error that occurred during the request. 64 | */ 65 | - (void)setCompletionBlockWithSuccess:(nullable void (^)(AFHTTPRequestOperation *operation, id responseObject))success 66 | failure:(nullable void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; 67 | 68 | @end 69 | 70 | NS_ASSUME_NONNULL_END 71 | -------------------------------------------------------------------------------- /Pods/AFNetworking/AFNetworking/AFHTTPRequestOperation.m: -------------------------------------------------------------------------------- 1 | // AFHTTPRequestOperation.m 2 | // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | // THE SOFTWARE. 21 | 22 | #import "AFHTTPRequestOperation.h" 23 | 24 | static dispatch_queue_t http_request_operation_processing_queue() { 25 | static dispatch_queue_t af_http_request_operation_processing_queue; 26 | static dispatch_once_t onceToken; 27 | dispatch_once(&onceToken, ^{ 28 | af_http_request_operation_processing_queue = dispatch_queue_create("com.alamofire.networking.http-request.processing", DISPATCH_QUEUE_CONCURRENT); 29 | }); 30 | 31 | return af_http_request_operation_processing_queue; 32 | } 33 | 34 | static dispatch_group_t http_request_operation_completion_group() { 35 | static dispatch_group_t af_http_request_operation_completion_group; 36 | static dispatch_once_t onceToken; 37 | dispatch_once(&onceToken, ^{ 38 | af_http_request_operation_completion_group = dispatch_group_create(); 39 | }); 40 | 41 | return af_http_request_operation_completion_group; 42 | } 43 | 44 | #pragma mark - 45 | 46 | @interface AFURLConnectionOperation () 47 | @property (readwrite, nonatomic, strong) NSURLRequest *request; 48 | @property (readwrite, nonatomic, strong) NSURLResponse *response; 49 | @end 50 | 51 | @interface AFHTTPRequestOperation () 52 | @property (readwrite, nonatomic, strong) NSHTTPURLResponse *response; 53 | @property (readwrite, nonatomic, strong) id responseObject; 54 | @property (readwrite, nonatomic, strong) NSError *responseSerializationError; 55 | @property (readwrite, nonatomic, strong) NSRecursiveLock *lock; 56 | @end 57 | 58 | @implementation AFHTTPRequestOperation 59 | @dynamic response; 60 | @dynamic lock; 61 | 62 | - (instancetype)initWithRequest:(NSURLRequest *)urlRequest { 63 | self = [super initWithRequest:urlRequest]; 64 | if (!self) { 65 | return nil; 66 | } 67 | 68 | self.responseSerializer = [AFHTTPResponseSerializer serializer]; 69 | 70 | return self; 71 | } 72 | 73 | - (void)setResponseSerializer:(AFHTTPResponseSerializer *)responseSerializer { 74 | NSParameterAssert(responseSerializer); 75 | 76 | [self.lock lock]; 77 | _responseSerializer = responseSerializer; 78 | self.responseObject = nil; 79 | self.responseSerializationError = nil; 80 | [self.lock unlock]; 81 | } 82 | 83 | - (id)responseObject { 84 | [self.lock lock]; 85 | if (!_responseObject && [self isFinished] && !self.error) { 86 | NSError *error = nil; 87 | self.responseObject = [self.responseSerializer responseObjectForResponse:self.response data:self.responseData error:&error]; 88 | if (error) { 89 | self.responseSerializationError = error; 90 | } 91 | } 92 | [self.lock unlock]; 93 | 94 | return _responseObject; 95 | } 96 | 97 | - (NSError *)error { 98 | if (_responseSerializationError) { 99 | return _responseSerializationError; 100 | } else { 101 | return [super error]; 102 | } 103 | } 104 | 105 | #pragma mark - AFHTTPRequestOperation 106 | 107 | - (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success 108 | failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure 109 | { 110 | // completionBlock is manually nilled out in AFURLConnectionOperation to break the retain cycle. 111 | #pragma clang diagnostic push 112 | #pragma clang diagnostic ignored "-Warc-retain-cycles" 113 | #pragma clang diagnostic ignored "-Wgnu" 114 | self.completionBlock = ^{ 115 | if (self.completionGroup) { 116 | dispatch_group_enter(self.completionGroup); 117 | } 118 | 119 | dispatch_async(http_request_operation_processing_queue(), ^{ 120 | if (self.error) { 121 | if (failure) { 122 | dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{ 123 | failure(self, self.error); 124 | }); 125 | } 126 | } else { 127 | id responseObject = self.responseObject; 128 | if (self.error) { 129 | if (failure) { 130 | dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{ 131 | failure(self, self.error); 132 | }); 133 | } 134 | } else { 135 | if (success) { 136 | dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{ 137 | success(self, responseObject); 138 | }); 139 | } 140 | } 141 | } 142 | 143 | if (self.completionGroup) { 144 | dispatch_group_leave(self.completionGroup); 145 | } 146 | }); 147 | }; 148 | #pragma clang diagnostic pop 149 | } 150 | 151 | #pragma mark - AFURLRequestOperation 152 | 153 | - (void)pause { 154 | [super pause]; 155 | 156 | u_int64_t offset = 0; 157 | if ([self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey]) { 158 | offset = [(NSNumber *)[self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey] unsignedLongLongValue]; 159 | } else { 160 | offset = [(NSData *)[self.outputStream propertyForKey:NSStreamDataWrittenToMemoryStreamKey] length]; 161 | } 162 | 163 | NSMutableURLRequest *mutableURLRequest = [self.request mutableCopy]; 164 | if ([self.response respondsToSelector:@selector(allHeaderFields)] && [[self.response allHeaderFields] valueForKey:@"ETag"]) { 165 | [mutableURLRequest setValue:[[self.response allHeaderFields] valueForKey:@"ETag"] forHTTPHeaderField:@"If-Range"]; 166 | } 167 | [mutableURLRequest setValue:[NSString stringWithFormat:@"bytes=%llu-", offset] forHTTPHeaderField:@"Range"]; 168 | self.request = mutableURLRequest; 169 | } 170 | 171 | #pragma mark - NSSecureCoding 172 | 173 | + (BOOL)supportsSecureCoding { 174 | return YES; 175 | } 176 | 177 | - (id)initWithCoder:(NSCoder *)decoder { 178 | self = [super initWithCoder:decoder]; 179 | if (!self) { 180 | return nil; 181 | } 182 | 183 | self.responseSerializer = [decoder decodeObjectOfClass:[AFHTTPResponseSerializer class] forKey:NSStringFromSelector(@selector(responseSerializer))]; 184 | 185 | return self; 186 | } 187 | 188 | - (void)encodeWithCoder:(NSCoder *)coder { 189 | [super encodeWithCoder:coder]; 190 | 191 | [coder encodeObject:self.responseSerializer forKey:NSStringFromSelector(@selector(responseSerializer))]; 192 | } 193 | 194 | #pragma mark - NSCopying 195 | 196 | - (id)copyWithZone:(NSZone *)zone { 197 | AFHTTPRequestOperation *operation = [super copyWithZone:zone]; 198 | 199 | operation.responseSerializer = [self.responseSerializer copyWithZone:zone]; 200 | operation.completionQueue = self.completionQueue; 201 | operation.completionGroup = self.completionGroup; 202 | 203 | return operation; 204 | } 205 | 206 | @end 207 | -------------------------------------------------------------------------------- /Pods/AFNetworking/AFNetworking/AFNetworking.h: -------------------------------------------------------------------------------- 1 | // AFNetworking.h 2 | // 3 | // Copyright (c) 2013 AFNetworking (http://afnetworking.com/) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | #import 25 | 26 | #ifndef _AFNETWORKING_ 27 | #define _AFNETWORKING_ 28 | 29 | #import "AFURLRequestSerialization.h" 30 | #import "AFURLResponseSerialization.h" 31 | #import "AFSecurityPolicy.h" 32 | #if !TARGET_OS_WATCH 33 | #import "AFNetworkReachabilityManager.h" 34 | #import "AFURLConnectionOperation.h" 35 | #import "AFHTTPRequestOperation.h" 36 | #import "AFHTTPRequestOperationManager.h" 37 | #endif 38 | 39 | #if ( ( defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) || \ 40 | ( defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 ) || \ 41 | TARGET_OS_WATCH ) 42 | #import "AFURLSessionManager.h" 43 | #import "AFHTTPSessionManager.h" 44 | #endif 45 | 46 | #endif /* _AFNETWORKING_ */ 47 | -------------------------------------------------------------------------------- /Pods/AFNetworking/AFNetworking/AFURLConnectionOperation.h: -------------------------------------------------------------------------------- 1 | // AFURLConnectionOperation.h 2 | // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | // THE SOFTWARE. 21 | 22 | #import 23 | 24 | #import 25 | #import "AFURLRequestSerialization.h" 26 | #import "AFURLResponseSerialization.h" 27 | #import "AFSecurityPolicy.h" 28 | 29 | #ifndef NS_DESIGNATED_INITIALIZER 30 | #if __has_attribute(objc_designated_initializer) 31 | #define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) 32 | #else 33 | #define NS_DESIGNATED_INITIALIZER 34 | #endif 35 | #endif 36 | 37 | /** 38 | `AFURLConnectionOperation` is a subclass of `NSOperation` that implements `NSURLConnection` delegate methods. 39 | 40 | ## Subclassing Notes 41 | 42 | This is the base class of all network request operations. You may wish to create your own subclass in order to implement additional `NSURLConnection` delegate methods (see "`NSURLConnection` Delegate Methods" below), or to provide additional properties and/or class constructors. 43 | 44 | If you are creating a subclass that communicates over the HTTP or HTTPS protocols, you may want to consider subclassing `AFHTTPRequestOperation` instead, as it supports specifying acceptable content types or status codes. 45 | 46 | ## NSURLConnection Delegate Methods 47 | 48 | `AFURLConnectionOperation` implements the following `NSURLConnection` delegate methods: 49 | 50 | - `connection:didReceiveResponse:` 51 | - `connection:didReceiveData:` 52 | - `connectionDidFinishLoading:` 53 | - `connection:didFailWithError:` 54 | - `connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:` 55 | - `connection:willCacheResponse:` 56 | - `connectionShouldUseCredentialStorage:` 57 | - `connection:needNewBodyStream:` 58 | - `connection:willSendRequestForAuthenticationChallenge:` 59 | 60 | If any of these methods are overridden in a subclass, they _must_ call the `super` implementation first. 61 | 62 | ## Callbacks and Completion Blocks 63 | 64 | The built-in `completionBlock` provided by `NSOperation` allows for custom behavior to be executed after the request finishes. It is a common pattern for class constructors in subclasses to take callback block parameters, and execute them conditionally in the body of its `completionBlock`. Make sure to handle cancelled operations appropriately when setting a `completionBlock` (i.e. returning early before parsing response data). See the implementation of any of the `AFHTTPRequestOperation` subclasses for an example of this. 65 | 66 | Subclasses are strongly discouraged from overriding `setCompletionBlock:`, as `AFURLConnectionOperation`'s implementation includes a workaround to mitigate retain cycles, and what Apple rather ominously refers to as ["The Deallocation Problem"](http://developer.apple.com/library/ios/#technotes/tn2109/). 67 | 68 | ## SSL Pinning 69 | 70 | Relying on the CA trust model to validate SSL certificates exposes your app to security vulnerabilities, such as man-in-the-middle attacks. For applications that connect to known servers, SSL certificate pinning provides an increased level of security, by checking server certificate validity against those specified in the app bundle. 71 | 72 | SSL with certificate pinning is strongly recommended for any application that transmits sensitive information to an external webservice. 73 | 74 | Connections will be validated on all matching certificates with a `.cer` extension in the bundle root. 75 | 76 | ## NSCoding & NSCopying Conformance 77 | 78 | `AFURLConnectionOperation` conforms to the `NSCoding` and `NSCopying` protocols, allowing operations to be archived to disk, and copied in memory, respectively. However, because of the intrinsic limitations of capturing the exact state of an operation at a particular moment, there are some important caveats to keep in mind: 79 | 80 | ### NSCoding Caveats 81 | 82 | - Encoded operations do not include any block or stream properties. Be sure to set `completionBlock`, `outputStream`, and any callback blocks as necessary when using `-initWithCoder:` or `NSKeyedUnarchiver`. 83 | - Operations are paused on `encodeWithCoder:`. If the operation was encoded while paused or still executing, its archived state will return `YES` for `isReady`. Otherwise, the state of an operation when encoding will remain unchanged. 84 | 85 | ### NSCopying Caveats 86 | 87 | - `-copy` and `-copyWithZone:` return a new operation with the `NSURLRequest` of the original. So rather than an exact copy of the operation at that particular instant, the copying mechanism returns a completely new instance, which can be useful for retrying operations. 88 | - A copy of an operation will not include the `outputStream` of the original. 89 | - Operation copies do not include `completionBlock`, as it often strongly captures a reference to `self`, which would otherwise have the unintuitive side-effect of pointing to the _original_ operation when copied. 90 | */ 91 | 92 | NS_ASSUME_NONNULL_BEGIN 93 | 94 | @interface AFURLConnectionOperation : NSOperation 95 | 96 | ///------------------------------- 97 | /// @name Accessing Run Loop Modes 98 | ///------------------------------- 99 | 100 | /** 101 | The run loop modes in which the operation will run on the network thread. By default, this is a single-member set containing `NSRunLoopCommonModes`. 102 | */ 103 | @property (nonatomic, strong) NSSet *runLoopModes; 104 | 105 | ///----------------------------------------- 106 | /// @name Getting URL Connection Information 107 | ///----------------------------------------- 108 | 109 | /** 110 | The request used by the operation's connection. 111 | */ 112 | @property (readonly, nonatomic, strong) NSURLRequest *request; 113 | 114 | /** 115 | The last response received by the operation's connection. 116 | */ 117 | @property (readonly, nonatomic, strong, nullable) NSURLResponse *response; 118 | 119 | /** 120 | The error, if any, that occurred in the lifecycle of the request. 121 | */ 122 | @property (readonly, nonatomic, strong, nullable) NSError *error; 123 | 124 | ///---------------------------- 125 | /// @name Getting Response Data 126 | ///---------------------------- 127 | 128 | /** 129 | The data received during the request. 130 | */ 131 | @property (readonly, nonatomic, strong, nullable) NSData *responseData; 132 | 133 | /** 134 | The string representation of the response data. 135 | */ 136 | @property (readonly, nonatomic, copy, nullable) NSString *responseString; 137 | 138 | /** 139 | The string encoding of the response. 140 | 141 | If the response does not specify a valid string encoding, `responseStringEncoding` will return `NSUTF8StringEncoding`. 142 | */ 143 | @property (readonly, nonatomic, assign) NSStringEncoding responseStringEncoding; 144 | 145 | ///------------------------------- 146 | /// @name Managing URL Credentials 147 | ///------------------------------- 148 | 149 | /** 150 | Whether the URL connection should consult the credential storage for authenticating the connection. `YES` by default. 151 | 152 | This is the value that is returned in the `NSURLConnectionDelegate` method `-connectionShouldUseCredentialStorage:`. 153 | */ 154 | @property (nonatomic, assign) BOOL shouldUseCredentialStorage; 155 | 156 | /** 157 | The credential used for authentication challenges in `-connection:didReceiveAuthenticationChallenge:`. 158 | 159 | This will be overridden by any shared credentials that exist for the username or password of the request URL, if present. 160 | */ 161 | @property (nonatomic, strong, nullable) NSURLCredential *credential; 162 | 163 | ///------------------------------- 164 | /// @name Managing Security Policy 165 | ///------------------------------- 166 | 167 | /** 168 | The security policy used to evaluate server trust for secure connections. 169 | */ 170 | @property (nonatomic, strong) AFSecurityPolicy *securityPolicy; 171 | 172 | ///------------------------ 173 | /// @name Accessing Streams 174 | ///------------------------ 175 | 176 | /** 177 | The input stream used to read data to be sent during the request. 178 | 179 | This property acts as a proxy to the `HTTPBodyStream` property of `request`. 180 | */ 181 | @property (nonatomic, strong) NSInputStream *inputStream; 182 | 183 | /** 184 | The output stream that is used to write data received until the request is finished. 185 | 186 | By default, data is accumulated into a buffer that is stored into `responseData` upon completion of the request, with the intermediary `outputStream` property set to `nil`. When `outputStream` is set, the data will not be accumulated into an internal buffer, and as a result, the `responseData` property of the completed request will be `nil`. The output stream will be scheduled in the network thread runloop upon being set. 187 | */ 188 | @property (nonatomic, strong, nullable) NSOutputStream *outputStream; 189 | 190 | ///--------------------------------- 191 | /// @name Managing Callback Queues 192 | ///--------------------------------- 193 | 194 | /** 195 | The dispatch queue for `completionBlock`. If `NULL` (default), the main queue is used. 196 | */ 197 | #if OS_OBJECT_USE_OBJC 198 | @property (nonatomic, strong, nullable) dispatch_queue_t completionQueue; 199 | #else 200 | @property (nonatomic, assign, nullable) dispatch_queue_t completionQueue; 201 | #endif 202 | 203 | /** 204 | The dispatch group for `completionBlock`. If `NULL` (default), a private dispatch group is used. 205 | */ 206 | #if OS_OBJECT_USE_OBJC 207 | @property (nonatomic, strong, nullable) dispatch_group_t completionGroup; 208 | #else 209 | @property (nonatomic, assign, nullable) dispatch_group_t completionGroup; 210 | #endif 211 | 212 | ///--------------------------------------------- 213 | /// @name Managing Request Operation Information 214 | ///--------------------------------------------- 215 | 216 | /** 217 | The user info dictionary for the receiver. 218 | */ 219 | @property (nonatomic, strong) NSDictionary *userInfo; 220 | // FIXME: It doesn't seem that this userInfo is used anywhere in the implementation. 221 | 222 | ///------------------------------------------------------ 223 | /// @name Initializing an AFURLConnectionOperation Object 224 | ///------------------------------------------------------ 225 | 226 | /** 227 | Initializes and returns a newly allocated operation object with a url connection configured with the specified url request. 228 | 229 | This is the designated initializer. 230 | 231 | @param urlRequest The request object to be used by the operation connection. 232 | */ 233 | - (instancetype)initWithRequest:(NSURLRequest *)urlRequest NS_DESIGNATED_INITIALIZER; 234 | 235 | ///---------------------------------- 236 | /// @name Pausing / Resuming Requests 237 | ///---------------------------------- 238 | 239 | /** 240 | Pauses the execution of the request operation. 241 | 242 | A paused operation returns `NO` for `-isReady`, `-isExecuting`, and `-isFinished`. As such, it will remain in an `NSOperationQueue` until it is either cancelled or resumed. Pausing a finished, cancelled, or paused operation has no effect. 243 | */ 244 | - (void)pause; 245 | 246 | /** 247 | Whether the request operation is currently paused. 248 | 249 | @return `YES` if the operation is currently paused, otherwise `NO`. 250 | */ 251 | - (BOOL)isPaused; 252 | 253 | /** 254 | Resumes the execution of the paused request operation. 255 | 256 | Pause/Resume behavior varies depending on the underlying implementation for the operation class. In its base implementation, resuming a paused requests restarts the original request. However, since HTTP defines a specification for how to request a specific content range, `AFHTTPRequestOperation` will resume downloading the request from where it left off, instead of restarting the original request. 257 | */ 258 | - (void)resume; 259 | 260 | ///---------------------------------------------- 261 | /// @name Configuring Backgrounding Task Behavior 262 | ///---------------------------------------------- 263 | 264 | /** 265 | Specifies that the operation should continue execution after the app has entered the background, and the expiration handler for that background task. 266 | 267 | @param handler A handler to be called shortly before the application’s remaining background time reaches 0. The handler is wrapped in a block that cancels the operation, and cleans up and marks the end of execution, unlike the `handler` parameter in `UIApplication -beginBackgroundTaskWithExpirationHandler:`, which expects this to be done in the handler itself. The handler is called synchronously on the main thread, thus blocking the application’s suspension momentarily while the application is notified. 268 | */ 269 | #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) 270 | - (void)setShouldExecuteAsBackgroundTaskWithExpirationHandler:(nullable void (^)(void))handler NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extensions."); 271 | #endif 272 | 273 | ///--------------------------------- 274 | /// @name Setting Progress Callbacks 275 | ///--------------------------------- 276 | 277 | /** 278 | Sets a callback to be called when an undetermined number of bytes have been uploaded to the server. 279 | 280 | @param block A block object to be called when an undetermined number of bytes have been uploaded to the server. This block has no return value and takes three arguments: the number of bytes written since the last time the upload progress block was called, the total bytes written, and the total bytes expected to be written during the request, as initially determined by the length of the HTTP body. This block may be called multiple times, and will execute on the main thread. 281 | */ 282 | - (void)setUploadProgressBlock:(nullable void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))block; 283 | 284 | /** 285 | Sets a callback to be called when an undetermined number of bytes have been downloaded from the server. 286 | 287 | @param block A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes three arguments: the number of bytes read since the last time the download progress block was called, the total bytes read, and the total bytes expected to be read during the request, as initially determined by the expected content size of the `NSHTTPURLResponse` object. This block may be called multiple times, and will execute on the main thread. 288 | */ 289 | - (void)setDownloadProgressBlock:(nullable void (^)(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead))block; 290 | 291 | ///------------------------------------------------- 292 | /// @name Setting NSURLConnection Delegate Callbacks 293 | ///------------------------------------------------- 294 | 295 | /** 296 | Sets a block to be executed when the connection will authenticate a challenge in order to download its request, as handled by the `NSURLConnectionDelegate` method `connection:willSendRequestForAuthenticationChallenge:`. 297 | 298 | @param block A block object to be executed when the connection will authenticate a challenge in order to download its request. The block has no return type and takes two arguments: the URL connection object, and the challenge that must be authenticated. This block must invoke one of the challenge-responder methods (NSURLAuthenticationChallengeSender protocol). 299 | 300 | If `allowsInvalidSSLCertificate` is set to YES, `connection:willSendRequestForAuthenticationChallenge:` will attempt to have the challenge sender use credentials with invalid SSL certificates. 301 | */ 302 | - (void)setWillSendRequestForAuthenticationChallengeBlock:(nullable void (^)(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge))block; 303 | 304 | /** 305 | Sets a block to be executed when the server redirects the request from one URL to another URL, or when the request URL changed by the `NSURLProtocol` subclass handling the request in order to standardize its format, as handled by the `NSURLConnectionDataDelegate` method `connection:willSendRequest:redirectResponse:`. 306 | 307 | @param block A block object to be executed when the request URL was changed. The block returns an `NSURLRequest` object, the URL request to redirect, and takes three arguments: the URL connection object, the the proposed redirected request, and the URL response that caused the redirect. 308 | */ 309 | - (void)setRedirectResponseBlock:(nullable NSURLRequest * (^)(NSURLConnection *connection, NSURLRequest *request, NSURLResponse *redirectResponse))block; 310 | 311 | 312 | /** 313 | Sets a block to be executed to modify the response a connection will cache, if any, as handled by the `NSURLConnectionDelegate` method `connection:willCacheResponse:`. 314 | 315 | @param block A block object to be executed to determine what response a connection will cache, if any. The block returns an `NSCachedURLResponse` object, the cached response to store in memory or `nil` to prevent the response from being cached, and takes two arguments: the URL connection object, and the cached response provided for the request. 316 | */ 317 | - (void)setCacheResponseBlock:(nullable NSCachedURLResponse * (^)(NSURLConnection *connection, NSCachedURLResponse *cachedResponse))block; 318 | 319 | /// 320 | 321 | /** 322 | 323 | */ 324 | + (NSArray *)batchOfRequestOperations:(nullable NSArray *)operations 325 | progressBlock:(nullable void (^)(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations))progressBlock 326 | completionBlock:(nullable void (^)(NSArray *operations))completionBlock; 327 | 328 | @end 329 | 330 | ///-------------------- 331 | /// @name Notifications 332 | ///-------------------- 333 | 334 | /** 335 | Posted when an operation begins executing. 336 | */ 337 | FOUNDATION_EXPORT NSString * const AFNetworkingOperationDidStartNotification; 338 | 339 | /** 340 | Posted when an operation finishes. 341 | */ 342 | FOUNDATION_EXPORT NSString * const AFNetworkingOperationDidFinishNotification; 343 | 344 | NS_ASSUME_NONNULL_END 345 | -------------------------------------------------------------------------------- /Pods/AFNetworking/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Pods/AFNetworking/README.md: -------------------------------------------------------------------------------- 1 |

2 | AFNetworking 3 |

4 | 5 | [![Build Status](https://travis-ci.org/AFNetworking/AFNetworking.svg)](https://travis-ci.org/AFNetworking/AFNetworking) 6 | 7 | AFNetworking is a delightful networking library for iOS and Mac OS X. It's built on top of the [Foundation URL Loading System](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html), extending the powerful high-level networking abstractions built into Cocoa. It has a modular architecture with well-designed, feature-rich APIs that are a joy to use. 8 | 9 | Perhaps the most important feature of all, however, is the amazing community of developers who use and contribute to AFNetworking every day. AFNetworking powers some of the most popular and critically-acclaimed apps on the iPhone, iPad, and Mac. 10 | 11 | Choose AFNetworking for your next project, or migrate over your existing projects—you'll be happy you did! 12 | 13 | ## How To Get Started 14 | 15 | - [Download AFNetworking](https://github.com/AFNetworking/AFNetworking/archive/master.zip) and try out the included Mac and iPhone example apps 16 | - Read the ["Getting Started" guide](https://github.com/AFNetworking/AFNetworking/wiki/Getting-Started-with-AFNetworking), [FAQ](https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-FAQ), or [other articles on the Wiki](https://github.com/AFNetworking/AFNetworking/wiki) 17 | - Check out the [documentation](http://cocoadocs.org/docsets/AFNetworking/) for a comprehensive look at all of the APIs available in AFNetworking 18 | - Read the [AFNetworking 2.0 Migration Guide](https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-2.0-Migration-Guide) for an overview of the architectural changes from 1.0. 19 | 20 | ## Communication 21 | 22 | - If you **need help**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/afnetworking). (Tag 'afnetworking') 23 | - If you'd like to **ask a general question**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/afnetworking). 24 | - If you **found a bug**, _and can provide steps to reliably reproduce it_, open an issue. 25 | - If you **have a feature request**, open an issue. 26 | - If you **want to contribute**, submit a pull request. 27 | 28 | ### Installation with CocoaPods 29 | 30 | [CocoaPods](https://cocoapods.org/) is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries like AFNetworking in your projects. See the ["Getting Started" guide for more information](https://github.com/AFNetworking/AFNetworking/wiki/Getting-Started-with-AFNetworking). 31 | 32 | #### Podfile 33 | 34 | ```ruby 35 | platform :ios, '7.0' 36 | pod "AFNetworking", "~> 2.0" 37 | ``` 38 | 39 | ## Requirements 40 | 41 | | AFNetworking Version | Minimum iOS Target | Minimum OS X Target | Notes | 42 | |:--------------------:|:---------------------------:|:----------------------------:|:-------------------------------------------------------------------------:| 43 | | 2.x | iOS 6 | OS X 10.8 | Xcode 5 is required. `NSURLSession` subspec requires iOS 7 or OS X 10.9. | 44 | | [1.x](https://github.com/AFNetworking/AFNetworking/tree/1.x) | iOS 5 | Mac OS X 10.7 | | 45 | | [0.10.x](https://github.com/AFNetworking/AFNetworking/tree/0.10.x) | iOS 4 | Mac OS X 10.6 | | 46 | 47 | (OS X projects must support [64-bit with modern Cocoa runtime](https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtVersionsPlatforms.html)). 48 | 49 | > Programming in Swift? Try [Alamofire](https://github.com/Alamofire/Alamofire) for a more conventional set of APIs. 50 | 51 | ## Architecture 52 | 53 | ### NSURLConnection 54 | 55 | - `AFURLConnectionOperation` 56 | - `AFHTTPRequestOperation` 57 | - `AFHTTPRequestOperationManager` 58 | 59 | ### NSURLSession _(iOS 7 / Mac OS X 10.9)_ 60 | 61 | - `AFURLSessionManager` 62 | - `AFHTTPSessionManager` 63 | 64 | ### Serialization 65 | 66 | * `` 67 | - `AFHTTPRequestSerializer` 68 | - `AFJSONRequestSerializer` 69 | - `AFPropertyListRequestSerializer` 70 | * `` 71 | - `AFHTTPResponseSerializer` 72 | - `AFJSONResponseSerializer` 73 | - `AFXMLParserResponseSerializer` 74 | - `AFXMLDocumentResponseSerializer` _(Mac OS X)_ 75 | - `AFPropertyListResponseSerializer` 76 | - `AFImageResponseSerializer` 77 | - `AFCompoundResponseSerializer` 78 | 79 | ### Additional Functionality 80 | 81 | - `AFSecurityPolicy` 82 | - `AFNetworkReachabilityManager` 83 | 84 | ## Usage 85 | 86 | ### HTTP Request Operation Manager 87 | 88 | `AFHTTPRequestOperationManager` encapsulates the common patterns of communicating with a web application over HTTP, including request creation, response serialization, network reachability monitoring, and security, as well as request operation management. 89 | 90 | #### `GET` Request 91 | 92 | ```objective-c 93 | AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 94 | [manager GET:@"http://example.com/resources.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { 95 | NSLog(@"JSON: %@", responseObject); 96 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 97 | NSLog(@"Error: %@", error); 98 | }]; 99 | ``` 100 | 101 | #### `POST` URL-Form-Encoded Request 102 | 103 | ```objective-c 104 | AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 105 | NSDictionary *parameters = @{@"foo": @"bar"}; 106 | [manager POST:@"http://example.com/resources.json" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { 107 | NSLog(@"JSON: %@", responseObject); 108 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 109 | NSLog(@"Error: %@", error); 110 | }]; 111 | ``` 112 | 113 | #### `POST` Multi-Part Request 114 | 115 | ```objective-c 116 | AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 117 | NSDictionary *parameters = @{@"foo": @"bar"}; 118 | NSURL *filePath = [NSURL fileURLWithPath:@"file://path/to/image.png"]; 119 | [manager POST:@"http://example.com/resources.json" parameters:parameters constructingBodyWithBlock:^(id formData) { 120 | [formData appendPartWithFileURL:filePath name:@"image" error:nil]; 121 | } success:^(AFHTTPRequestOperation *operation, id responseObject) { 122 | NSLog(@"Success: %@", responseObject); 123 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 124 | NSLog(@"Error: %@", error); 125 | }]; 126 | ``` 127 | 128 | --- 129 | 130 | ### AFURLSessionManager 131 | 132 | `AFURLSessionManager` creates and manages an `NSURLSession` object based on a specified `NSURLSessionConfiguration` object, which conforms to ``, ``, ``, and ``. 133 | 134 | #### Creating a Download Task 135 | 136 | ```objective-c 137 | NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; 138 | AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration]; 139 | 140 | NSURL *URL = [NSURL URLWithString:@"http://example.com/download.zip"]; 141 | NSURLRequest *request = [NSURLRequest requestWithURL:URL]; 142 | 143 | NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) { 144 | NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil]; 145 | return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]]; 146 | } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) { 147 | NSLog(@"File downloaded to: %@", filePath); 148 | }]; 149 | [downloadTask resume]; 150 | ``` 151 | 152 | #### Creating an Upload Task 153 | 154 | ```objective-c 155 | NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; 156 | AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration]; 157 | 158 | NSURL *URL = [NSURL URLWithString:@"http://example.com/upload"]; 159 | NSURLRequest *request = [NSURLRequest requestWithURL:URL]; 160 | 161 | NSURL *filePath = [NSURL fileURLWithPath:@"file://path/to/image.png"]; 162 | NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromFile:filePath progress:nil completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { 163 | if (error) { 164 | NSLog(@"Error: %@", error); 165 | } else { 166 | NSLog(@"Success: %@ %@", response, responseObject); 167 | } 168 | }]; 169 | [uploadTask resume]; 170 | ``` 171 | 172 | #### Creating an Upload Task for a Multi-Part Request, with Progress 173 | 174 | ```objective-c 175 | NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"http://example.com/upload" parameters:nil constructingBodyWithBlock:^(id formData) { 176 | [formData appendPartWithFileURL:[NSURL fileURLWithPath:@"file://path/to/image.jpg"] name:@"file" fileName:@"filename.jpg" mimeType:@"image/jpeg" error:nil]; 177 | } error:nil]; 178 | 179 | AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; 180 | NSProgress *progress = nil; 181 | 182 | NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithStreamedRequest:request progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { 183 | if (error) { 184 | NSLog(@"Error: %@", error); 185 | } else { 186 | NSLog(@"%@ %@", response, responseObject); 187 | } 188 | }]; 189 | 190 | [uploadTask resume]; 191 | ``` 192 | 193 | #### Creating a Data Task 194 | 195 | ```objective-c 196 | NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; 197 | AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration]; 198 | 199 | NSURL *URL = [NSURL URLWithString:@"http://example.com/upload"]; 200 | NSURLRequest *request = [NSURLRequest requestWithURL:URL]; 201 | 202 | NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { 203 | if (error) { 204 | NSLog(@"Error: %@", error); 205 | } else { 206 | NSLog(@"%@ %@", response, responseObject); 207 | } 208 | }]; 209 | [dataTask resume]; 210 | ``` 211 | 212 | --- 213 | 214 | ### Request Serialization 215 | 216 | Request serializers create requests from URL strings, encoding parameters as either a query string or HTTP body. 217 | 218 | ```objective-c 219 | NSString *URLString = @"http://example.com"; 220 | NSDictionary *parameters = @{@"foo": @"bar", @"baz": @[@1, @2, @3]}; 221 | ``` 222 | 223 | #### Query String Parameter Encoding 224 | 225 | ```objective-c 226 | [[AFHTTPRequestSerializer serializer] requestWithMethod:@"GET" URLString:URLString parameters:parameters error:nil]; 227 | ``` 228 | 229 | GET http://example.com?foo=bar&baz[]=1&baz[]=2&baz[]=3 230 | 231 | #### URL Form Parameter Encoding 232 | 233 | ```objective-c 234 | [[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:URLString parameters:parameters]; 235 | ``` 236 | 237 | POST http://example.com/ 238 | Content-Type: application/x-www-form-urlencoded 239 | 240 | foo=bar&baz[]=1&baz[]=2&baz[]=3 241 | 242 | #### JSON Parameter Encoding 243 | 244 | ```objective-c 245 | [[AFJSONRequestSerializer serializer] requestWithMethod:@"POST" URLString:URLString parameters:parameters]; 246 | ``` 247 | 248 | POST http://example.com/ 249 | Content-Type: application/json 250 | 251 | {"foo": "bar", "baz": [1,2,3]} 252 | 253 | --- 254 | 255 | ### Network Reachability Manager 256 | 257 | `AFNetworkReachabilityManager` monitors the reachability of domains, and addresses for both WWAN and WiFi network interfaces. 258 | 259 | * Do not use Reachability to determine if the original request should be sent. 260 | * You should try to send it. 261 | * You can use Reachability to determine when a request should be automatically retried. 262 | * Although it may still fail, a Reachability notification that the connectivity is available is a good time to retry something. 263 | * Network reachability is a useful tool for determining why a request might have failed. 264 | * After a network request has failed, telling the user they're offline is better than giving them a more technical but accurate error, such as "request timed out." 265 | 266 | See also [WWDC 2012 session 706, "Networking Best Practices."](https://developer.apple.com/videos/play/wwdc2012-706/). 267 | 268 | #### Shared Network Reachability 269 | 270 | ```objective-c 271 | [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { 272 | NSLog(@"Reachability: %@", AFStringFromNetworkReachabilityStatus(status)); 273 | }]; 274 | 275 | [[AFNetworkReachabilityManager sharedManager] startMonitoring]; 276 | ``` 277 | 278 | #### HTTP Manager Reachability 279 | 280 | ```objective-c 281 | NSURL *baseURL = [NSURL URLWithString:@"http://example.com/"]; 282 | AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:baseURL]; 283 | 284 | NSOperationQueue *operationQueue = manager.operationQueue; 285 | [manager.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { 286 | switch (status) { 287 | case AFNetworkReachabilityStatusReachableViaWWAN: 288 | case AFNetworkReachabilityStatusReachableViaWiFi: 289 | [operationQueue setSuspended:NO]; 290 | break; 291 | case AFNetworkReachabilityStatusNotReachable: 292 | default: 293 | [operationQueue setSuspended:YES]; 294 | break; 295 | } 296 | }]; 297 | 298 | [manager.reachabilityManager startMonitoring]; 299 | ``` 300 | 301 | --- 302 | 303 | ### Security Policy 304 | 305 | `AFSecurityPolicy` evaluates server trust against pinned X.509 certificates and public keys over secure connections. 306 | 307 | Adding pinned SSL certificates to your app helps prevent man-in-the-middle attacks and other vulnerabilities. Applications dealing with sensitive customer data or financial information are strongly encouraged to route all communication over an HTTPS connection with SSL pinning configured and enabled. 308 | 309 | #### Allowing Invalid SSL Certificates 310 | 311 | ```objective-c 312 | AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 313 | manager.securityPolicy.allowInvalidCertificates = YES; // not recommended for production 314 | ``` 315 | 316 | --- 317 | 318 | ### AFHTTPRequestOperation 319 | 320 | `AFHTTPRequestOperation` is a subclass of `AFURLConnectionOperation` for requests using the HTTP or HTTPS protocols. It encapsulates the concept of acceptable status codes and content types, which determine the success or failure of a request. 321 | 322 | Although `AFHTTPRequestOperationManager` is usually the best way to go about making requests, `AFHTTPRequestOperation` can be used by itself. 323 | 324 | #### `GET` with `AFHTTPRequestOperation` 325 | 326 | ```objective-c 327 | NSURL *URL = [NSURL URLWithString:@"http://example.com/resources/123.json"]; 328 | NSURLRequest *request = [NSURLRequest requestWithURL:URL]; 329 | AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request]; 330 | op.responseSerializer = [AFJSONResponseSerializer serializer]; 331 | [op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { 332 | NSLog(@"JSON: %@", responseObject); 333 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 334 | NSLog(@"Error: %@", error); 335 | }]; 336 | [[NSOperationQueue mainQueue] addOperation:op]; 337 | ``` 338 | 339 | #### Batch of Operations 340 | 341 | ```objective-c 342 | NSMutableArray *mutableOperations = [NSMutableArray array]; 343 | for (NSURL *fileURL in filesToUpload) { 344 | NSURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"http://example.com/upload" parameters:nil constructingBodyWithBlock:^(id formData) { 345 | [formData appendPartWithFileURL:fileURL name:@"images[]" error:nil]; 346 | }]; 347 | 348 | AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; 349 | 350 | [mutableOperations addObject:operation]; 351 | } 352 | 353 | NSArray *operations = [AFURLConnectionOperation batchOfRequestOperations:@[...] progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) { 354 | NSLog(@"%lu of %lu complete", numberOfFinishedOperations, totalNumberOfOperations); 355 | } completionBlock:^(NSArray *operations) { 356 | NSLog(@"All operations in batch complete"); 357 | }]; 358 | [[NSOperationQueue mainQueue] addOperations:operations waitUntilFinished:NO]; 359 | ``` 360 | 361 | ## Unit Tests 362 | 363 | AFNetworking includes a suite of unit tests within the Tests subdirectory. In order to run the unit tests, you must install the testing dependencies via [CocoaPods](https://cocoapods.org/): 364 | 365 | $ cd Tests 366 | $ pod install 367 | 368 | Once testing dependencies are installed, you can execute the test suite via the 'iOS Tests' and 'OS X Tests' schemes within Xcode. 369 | 370 | ### Running Tests from the Command Line 371 | 372 | Tests can also be run from the command line or within a continuous integration environment. The [`xcpretty`](https://github.com/supermarin/xcpretty) utility needs to be installed before running the tests from the command line: 373 | 374 | $ gem install xcpretty 375 | 376 | Once `xcpretty` is installed, you can execute the suite via `rake test`. 377 | 378 | ## Credits 379 | 380 | AFNetworking is owned and maintained by the [Alamofire Software Foundation](http://alamofire.org). 381 | 382 | AFNetworking was originally created by [Scott Raymond](https://github.com/sco/) and [Mattt Thompson](https://github.com/mattt/) in the development of [Gowalla for iPhone](https://en.wikipedia.org/wiki/Gowalla). 383 | 384 | AFNetworking's logo was designed by [Alan Defibaugh](http://www.alandefibaugh.com/). 385 | 386 | And most of all, thanks to AFNetworking's [growing list of contributors](https://github.com/AFNetworking/AFNetworking/graphs/contributors). 387 | 388 | ### Security Disclosure 389 | 390 | If you believe you have identified a security vulnerability with AFNetworking, you should report it as soon as possible via email to security@alamofire.org. Please do not post it to a public issue tracker. 391 | 392 | ## License 393 | 394 | AFNetworking is released under the MIT license. See LICENSE for details. 395 | -------------------------------------------------------------------------------- /Pods/AZSocketIO/AZSocketIO/AZSocketIO.h: -------------------------------------------------------------------------------- 1 | // 2 | // AZSocketIO.h 3 | // AZSocketIO 4 | // 5 | // Created by Patrick Shields on 4/6/12. 6 | // Copyright 2012 Patrick Shields 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // 20 | 21 | #import 22 | #import "AZSocketIOTransportDelegate.h" 23 | 24 | @protocol AZSocketIOTransport; 25 | 26 | #define AZDOMAIN @"AZSocketIO" 27 | 28 | extern NSString * const AZSocketIODefaultNamespace; 29 | 30 | typedef void (^MessageReceivedBlock)(id data); 31 | typedef void (^EventReceivedBlock)(NSString *eventName, id data); 32 | typedef void (^ConnectedBlock)(); 33 | typedef void (^DisconnectedBlock)(); 34 | typedef void (^ErrorBlock)(NSError *error); 35 | 36 | typedef void (^ACKCallback)(); 37 | typedef void (^ACKCallbackWithArgs)(NSArray *args); 38 | 39 | /** 40 | The socket state according to socket.io specs ( https://github.com/LearnBoost/socket.io-spec#anatomy-of-a-socketio-socket ) 41 | */ 42 | typedef enum { 43 | AZSocketIOStateDisconnected, 44 | AZSocketIOStateDisconnecting, 45 | AZSocketIOStateConnecting, 46 | AZSocketIOStateConnected, 47 | } AZSocketIOState; 48 | 49 | NS_ENUM(NSUInteger, AZSocketIOError) { 50 | AZSocketIOErrorConnection = 100, 51 | AZSocketIOErrorArgs = 3000, 52 | }; 53 | 54 | /** 55 | `AZSocketIO` provides a mechanism for connecting to and interacting with a socket.io compliant server. It maintains the actual transport connection and provides facilities for sending all types of messages. 56 | */ 57 | @interface AZSocketIO : NSObject 58 | /** 59 | The hostname of the socket.io server 60 | */ 61 | @property(nonatomic, strong, readonly)NSString *host; 62 | /** 63 | The port the socket.io server is running on 64 | */ 65 | @property(nonatomic, strong, readonly)NSString *port; 66 | /** 67 | Determines whether AZSocketIO will use secured connections such as wss or https 68 | */ 69 | @property(nonatomic, assign, readonly)BOOL secureConnections; 70 | /** 71 | The namespace / endpoint of the socket.io server 72 | */ 73 | @property(nonatomic, copy, readonly)NSString *endpoint; 74 | /** 75 | Contains the current state of the connection. 76 | 77 | @warning This property may conflict with the state of the transport during state changes. 78 | */ 79 | @property(nonatomic, readonly)AZSocketIOState state; 80 | /** 81 | The set of transports the client wishes to use. Defaults to "websocket" and "xhr-polling". 82 | */ 83 | @property(nonatomic, strong)NSMutableSet *transports; 84 | /** 85 | The currently active transport, if one exists. 86 | */ 87 | @property(nonatomic, strong)id transport; 88 | 89 | /** 90 | This block will be called on the reception of any non-protocol message. 91 | */ 92 | @property(nonatomic, copy)MessageReceivedBlock messageReceivedBlock; 93 | /** 94 | This block will be called on the reception of any event. 95 | */ 96 | @property(nonatomic, copy)EventReceivedBlock eventReceivedBlock; 97 | /** 98 | This block will be called after the instance has disconnected 99 | */ 100 | @property(nonatomic, copy)DisconnectedBlock disconnectedBlock; 101 | /** 102 | This block will be called when an error is reported by the socket.io server or the connection becomes unusable. 103 | */ 104 | @property(nonatomic, copy)ErrorBlock errorBlock; 105 | 106 | ///---------------------------------------------------- 107 | /// @name Creating and Connecting to a Socket.io Server 108 | ///---------------------------------------------------- 109 | 110 | /** 111 | Initializes an `AZSocketIO` object with the specified host and port. 112 | 113 | @param host The hostname of socket.io server. 114 | @param port The port the socket.io server is running on. 115 | @param secureConnections Determines whether SSL encryption is used when possible 116 | 117 | @return the initialized client 118 | */ 119 | - (id)initWithHost:(NSString *)host andPort:(NSString *)port secure:(BOOL)secureConnections; 120 | /** 121 | Initializes an `AZSocketIO` object with the specified host, port and namespace. 122 | 123 | This is the designated initializer. It will not create a connection to the server. 124 | 125 | @param host The hostname of socket.io server. 126 | @param port The port the socket.io server is running on. 127 | @param secureConnections Determines whether SSL encryption is used when possible 128 | @param endpoint The endpoint namespace 129 | 130 | @return the initialized client 131 | */ 132 | - (id)initWithHost:(NSString *)host andPort:(NSString *)port secure:(BOOL)secureConnections withNamespace:(NSString *)endpoint; 133 | /** 134 | Connects to the socket.io server. 135 | 136 | @param success A block object that will be executed after the completion of handshake. 137 | @param failure A block object that will be executed when an error is reported by the socket.io server or the connection becomes unusable. 138 | */ 139 | - (void)connectWithSuccess:(void (^)())success andFailure:(void (^)(NSError *error))failure; 140 | /** 141 | Disconnects from the socket.io server 142 | */ 143 | - (void)disconnect; 144 | 145 | ///----------------------- 146 | /// @name Sending messages 147 | ///----------------------- 148 | 149 | /** 150 | Sends a normal message to the socket.io server. 151 | 152 | @param data The data to be sent to the socket.io server. If this data is not an `NSString`, the data will be encoded as JSON. 153 | @param error If there is a problem encoding the message, upon return contains an instance of NSError that describes the problem. 154 | 155 | @return `YES` if the message was dispatched immediately, `NO` if it was queued. 156 | */ 157 | - (BOOL)send:(id)data error:(NSError * __autoreleasing *)error; 158 | 159 | /** 160 | Sends a normal message to the socket.io server. 161 | 162 | This functions identically to the socket.io javascript client. For discussion of that, see the [socket.io readme](https://github.com/learnboost/socket.io#getting-acknowledgements). 163 | 164 | @param data The data to be sent to the socket.io server. If this data is not an `NSString`, the data will be encoded as JSON. 165 | @param error If there is a problem encoding the message, upon return contains an instance of NSError that describes the problem. 166 | @param callback A block that will be executed using the ACK args from the socket.io server. 167 | 168 | @return `YES` if the message was dispatched immediately, `NO` if it was queued. 169 | */ 170 | - (BOOL)send:(id)data error:(NSError *__autoreleasing *)error ackWithArgs:(void (^)(NSArray *data))callback; 171 | 172 | /** 173 | Sends a normal message to the socket.io server. 174 | 175 | This functions identically to the socket.io javascript client. For discussion of that, see the [socket.io readme](https://github.com/learnboost/socket.io#getting-acknowledgements). 176 | 177 | @param data The data to be sent to the socket.io server. If this data is not an `NSString`, the data will be encoded as JSON. 178 | @param error If there is a problem encoding the message, upon return contains an instance of NSError that describes the problem. 179 | @param callback A block that will be executed using the ACK from the socket.io server. 180 | 181 | @return `YES` if the message was dispatched immediately, `NO` if it was queued. 182 | */ 183 | - (BOOL)send:(id)data error:(NSError *__autoreleasing *)error ack:(void (^)())callback; 184 | 185 | /** 186 | Emits a namespaced message to the socket.io server. 187 | 188 | @param name The name of the event. 189 | @param args The arguements to emit with the event. 190 | @param error If there is a problem encoding the message, upon return contains an instance of NSError that describes the problem. 191 | 192 | @return `YES` if the message was dispatched immediately, `NO` if it was queued. 193 | */ 194 | - (BOOL)emit:(NSString *)name args:(id)args error:(NSError * __autoreleasing *)error; 195 | 196 | /** 197 | Emits a namespaced message to the socket.io server. 198 | 199 | This functions identically to the socket.io javascript client. For discussion of that, see the [socket.io readme](https://github.com/learnboost/socket.io#getting-acknowledgements). 200 | 201 | @param name The name of the event. 202 | @param args The arguements to emit with the event. 203 | @param error If there is a problem encoding the message, upon return contains an instance of NSError that describes the problem. 204 | @param callback A block that will be executed using the ACK args from the socket.io server. 205 | 206 | @return `YES` if the message was dispatched immediately, `NO` if it was queued. 207 | */ 208 | - (BOOL)emit:(NSString *)name args:(id)args error:(NSError *__autoreleasing *)error ackWithArgs:(void (^)(NSArray *data))callback; 209 | 210 | /** 211 | Emits a namespaced message to the socket.io server. 212 | 213 | This functions identically to the socket.io javascript client. For discussion of that, see the [socket.io readme](https://github.com/learnboost/socket.io#getting-acknowledgements). 214 | 215 | @param name The name of the event. 216 | @param args The arguements to emit with the event. 217 | @param error If there is a problem encoding the message, upon return contains an instance of NSError that describes the problem. 218 | @param callback A block that will be executed using the ACK from the socket.io server. 219 | 220 | @return `YES` if the message was dispatched immediately, `NO` if it was queued. 221 | */ 222 | - (BOOL)emit:(NSString *)name args:(id)args error:(NSError *__autoreleasing *)error ack:(void (^)())callback; 223 | 224 | ///------------------------------------- 225 | /// @name Routing Events From the Server 226 | ///------------------------------------- 227 | 228 | /** 229 | Sets the callback for a particular event 230 | 231 | For most users, this will be the most common way to handle messages. 232 | 233 | @param name The name of the event. 234 | @param block A block object that will be called when an event with this name is received. The block has no return value and takes two arguements: the name of the event and the arguements sent with the event. 235 | 236 | @warning A single event can have many registered callback blocks. Adding a new callback does not implicitly remove the existing callback. To remove existing callbacks, see `removeCallbackForEvent:callback:` or `removeCallbacksForEvent:`. 237 | */ 238 | - (void)addCallbackForEventName:(NSString *)name callback:(void (^)(NSString *eventName, id data))block; 239 | 240 | /** 241 | Removes a single callback for a particular event 242 | 243 | @param name The name of the event. 244 | @param block A block object that is currently registered with this event. 245 | 246 | @return `YES` if there are no remaining callbacks for this event, `NO` if other callbacks remain 247 | */ 248 | - (BOOL)removeCallbackForEvent:(NSString *)name callback:(void (^)(NSString *eventName, id data))block; 249 | 250 | /** 251 | Removes all callbacks for a particular event 252 | 253 | @param name The name of the event. 254 | 255 | @return The number of callbacks that were removed. 256 | */ 257 | - (NSInteger)removeCallbacksForEvent:(NSString *)name; 258 | 259 | /** 260 | Returns all the callbacks for a particular event 261 | 262 | @param eventName the name of the event. 263 | 264 | @return An `NSArray` containing all the callback blocks, `nil` if no callback blocks exists. 265 | */ 266 | - (NSArray *)callbacksForEvent:(NSString *)eventName; 267 | 268 | /*! 269 | @method setValue:forHTTPHeaderField: 270 | @abstract Sets the value of the given HTTP header field. 271 | @discussion If a value was previously set for the given header 272 | field, that value is replaced with the given value. Note that, in 273 | keeping with the HTTP RFC, HTTP header field names are 274 | case-insensitive. 275 | @param value the header field value. 276 | @param field the header field name (case-insensitive). 277 | */ 278 | - (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field; 279 | 280 | ///------------------------------------- 281 | /// @name Reconnecting 282 | ///------------------------------------- 283 | /** 284 | Determines whether AZSocketIO will try to reconnect. Defaults to 'YES'. 285 | */ 286 | @property(nonatomic, assign, getter = shouldReconnect)BOOL reconnect; 287 | /** 288 | The initial delay, in seconds, before reconnecting. Defaults to '0.5'. 289 | */ 290 | @property(nonatomic, assign)NSTimeInterval reconnectionDelay; 291 | /** 292 | The maximum delay, in seconds, before reconnecting. After the delay hits this ceiling, reconnection attempts will stop. Defaults to 'MAX_FLOAT'. 293 | */ 294 | @property(nonatomic, assign)NSTimeInterval reconnectionLimit; 295 | /** 296 | The maximum number of reconnection attempts. Defaults to '10'. 297 | */ 298 | @property(nonatomic, assign)NSUInteger maxReconnectionAttempts; 299 | 300 | #pragma mark overridden setters 301 | - (void)setMessageReceivedBlock:(void (^)(id data))messageReceivedBlock; 302 | - (void)setEventReceivedBlock:(void (^)(NSString *eventName, id data))eventReceivedBlock; 303 | - (void)setDisconnectedBlock:(void (^)())disconnectedBlock; 304 | - (void)setErrorBlock:(void (^)(NSError *error))errorBlock; 305 | @end 306 | -------------------------------------------------------------------------------- /Pods/AZSocketIO/AZSocketIO/AZSocketIO.m: -------------------------------------------------------------------------------- 1 | // 2 | // AZSocketIO.m 3 | // AZSocketIO 4 | // 5 | // Created by Patrick Shields on 4/6/12. 6 | // Copyright 2012 Patrick Shields 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // 20 | 21 | #import "AZSocketIO.h" 22 | #import "AZSocketIOTransport.h" 23 | #import "AZWebsocketTransport.h" 24 | #import "AZxhrTransport.h" 25 | #import "AZSocketIOPacket.h" 26 | #import 27 | 28 | #define PROTOCOL_VERSION @"1" 29 | 30 | NSString * const AZSocketIODefaultNamespace = @""; 31 | 32 | @interface AZSocketIO () 33 | @property(nonatomic, strong, readwrite)NSString *host; 34 | @property(nonatomic, strong, readwrite)NSString *port; 35 | @property(nonatomic, assign, readwrite)BOOL secureConnections; 36 | @property(nonatomic, copy, readwrite)NSString *endpoint; 37 | 38 | @property(nonatomic, strong)NSOperationQueue *queue; 39 | 40 | @property(nonatomic, strong)ConnectedBlock connectionBlock; 41 | 42 | @property(nonatomic, strong)AFHTTPRequestOperationManager *httpClient; 43 | @property(nonatomic, strong)NSDictionary *transportMap; 44 | 45 | @property(nonatomic, strong)NSMutableDictionary *ackCallbacks; 46 | @property(nonatomic, assign)NSUInteger ackCount; 47 | @property(nonatomic, strong)NSTimer *heartbeatTimer; 48 | @property(nonatomic, assign)NSUInteger connectionAttempts; 49 | 50 | @property(nonatomic, strong)NSMutableDictionary *specificEventBlocks; 51 | 52 | @property(nonatomic, strong)NSArray *availableTransports; 53 | @property(nonatomic, strong)NSString *sessionId; 54 | @property(nonatomic, assign)NSInteger heartbeatInterval; 55 | @property(nonatomic, assign)NSInteger disconnectInterval; 56 | 57 | @property(nonatomic, assign)NSTimeInterval currentReconnectDelay; 58 | 59 | @property(nonatomic, assign, readwrite)AZSocketIOState state; 60 | @end 61 | 62 | @implementation AZSocketIO 63 | 64 | - (id)initWithHost:(NSString *)host andPort:(NSString *)port secure:(BOOL)secureConnections 65 | { 66 | return [self initWithHost:host 67 | andPort:port 68 | secure:secureConnections 69 | withNamespace:AZSocketIODefaultNamespace]; 70 | } 71 | 72 | - (id)initWithHost:(NSString *)host andPort:(NSString *)port secure:(BOOL)secureConnections withNamespace:(NSString *)endpoint 73 | { 74 | NSParameterAssert(host); 75 | NSParameterAssert(port); 76 | NSParameterAssert(endpoint); 77 | 78 | self = [super init]; 79 | if (self) { 80 | self.host = host; 81 | self.port = port; 82 | self.secureConnections = secureConnections; 83 | self.endpoint = endpoint; 84 | 85 | NSString *protocolString = self.secureConnections ? @"https://" : @"http://"; 86 | NSString *urlString = [NSString stringWithFormat:@"%@%@:%@", protocolString, 87 | self.host, self.port]; 88 | 89 | self.httpClient = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:urlString]]; 90 | // NSMutableSet* types = [NSMutableSet setWithSet:self.httpClient.responseSerializer.acceptableContentTypes]; 91 | // [types addObject:@"text/plain"]; 92 | // self.httpClient.responseSerializer.acceptableContentTypes = types; 93 | self.httpClient.requestSerializer.stringEncoding = NSUTF8StringEncoding; 94 | self.httpClient.responseSerializer = [AFHTTPResponseSerializer serializer]; 95 | self.httpClient.responseSerializer.stringEncoding = NSUTF8StringEncoding; 96 | 97 | self.ackCallbacks = [NSMutableDictionary dictionary]; 98 | self.ackCount = 0; 99 | self.specificEventBlocks = [NSMutableDictionary new]; 100 | 101 | self.queue = [[NSOperationQueue alloc] init]; 102 | [self.queue setSuspended:YES]; 103 | 104 | self.transports = [NSMutableSet setWithObjects:@"websocket", @"xhr-polling", nil]; 105 | self.transportMap = @{ @"websocket" : [AZWebsocketTransport class], @"xhr-polling" : [AZxhrTransport class] }; 106 | 107 | self.reconnect = YES; 108 | self.reconnectionDelay = .5; 109 | self.reconnectionLimit = MAXFLOAT; 110 | self.maxReconnectionAttempts = 10; 111 | self.state = AZSocketIOStateDisconnected; 112 | } 113 | return self; 114 | } 115 | 116 | - (void)setReconnectionDelay:(NSTimeInterval)reconnectionDelay 117 | { 118 | _reconnectionDelay = reconnectionDelay; 119 | _currentReconnectDelay = reconnectionDelay; 120 | } 121 | 122 | #pragma mark connection management 123 | - (void)connectWithSuccess:(ConnectedBlock)success andFailure:(ErrorBlock)failure 124 | { 125 | self.state = AZSocketIOStateConnecting; 126 | self.connectionBlock = success; 127 | self.errorBlock = failure; 128 | NSString *urlString = [NSString stringWithFormat:@"socket.io/%@", PROTOCOL_VERSION]; 129 | [self.httpClient GET:urlString 130 | parameters:nil 131 | success:^(AFHTTPRequestOperation *operation, id responseObject) { 132 | NSString *response = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]; 133 | NSArray *msg = [response componentsSeparatedByString:@":"]; 134 | if ([msg count] < 4) { 135 | NSMutableDictionary *errorDetail = [NSMutableDictionary dictionary]; 136 | [errorDetail setValue:@"Server handshake message could not be decoded" forKey:NSLocalizedDescriptionKey]; 137 | failure([NSError errorWithDomain:AZDOMAIN code:AZSocketIOErrorConnection userInfo:errorDetail]); 138 | return; 139 | } 140 | self.sessionId = [msg objectAtIndex:0]; 141 | self.heartbeatInterval = [[msg objectAtIndex:1] intValue]; 142 | self.disconnectInterval = [[msg objectAtIndex:2] intValue]; 143 | self.availableTransports = [[msg objectAtIndex:3] componentsSeparatedByString:@","]; 144 | self.currentReconnectDelay = self.reconnectionDelay; 145 | [self connect]; 146 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 147 | self.state = AZSocketIOStateDisconnected; 148 | if (![self reconnect]) { 149 | failure(error); 150 | } 151 | }]; 152 | } 153 | 154 | - (void)connect 155 | { 156 | self.connectionAttempts++; 157 | for (NSString *transportType in self.availableTransports) { 158 | if ([self.transports containsObject:transportType]) { 159 | [self connectViaTransport:transportType]; 160 | return; 161 | } 162 | } 163 | 164 | NSMutableDictionary *errorDetail = [NSMutableDictionary dictionary]; 165 | [errorDetail setValue:@"None of the available transports are recognized by this server" forKey:NSLocalizedDescriptionKey]; 166 | NSError *error = [NSError errorWithDomain:AZDOMAIN code:AZSocketIOErrorConnection userInfo:errorDetail]; 167 | self.errorBlock(error); 168 | } 169 | 170 | - (void)connectViaTransport:(NSString*)transportType 171 | { 172 | if ([transportType isEqualToString:@"websocket"]) { 173 | self.transport = [[AZWebsocketTransport alloc] initWithDelegate:self secureConnections:self.secureConnections]; 174 | } else if ([transportType isEqualToString:@"xhr-polling"]) { 175 | self.transport = [[AZxhrTransport alloc] initWithDelegate:self secureConnections:self.secureConnections]; 176 | } else { 177 | NSLog(@"Transport not implemented"); 178 | } 179 | [self.transport connect]; 180 | } 181 | 182 | - (void)disconnect 183 | { 184 | [self clearHeartbeatTimeout]; 185 | self.state = AZSocketIOStateDisconnecting; 186 | [self.transport disconnect]; 187 | } 188 | 189 | - (BOOL)reconnect 190 | { 191 | if (self.shouldReconnect && self.state == AZSocketIOStateDisconnected) { 192 | NSString *transportName = [[self.transportMap allKeysForObject:[self.transport class]] lastObject]; 193 | self.availableTransports = [self.availableTransports filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) { 194 | return ![transportName isEqualToString:evaluatedObject] && [self.transports containsObject:evaluatedObject]; 195 | }]]; 196 | if ([self.availableTransports count] > 0) { 197 | [self connect]; 198 | return YES; 199 | } else if (self.connectionAttempts < self.maxReconnectionAttempts) { 200 | if (self.currentReconnectDelay < self.reconnectionLimit) { 201 | NSLog(@"Reconnecting after %f", self.currentReconnectDelay); 202 | NSInvocation *connectionCallable = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(connectWithSuccess:andFailure:)]]; 203 | connectionCallable.target = self; 204 | connectionCallable.selector = @selector(connectWithSuccess:andFailure:); 205 | [connectionCallable setArgument:&_connectionBlock atIndex:2]; 206 | [connectionCallable setArgument:&_errorBlock atIndex:3]; 207 | [NSTimer scheduledTimerWithTimeInterval:self.currentReconnectDelay invocation:connectionCallable repeats:NO]; 208 | 209 | self.currentReconnectDelay *= 2; 210 | return YES; 211 | } 212 | } 213 | } 214 | 215 | return NO; 216 | } 217 | 218 | #pragma mark data sending 219 | - (BOOL)send:(id)data error:(NSError *__autoreleasing *)error ack:(ACKCallback)callback 220 | { 221 | return [self send:data error:error ack:callback argCount:0]; 222 | } 223 | 224 | - (BOOL)send:(id)data error:(NSError *__autoreleasing *)error ackWithArgs:(ACKCallbackWithArgs)callback 225 | { 226 | return [self send:data error:error ack:callback argCount:1]; 227 | } 228 | 229 | - (BOOL)send:(id)data error:(NSError *__autoreleasing *)error ack:(id)callback argCount:(NSUInteger)argCount 230 | { 231 | AZSocketIOPacket *packet = [[AZSocketIOPacket alloc] init]; 232 | 233 | if (![data isKindOfClass:[NSString class]]) { 234 | NSData *jsonData = [NSJSONSerialization dataWithJSONObject:data options:0 error:error]; 235 | if (jsonData == nil) { 236 | return NO; 237 | } 238 | 239 | packet.data = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 240 | packet.type = JSON_MESSAGE; 241 | } else { 242 | packet.data = data; 243 | packet.type = MESSAGE; 244 | } 245 | 246 | if (callback != NULL) { 247 | packet.Id = [NSString stringWithFormat:@"%d", self.ackCount++]; 248 | [self.ackCallbacks setObject:callback forKey:packet.Id]; 249 | if (argCount > 0) { 250 | packet.Id = [packet.Id stringByAppendingString:@"+"]; 251 | } 252 | } 253 | 254 | return [self sendPacket:packet error:error]; 255 | } 256 | 257 | - (BOOL)send:(id)data error:(NSError *__autoreleasing *)error 258 | { 259 | return [self send:data error:error ack:NULL]; 260 | } 261 | 262 | - (void)sendExplicitConnectMessage 263 | { 264 | AZSocketIOPacket *connectPacket = [[AZSocketIOPacket alloc] init]; 265 | connectPacket.type = CONNECT; 266 | connectPacket.endpoint = self.endpoint; 267 | [self.transport send:[connectPacket encode]]; 268 | } 269 | 270 | - (BOOL)emit:(NSString *)name args:(id)args error:(NSError *__autoreleasing *)error ack:(ACKCallback)callback 271 | { 272 | return [self emit:name args:args error:error ack:callback argCount:0]; 273 | } 274 | 275 | - (BOOL)emit:(NSString *)name args:(id)args error:(NSError *__autoreleasing *)error ackWithArgs:(ACKCallbackWithArgs)callback 276 | { 277 | return [self emit:name args:args error:error ack:callback argCount:1]; 278 | } 279 | 280 | - (BOOL)emit:(NSString *)name args:(id)args error:(NSError *__autoreleasing *)error ack:(id)callback argCount:(NSUInteger)argCount 281 | { 282 | AZSocketIOPacket *packet = [[AZSocketIOPacket alloc] init]; 283 | packet.type = EVENT; 284 | 285 | NSDictionary *data = nil; 286 | 287 | if (args) { 288 | data = @{ @"name" : name, @"args" : args}; 289 | } else { 290 | data = @{ @"name" : name}; 291 | } 292 | 293 | if (![NSJSONSerialization isValidJSONObject:data]) { 294 | if (error) { 295 | NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"The provided args can't be converted to JSON"}; 296 | *error = [NSError errorWithDomain:AZDOMAIN code:AZSocketIOErrorArgs userInfo:userInfo]; 297 | } 298 | return NO; 299 | } 300 | 301 | NSData *jsonData = [NSJSONSerialization dataWithJSONObject:data options:0 error:error]; 302 | if (jsonData == nil) { 303 | return NO; 304 | } 305 | 306 | packet.data = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 307 | packet.Id = [NSString stringWithFormat:@"%d", self.ackCount++]; 308 | 309 | if (callback != NULL) { 310 | [self.ackCallbacks setObject:callback forKey:packet.Id]; 311 | if (argCount > 0) { 312 | packet.Id = [packet.Id stringByAppendingString:@"+"]; 313 | } 314 | } 315 | 316 | return [self sendPacket:packet error:error]; 317 | } 318 | 319 | - (BOOL)emit:(NSString *)name args:(id)args error:(NSError * __autoreleasing *)error 320 | { 321 | return [self emit:name args:args error:error ack:NULL]; 322 | } 323 | 324 | - (BOOL)sendPacket:(AZSocketIOPacket *)packet error:(NSError * __autoreleasing *)error 325 | { 326 | packet.endpoint = self.endpoint; 327 | [self.queue addOperation:[NSBlockOperation blockOperationWithBlock:^{ 328 | [self.transport send:[packet encode]]; 329 | }]]; 330 | return !self.queue.isSuspended; 331 | } 332 | 333 | #pragma mark event callback registration 334 | 335 | - (void)addCallbackForEventName:(NSString *)name callback:(EventReceivedBlock)block 336 | { 337 | NSMutableArray *callbacks = [self.specificEventBlocks objectForKey:name]; 338 | if (callbacks == nil) { 339 | callbacks = [NSMutableArray array]; 340 | [self.specificEventBlocks setValue:callbacks forKey:name]; 341 | } 342 | [callbacks addObject:block]; 343 | } 344 | 345 | - (BOOL)removeCallbackForEvent:(NSString *)name callback:(EventReceivedBlock)block 346 | { 347 | NSMutableArray *callbacks = [self.specificEventBlocks objectForKey:name]; 348 | if (callbacks != nil) { 349 | NSInteger count = [callbacks count]; 350 | [callbacks removeObject:block]; 351 | if ([callbacks count] == 0) { 352 | [self.specificEventBlocks removeObjectForKey:name]; 353 | return YES; 354 | } 355 | return count != [callbacks count]; 356 | } 357 | return NO; 358 | } 359 | 360 | - (NSInteger)removeCallbacksForEvent:(NSString *)name 361 | { 362 | NSMutableArray *callbacks = [self.specificEventBlocks objectForKey:name]; 363 | [self.specificEventBlocks removeObjectForKey:name]; 364 | return [callbacks count]; 365 | } 366 | 367 | - (NSArray *)callbacksForEvent:(NSString *)eventName 368 | { 369 | return [[self.specificEventBlocks objectForKey:eventName] copy]; 370 | } 371 | 372 | - (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field { 373 | [self.httpClient.requestSerializer setValue:value forHTTPHeaderField:field]; 374 | } 375 | 376 | #pragma mark heartbeat 377 | 378 | - (void)clearHeartbeatTimeout 379 | { 380 | [self.heartbeatTimer invalidate]; 381 | self.heartbeatTimer = nil; 382 | } 383 | 384 | - (void)startHeartbeatTimeout 385 | { 386 | [self clearHeartbeatTimeout]; 387 | self.heartbeatTimer = [NSTimer scheduledTimerWithTimeInterval:self.heartbeatInterval 388 | target:self 389 | selector:@selector(heartbeatTimeout) 390 | userInfo:nil 391 | repeats:NO]; 392 | } 393 | - (void)heartbeatTimeout 394 | { 395 | [self disconnect]; 396 | [self reconnect]; 397 | } 398 | 399 | 400 | #pragma mark AZSocketIOTransportDelegate 401 | 402 | - (void)didReceiveMessage:(NSString *)message 403 | { 404 | [self startHeartbeatTimeout]; 405 | AZSocketIOPacket *packet = [[AZSocketIOPacket alloc] initWithString:message]; 406 | AZSocketIOACKMessage *ackMessage; ACKCallback callback; 407 | switch (packet.type) { 408 | case DISCONNECT: 409 | [self disconnect]; 410 | break; 411 | case CONNECT: 412 | { 413 | if (self.endpoint) { 414 | NSString *receivedEndpoint = packet.endpoint; 415 | if (![receivedEndpoint isEqualToString:self.endpoint]) { 416 | [self sendExplicitConnectMessage]; 417 | return; 418 | } 419 | } 420 | 421 | self.connectionBlock(); 422 | [self.queue setSuspended:NO]; 423 | break; 424 | } 425 | case HEARTBEAT: 426 | [self.transport send:message]; 427 | break; 428 | case MESSAGE: 429 | if (self.messageReceivedBlock) { 430 | self.messageReceivedBlock(packet.data); 431 | } 432 | break; 433 | case JSON_MESSAGE: 434 | { 435 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 436 | id outData = [NSJSONSerialization JSONObjectWithData:[packet.data dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil]; 437 | [self performSelectorOnMainThread:@selector(didParseJSONMessage:) 438 | withObject:outData waitUntilDone:NO]; 439 | }); 440 | break; 441 | } 442 | case EVENT: 443 | { 444 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 445 | id outData = [NSJSONSerialization JSONObjectWithData:[packet.data dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil]; 446 | [self performSelectorOnMainThread:@selector(didParseJSONEvent:) 447 | withObject:outData waitUntilDone:NO]; 448 | }); 449 | break; 450 | } 451 | case ACK: 452 | ackMessage = [[AZSocketIOACKMessage alloc] initWithPacket:packet]; 453 | callback = [self.ackCallbacks objectForKey:ackMessage.messageId]; 454 | if (callback != NULL) { 455 | if (ackMessage.args.count > 0) { 456 | callback(ackMessage.args); 457 | } else { 458 | callback(); 459 | } 460 | } 461 | [self.ackCallbacks removeObjectForKey:ackMessage.messageId]; 462 | break; 463 | case ERROR: 464 | [self disconnect]; 465 | if (![self reconnect]) { 466 | if (self.errorBlock) { 467 | NSMutableDictionary *errorDetail = [NSMutableDictionary dictionary]; 468 | [errorDetail setValue:packet.data forKey:NSLocalizedDescriptionKey]; 469 | NSError *error = [NSError errorWithDomain:AZDOMAIN code:AZSocketIOErrorConnection userInfo:errorDetail]; 470 | self.errorBlock(error); 471 | } 472 | } 473 | break; 474 | default: 475 | break; 476 | } 477 | } 478 | 479 | - (void)didOpen 480 | { 481 | self.state = AZSocketIOStateConnected; 482 | self.connectionAttempts = 0; 483 | } 484 | 485 | - (void)didClose 486 | { 487 | self.state = AZSocketIOStateDisconnected; 488 | [self.queue setSuspended:YES]; 489 | if (self.disconnectedBlock) { 490 | self.disconnectedBlock(); 491 | } 492 | } 493 | 494 | - (void)didFailWithError:(NSError *)error 495 | { 496 | self.state = AZSocketIOStateDisconnected; 497 | [self.queue setSuspended:YES]; 498 | if (![self reconnect] && self.errorBlock) { 499 | self.errorBlock(error); 500 | } 501 | } 502 | 503 | #pragma mark - Parse response 504 | 505 | - (void)didParseJSONMessage:(id)outData 506 | { 507 | if (self.messageReceivedBlock) { 508 | self.messageReceivedBlock(outData); 509 | } 510 | } 511 | 512 | - (void)didParseJSONEvent:(id)outData 513 | { 514 | NSArray *callbackList = [self.specificEventBlocks objectForKey:[outData objectForKey:@"name"]]; 515 | if (callbackList != nil) { 516 | for (EventReceivedBlock block in [callbackList copy]) { 517 | block([outData objectForKey:@"name"], [outData objectForKey:@"args"]); 518 | } 519 | } else { 520 | if (self.eventReceivedBlock) { 521 | self.eventReceivedBlock([outData objectForKey:@"name"], [outData objectForKey:@"args"]); 522 | } 523 | } 524 | } 525 | 526 | @end 527 | -------------------------------------------------------------------------------- /Pods/AZSocketIO/AZSocketIO/AZSocketIOPacket.h: -------------------------------------------------------------------------------- 1 | // 2 | // AZSocketIOPacket.h 3 | // AZSocketIO 4 | // 5 | // Created by Patrick Shields on 4/7/12. 6 | // Copyright 2012 Patrick Shields 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // 20 | 21 | #import 22 | 23 | typedef enum { 24 | DISCONNECT, 25 | CONNECT, 26 | HEARTBEAT, 27 | MESSAGE, 28 | JSON_MESSAGE, 29 | EVENT, 30 | ACK, 31 | ERROR, 32 | NOOP 33 | } MESSAGE_TYPE; 34 | 35 | /** 36 | `AZSocketIOPacket` is an object that represents an encoded message that can be read by the socket.io server. 37 | */ 38 | @interface AZSocketIOPacket : NSObject 39 | /** 40 | The type of the message. 41 | */ 42 | @property(nonatomic, assign)MESSAGE_TYPE type; 43 | 44 | /** 45 | The id of the message. This is used for ack'ing packets. 46 | */ 47 | @property(nonatomic, strong)NSString *Id; 48 | 49 | /** 50 | Determines whether the server will ACK a packet. If 'YES', ACK packet will be sent. 51 | */ 52 | @property(nonatomic, assign)BOOL ack; 53 | 54 | /** 55 | The endpoint for the packet. Currently unused. 56 | */ 57 | @property(nonatomic, strong)NSString *endpoint; 58 | 59 | /** 60 | The data to be appended to the packet. This should be preformated to match the type. 61 | */ 62 | @property(nonatomic, strong)NSString *data; 63 | 64 | /** 65 | Initializes a packet using a serialized representation. 66 | 67 | @param packetString A serialized packet. 68 | 69 | @return the initialized packet. 70 | */ 71 | - (id)initWithString:(NSString *)packetString; 72 | 73 | /** 74 | Serializes a packet so that it can be written to the wire. 75 | 76 | @return A string containing the serialized packet data. 77 | */ 78 | - (NSString *)encode; 79 | @end 80 | 81 | @interface AZSocketIOACKMessage : NSObject 82 | @property(nonatomic, strong)NSString *messageId; 83 | @property(nonatomic, strong)NSArray *args; 84 | - (id)initWithPacket:(AZSocketIOPacket *)packet; 85 | @end 86 | -------------------------------------------------------------------------------- /Pods/AZSocketIO/AZSocketIO/AZSocketIOPacket.m: -------------------------------------------------------------------------------- 1 | // 2 | // AZSocketIOPacket.m 3 | // AZSocketIO 4 | // 5 | // Created by Patrick Shields on 4/7/12. 6 | // Copyright 2012 Patrick Shields 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // 20 | 21 | #import "AZSocketIOPacket.h" 22 | 23 | @interface AZSocketIOPacket () 24 | + (NSRegularExpression *)regex; 25 | + (NSString *)captureOrEmptyString:(NSString *)whole range:(NSRange)range; 26 | @end 27 | 28 | @implementation AZSocketIOPacket 29 | @synthesize type; 30 | @synthesize Id; 31 | @synthesize ack; 32 | @synthesize endpoint; 33 | @synthesize data; 34 | 35 | - (id)init 36 | { 37 | self = [super init]; 38 | if (self) { 39 | self.data = @""; 40 | self.endpoint = @""; 41 | } 42 | return self; 43 | } 44 | 45 | - (id)initWithString:(NSString *)packetString 46 | { 47 | self = [self init]; 48 | if (self) { 49 | NSTextCheckingResult *result = [[AZSocketIOPacket regex] firstMatchInString:packetString 50 | options:0 51 | range:NSMakeRange(0, [packetString length])]; 52 | 53 | NSString *typeString = [packetString substringWithRange:[result rangeAtIndex:1]]; 54 | self.type = typeString.length == 0 ? -1 : [typeString intValue]; 55 | self.Id = [AZSocketIOPacket captureOrEmptyString:packetString range:[result rangeAtIndex:2]]; 56 | 57 | self.ack = NO; 58 | if (([self.Id length] > 0) && 59 | ([[self.Id substringFromIndex:[self.Id length]-1] isEqualToString:@"+"])) { 60 | self.ack = YES; 61 | } 62 | 63 | self.endpoint = [AZSocketIOPacket captureOrEmptyString:packetString range:[result rangeAtIndex:4]]; 64 | self.data = [AZSocketIOPacket captureOrEmptyString:packetString range:[result rangeAtIndex:5]]; 65 | } 66 | return self; 67 | } 68 | 69 | - (NSString *)encode 70 | { 71 | NSString *idString; 72 | if (self.Id != nil) { 73 | idString = self.Id; 74 | if (self.ack) { 75 | idString = [idString stringByAppendingString:@"+"]; 76 | } 77 | } else { 78 | idString = @""; 79 | } 80 | 81 | // Message encoding format (https://github.com/LearnBoost/socket.io-spec#encoding) 82 | // [message type] ':' [message id ('+')] ':' [message endpoint] (':' [message data]) 83 | NSString *encodedString = [NSString stringWithFormat:@"%d:%@:%@:%@", self.type, idString, self.endpoint, self.data]; 84 | return encodedString; 85 | } 86 | 87 | - (NSString *)description 88 | { 89 | NSArray *pieces = [NSArray arrayWithObjects:[NSString stringWithFormat:@"<%@: %p>", NSStringFromClass([self class]), self], 90 | [NSString stringWithFormat:@"type: %d", self.type], [NSString stringWithFormat:@"id: %@", self.Id], 91 | [NSString stringWithFormat:@"endpoint: %@", self.endpoint], 92 | [NSString stringWithFormat:@"data: %@", self.data], nil]; 93 | return [pieces componentsJoinedByString:@"\n\t"]; 94 | } 95 | 96 | + (NSRegularExpression *)regex 97 | { 98 | static NSRegularExpression *regex; 99 | static dispatch_once_t onceToken; 100 | dispatch_once(&onceToken, ^{ 101 | regex = [NSRegularExpression regularExpressionWithPattern:@"([^:]+):([0-9]+)?(\\+)?:([^:]+)?:?([\\s\\S]*)?" 102 | options:NSRegularExpressionCaseInsensitive 103 | error:nil]; 104 | }); 105 | return regex; 106 | } 107 | 108 | 109 | 110 | + (NSString *)captureOrEmptyString:(NSString *)whole range:(NSRange)range 111 | { 112 | if (range.length <= 0) { 113 | return @""; 114 | } else { 115 | return [whole substringWithRange:range]; 116 | } 117 | } 118 | @end 119 | 120 | @implementation AZSocketIOACKMessage 121 | @synthesize messageId; 122 | @synthesize args; 123 | - (id)initWithPacket:(AZSocketIOPacket *)packet 124 | { 125 | self = [super init]; 126 | if (self) { 127 | if (![packet.data isKindOfClass:[NSString class]]) { 128 | [NSException raise:@"Packet is not an ack" 129 | format:@"Packet data is: %@", packet.data]; 130 | } 131 | 132 | NSTextCheckingResult *result = [[AZSocketIOACKMessage ackRegex] firstMatchInString:packet.data 133 | options:0 134 | range:NSMakeRange(0, [packet.data length])]; 135 | self.messageId = [packet.data substringWithRange:[result rangeAtIndex:1]]; 136 | 137 | if ([result rangeAtIndex:1].length != [result range].length) { 138 | NSString *ackData = [packet.data substringWithRange:[result rangeAtIndex:2]]; 139 | self.args = [NSJSONSerialization JSONObjectWithData:[ackData dataUsingEncoding:NSUTF8StringEncoding] 140 | options:NSJSONReadingMutableContainers 141 | error:nil]; 142 | } 143 | } 144 | return self; 145 | } 146 | 147 | + (NSRegularExpression *)ackRegex 148 | { 149 | static NSRegularExpression *regex; 150 | static dispatch_once_t onceToken; 151 | dispatch_once(&onceToken, ^{ 152 | regex = [NSRegularExpression regularExpressionWithPattern:@"([0-9]+)\\+?(.*)" 153 | options:NSRegularExpressionCaseInsensitive 154 | error:nil]; 155 | }); 156 | return regex; 157 | } 158 | @end -------------------------------------------------------------------------------- /Pods/AZSocketIO/AZSocketIO/Protocols/AZSocketIOTransport.h: -------------------------------------------------------------------------------- 1 | // 2 | // AZSocketIOTransport.h 3 | // AZSocketIO 4 | // 5 | // Created by Patrick Shields on 8/9/11. 6 | // Copyright 2012 Patrick Shields 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // 20 | 21 | #import 22 | #import "AZSocketIOTransportDelegate.h" 23 | 24 | /** 25 | The `AZSocketIOTransport` protocol specifies the requirements of a transport that can be utilized by an `AZSocketIO` object. 26 | */ 27 | @protocol AZSocketIOTransport 28 | @required 29 | 30 | ///--------------------------------------------- 31 | /// @name Creating and Configuring the Transport 32 | ///--------------------------------------------- 33 | 34 | /** 35 | Initializes an object conforming to `AZSocketIOTransport`. 36 | 37 | @param delegate The delegate for the transport to use. 38 | @param secureConnections Determines whether the transport will secure it's connection. 39 | 40 | @return The initialized transport. 41 | */ 42 | - (id)initWithDelegate:(id)delegate secureConnections:(BOOL)secureConnections; 43 | 44 | /** 45 | Determines whether the transport will secure the connection. 46 | */ 47 | @property(nonatomic, assign)BOOL secureConnections; 48 | 49 | /** 50 | Contains the current state of the transport. 51 | 52 | @return `YES` if the transport is connected, otherwise `NO`. 53 | */ 54 | @property(nonatomic, readonly, getter = isConnected)BOOL connected; 55 | 56 | /** 57 | Sets the delegate for the transport. 58 | 59 | @param delegate A delegate class conforming to `AZSocketIOTransportDelegate`. 60 | */ 61 | - (void)setDelegate:(id)delegate; 62 | 63 | ///------------------------------------ 64 | /// @name Communicating With the Server 65 | ///------------------------------------ 66 | 67 | /** 68 | Causes the transport to connect to the socket.io server. 69 | */ 70 | - (void)connect; 71 | 72 | /** 73 | Causes the transport to disconnect 74 | */ 75 | - (void)disconnect; 76 | 77 | /** 78 | Sends a serialized encoded message to the socket.io server. 79 | 80 | @param msg A serialized encoded message. 81 | */ 82 | - (void)send:(NSString*)msg; 83 | @end 84 | -------------------------------------------------------------------------------- /Pods/AZSocketIO/AZSocketIO/Protocols/AZSocketIOTransportDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AZSocketIOTransportDelegate.h 3 | // AZSocketIO 4 | // 5 | // Created by Patrick Shields on 8/9/11. 6 | // Copyright 2012 Patrick Shields 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // 20 | 21 | #import 22 | 23 | /** 24 | The `AZSocketIOTransportDelegate` protocol allows the adopting delegate to respond to messages from an `AZSocketIOTransport`. 25 | */ 26 | @protocol AZSocketIOTransportDelegate 27 | @optional 28 | 29 | ///------------------------------------------- 30 | /// @name Informing Delegate of Status Changes 31 | ///------------------------------------------- 32 | 33 | /** 34 | Tells the delegate that the transport has opened. 35 | */ 36 | - (void)didOpen; 37 | 38 | /** 39 | Tells the delegate that the transport has closed. 40 | */ 41 | - (void)didClose; 42 | 43 | /** 44 | Tells the delegate that the transport sent a message. 45 | */ 46 | - (void)didSendMessage; 47 | 48 | @required 49 | 50 | /** 51 | Tells the delegate that the transport has failed. 52 | 53 | @param error An instance of `NSError` that describes the problem. 54 | */ 55 | - (void)didFailWithError:(NSError*)error; 56 | 57 | ///-------------------------------------------- 58 | /// @name Recieving Messages From the Transport 59 | ///-------------------------------------------- 60 | 61 | /** 62 | Tells the delegate that message was received. 63 | 64 | @param message An `NSString` containing the message data. 65 | */ 66 | - (void)didReceiveMessage:(NSString*)message; 67 | 68 | ///--------------------------------------------------------- 69 | /// @name Supplying Connection Information From the Delegate 70 | ///--------------------------------------------------------- 71 | 72 | /** 73 | Allows the transport to retrieve the hostname of the socket.io server. 74 | 75 | @return The socket.io server hostname. 76 | */ 77 | - (NSString*)host; 78 | 79 | /** 80 | Allows the transport to retrieve the port the socket.io server is running on. 81 | 82 | @return The socket.io server port. 83 | */ 84 | - (NSString*)port; 85 | 86 | /** 87 | Allows the transport to retrieve the current session id. 88 | 89 | @return The current session Id. 90 | */ 91 | - (NSString*)sessionId; 92 | @end 93 | -------------------------------------------------------------------------------- /Pods/AZSocketIO/AZSocketIO/Transports/AZWebsocketTransport.h: -------------------------------------------------------------------------------- 1 | // 2 | // AZWebsocketTransport.h 3 | // AZSocketIO 4 | // 5 | // Created by Patrick Shields on 4/6/12. 6 | // Copyright 2012 Patrick Shields 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // 20 | #import 21 | #import "AZSocketIOTransport.h" 22 | #import "SRWebSocket.h" 23 | 24 | @interface AZWebsocketTransport : NSObject 25 | @property(nonatomic, strong)SRWebSocket *websocket; 26 | @end 27 | -------------------------------------------------------------------------------- /Pods/AZSocketIO/AZSocketIO/Transports/AZWebsocketTransport.m: -------------------------------------------------------------------------------- 1 | // 2 | // AZWebsocketTransport.m 3 | // AZSocketIO 4 | // 5 | // Created by Patrick Shields on 4/6/12. 6 | // Copyright 2012 Patrick Shields 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // 20 | 21 | #import "AZWebsocketTransport.h" 22 | #import "AZSocketIOTransportDelegate.h" 23 | 24 | @interface AZWebsocketTransport () 25 | @property(nonatomic, weak)id delegate; 26 | @property(nonatomic, readwrite, assign)BOOL connected; 27 | @end 28 | 29 | @implementation AZWebsocketTransport 30 | @synthesize secureConnections; 31 | 32 | @synthesize websocket; 33 | @synthesize delegate; 34 | @synthesize connected; 35 | 36 | #pragma mark AZSocketIOTransport 37 | - (id)initWithDelegate:(id)_delegate secureConnections:(BOOL)_secureConnections 38 | { 39 | self = [super init]; 40 | if (self) { 41 | self.connected = NO; 42 | self.delegate = _delegate; 43 | self.secureConnections = _secureConnections; 44 | 45 | NSString *protocolString = self.secureConnections ? @"wss://" : @"ws://"; 46 | NSString *urlString = [NSString stringWithFormat:@"%@%@:%@/socket.io/1/websocket/%@", 47 | protocolString, [self.delegate host], [self.delegate port], 48 | [self.delegate sessionId]]; 49 | NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]; 50 | self.websocket = [[SRWebSocket alloc] initWithURLRequest:request]; 51 | self.websocket.delegate = self; 52 | } 53 | return self; 54 | } 55 | - (void)dealloc 56 | { 57 | [self disconnect]; 58 | } 59 | - (void)connect 60 | { 61 | [self.websocket open]; 62 | } 63 | - (void)send:(NSString *)msg 64 | { 65 | [self.websocket send:msg]; 66 | if ([self.delegate respondsToSelector:@selector(didSendMessage)]) { 67 | [self.delegate didSendMessage]; 68 | } 69 | } 70 | - (void)disconnect 71 | { 72 | self.websocket.delegate = nil; 73 | [self.websocket close]; 74 | self.websocket = nil; 75 | [self webSocket:self.websocket didCloseWithCode:0 reason:@"Client requested disconnect" wasClean:YES]; 76 | self.connected = NO; 77 | } 78 | 79 | #pragma mark SRWebSocketDelegate 80 | - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(NSString *)message 81 | { 82 | [self.delegate didReceiveMessage:message]; 83 | } 84 | - (void)webSocketDidOpen:(SRWebSocket *)webSocket 85 | { 86 | self.connected = YES; 87 | if ([self.delegate respondsToSelector:@selector(didOpen)]) { 88 | [self.delegate didOpen]; 89 | } 90 | } 91 | - (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean 92 | { 93 | if (!self.connected || wasClean) { 94 | if ([self.delegate respondsToSelector:@selector(didClose)]) { 95 | [self.delegate didClose]; 96 | } 97 | } else { // Socket disconnections can be errors, but with socket.io was clean always seems to be false, so we'll check on our own 98 | [self webSocket:webSocket didFailWithError:nil]; 99 | } 100 | } 101 | - (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error 102 | { 103 | self.connected = NO; 104 | [self.delegate didFailWithError:error]; 105 | } 106 | @end 107 | -------------------------------------------------------------------------------- /Pods/AZSocketIO/AZSocketIO/Transports/AZxhrTransport.h: -------------------------------------------------------------------------------- 1 | // 2 | // AZxhrTransport.h 3 | // AZSocketIO 4 | // 5 | // Created by Patrick Shields on 5/15/12. 6 | // Copyright 2012 Patrick Shields 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // 20 | 21 | #import 22 | #import "AZSocketIOTransport.h" 23 | #import 24 | 25 | @interface AZxhrTransport : NSObject 26 | @property(nonatomic, strong)AFHTTPRequestOperationManager *client; 27 | @end 28 | -------------------------------------------------------------------------------- /Pods/AZSocketIO/AZSocketIO/Transports/AZxhrTransport.m: -------------------------------------------------------------------------------- 1 | // 2 | // AZxhrTransport.m 3 | // AZSocketIO 4 | // 5 | // Created by Patrick Shields on 5/15/12. 6 | // Copyright 2012 Patrick Shields 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // 20 | 21 | #import "AZxhrTransport.h" 22 | #import 23 | #import "AZSocketIOTransportDelegate.h" 24 | 25 | @interface AZxhrTransport () 26 | @property(nonatomic, weak)id delegate; 27 | @property(nonatomic, readwrite, assign)BOOL connected; 28 | @end 29 | 30 | @implementation AZxhrTransport 31 | @synthesize client; 32 | @synthesize secureConnections; 33 | @synthesize delegate; 34 | @synthesize connected; 35 | - (void)connect 36 | { 37 | [self.client GET:@"" 38 | parameters:nil 39 | success:^(AFHTTPRequestOperation *operation, id responseObject) { 40 | self.connected = YES; 41 | if ([self.delegate respondsToSelector:@selector(didOpen)]) { 42 | [self.delegate didOpen]; 43 | } 44 | NSString *responseString = [self stringFromData:responseObject]; 45 | NSArray *messages = [responseString componentsSeparatedByString:@"\ufffd"]; 46 | if ([messages count] > 0) { 47 | for (NSString *message in messages) { 48 | [self.delegate didReceiveMessage:message]; 49 | } 50 | } else { 51 | [self.delegate didReceiveMessage:responseString]; 52 | } 53 | 54 | if (self.connected) { 55 | [self connect]; 56 | } 57 | } 58 | failure:^(AFHTTPRequestOperation *operation, NSError *error) { 59 | [self.delegate didFailWithError:error]; 60 | if ([self.delegate respondsToSelector:@selector(didClose)]) { 61 | [self.delegate didClose]; 62 | } 63 | }]; 64 | 65 | } 66 | - (void)disconnect 67 | { 68 | [self.client.operationQueue cancelAllOperations]; 69 | [self.client GET:@"?disconnect" 70 | parameters:nil 71 | success:nil 72 | failure:nil]; 73 | 74 | self.connected = NO; 75 | if ([self.delegate respondsToSelector:@selector(didClose)]) { 76 | [self.delegate didClose]; 77 | } 78 | } 79 | - (void)send:(NSString*)msg 80 | { 81 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:self.client.baseURL]; 82 | request.HTTPMethod = @"POST"; 83 | [request setHTTPBody:[msg dataUsingEncoding:NSUTF8StringEncoding]]; 84 | [request setValue:@"text/plain; charset=UTF-8" forHTTPHeaderField:@"Content-Type"]; 85 | [request setValue:@"Keep-Alive" forHTTPHeaderField:@"Connection"]; 86 | 87 | [self.client HTTPRequestOperationWithRequest:request 88 | success:^(AFHTTPRequestOperation *operation, id responseObject) { 89 | if ([self.delegate respondsToSelector:@selector(didSendMessage)]) { 90 | [self.delegate didSendMessage]; 91 | } 92 | } 93 | failure:^(AFHTTPRequestOperation *operation, NSError *error) { 94 | [self.delegate didFailWithError:error]; 95 | }]; 96 | } 97 | - (id)initWithDelegate:(id)_delegate secureConnections:(BOOL)_secureConnections 98 | { 99 | self = [super init]; 100 | if (self) { 101 | self.connected = NO; 102 | self.delegate = _delegate; 103 | self.secureConnections = _secureConnections; 104 | 105 | NSString *protocolString = self.secureConnections ? @"https://" : @"http://"; 106 | NSString *urlString = [NSString stringWithFormat:@"%@%@:%@/socket.io/1/xhr-polling/%@", 107 | protocolString, [self.delegate host], [self.delegate port], 108 | [self.delegate sessionId]]; 109 | 110 | self.client = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:urlString]]; 111 | self.client.requestSerializer.stringEncoding = NSUTF8StringEncoding; 112 | self.client.responseSerializer = [AFHTTPResponseSerializer serializer]; 113 | self.client.responseSerializer.stringEncoding = NSUTF8StringEncoding; 114 | } 115 | return self; 116 | } 117 | - (NSString *)stringFromData:(NSData *)data 118 | { 119 | return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 120 | } 121 | @end 122 | -------------------------------------------------------------------------------- /Pods/AZSocketIO/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2012 Patrick Shields 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /Pods/AZSocketIO/README.md: -------------------------------------------------------------------------------- 1 | AZSocketIO 2 | ========== 3 | AZSocketIO is a socket.io client for iOS. It: 4 | 5 | * Supports websockets and xhr-polling transports 6 | * Is about alpha stage 7 | * Is heavily reliant on blocks for it's API 8 | * Has appledocs for all user facing classes 9 | * Welcomes patches and issues 10 | 11 | It does not currently support namespacing a socket. 12 | 13 | Dependencies 14 | ------------ 15 | AZSocketIO uses cocoapods, so you shouldn't have to think too much about dependencies, but here they are. 16 | 17 | * [SocketRocket](https://github.com/square/SocketRocket) 18 | * [AFNetworking](https://github.com/AFNetworking/AFNetworking) 19 | 20 | AZSocketIO uses NSJSONSerialization, so it's iOS 5+. 21 | 22 | Usage 23 | ----- 24 | ``` objective-c 25 | AZSocketIO *socket = [[AZSocketIO alloc] initWithHost:@"localhost" andPort:@"9000" secure:NO]; 26 | [socket setEventRecievedBlock:^(NSString *eventName, id data) { 27 | NSLog(@"%@ : %@", eventName, data); 28 | }]; 29 | [socket connectWithSuccess:^{ 30 | [socket emit:@"Send Me Data" args:@"cows" error:nil]; 31 | } andFailure:^(NSError *error) { 32 | NSLog(@"Boo: %@", error); 33 | }]; 34 | ``` 35 | 36 | Author 37 | ------- 38 | Pat Shields 39 | 40 | * http://github.com/pashields 41 | * http://twitter.com/whatidoissecret 42 | 43 | Contributors 44 | ------------ 45 | * Luca Bernardi (https://github.com/lukabernardi) 46 | * Oli Kingshott (https://github.com/oliland) 47 | 48 | License 49 | ------- 50 | Apache 2.0 51 | -------------------------------------------------------------------------------- /Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - AFNetworking (2.6.3): 3 | - AFNetworking/NSURLConnection (= 2.6.3) 4 | - AFNetworking/NSURLSession (= 2.6.3) 5 | - AFNetworking/Reachability (= 2.6.3) 6 | - AFNetworking/Security (= 2.6.3) 7 | - AFNetworking/Serialization (= 2.6.3) 8 | - AFNetworking/UIKit (= 2.6.3) 9 | - AFNetworking/NSURLConnection (2.6.3): 10 | - AFNetworking/Reachability 11 | - AFNetworking/Security 12 | - AFNetworking/Serialization 13 | - AFNetworking/NSURLSession (2.6.3): 14 | - AFNetworking/Reachability 15 | - AFNetworking/Security 16 | - AFNetworking/Serialization 17 | - AFNetworking/Reachability (2.6.3) 18 | - AFNetworking/Security (2.6.3) 19 | - AFNetworking/Serialization (2.6.3) 20 | - AFNetworking/UIKit (2.6.3): 21 | - AFNetworking/NSURLConnection 22 | - AFNetworking/NSURLSession 23 | - AZSocketIO (0.0.6): 24 | - AFNetworking (~> 2.x) 25 | - SocketRocket (~> 0.x) 26 | - libjingle_peerconnection (10604.2.2) 27 | - SocketRocket (0.4.2) 28 | - TLKSimpleWebRTC (1.0.0): 29 | - AZSocketIO (= 0.0.6) 30 | - TLKWebRTC (2.1.0) 31 | 32 | DEPENDENCIES: 33 | - libjingle_peerconnection 34 | - TLKSimpleWebRTC (from `https://github.com/otalk/TLKSimpleWebRTC.git`) 35 | - TLKWebRTC (from `https://github.com/otalk/TLKWebRTC.git`) 36 | 37 | EXTERNAL SOURCES: 38 | TLKSimpleWebRTC: 39 | :git: https://github.com/otalk/TLKSimpleWebRTC.git 40 | TLKWebRTC: 41 | :git: https://github.com/otalk/TLKWebRTC.git 42 | 43 | CHECKOUT OPTIONS: 44 | TLKSimpleWebRTC: 45 | :commit: a459335423e98e4540222a86e457f7778c0d9b05 46 | :git: https://github.com/otalk/TLKSimpleWebRTC.git 47 | TLKWebRTC: 48 | :commit: 9d5f8dfc9791fe9e541a5ad69b8b763fdbbc94d3 49 | :git: https://github.com/otalk/TLKWebRTC.git 50 | 51 | SPEC CHECKSUMS: 52 | AFNetworking: cb8d14a848e831097108418f5d49217339d4eb60 53 | AZSocketIO: 135d76d11e90a0b7509f0f64d448fc8d0cd96e4f 54 | libjingle_peerconnection: e2068e7c6859c64409345931ee035616c893c107 55 | SocketRocket: ffe08119b00ef982f6c37052a4705a057c8494ad 56 | TLKSimpleWebRTC: be2ec60106ed78c034c2a85a2945c49ccf92131f 57 | TLKWebRTC: ac347a4b53024a2e81ff843d3e984bb1337d3d79 58 | 59 | COCOAPODS: 0.39.0 60 | -------------------------------------------------------------------------------- /Pods/SocketRocket/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright 2012 Square Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | -------------------------------------------------------------------------------- /Pods/SocketRocket/README.rst: -------------------------------------------------------------------------------- 1 | SocketRocket Objective-C WebSocket Client (beta) 2 | ================================================ 3 | A conforming WebSocket (`RFC 6455 `_) 4 | client library. 5 | 6 | `Test results for SocketRocket here `_. 7 | You can compare to what `modern browsers look like here 8 | `_. 9 | 10 | SocketRocket currently conforms to all ~300 of `Autobahn 11 | `_'s fuzzing tests (aside from 12 | two UTF-8 ones where it is merely *non-strict*. tests 6.4.2 and 6.4.4) 13 | 14 | Features/Design 15 | --------------- 16 | - TLS (wss) support. It uses CFStream so we get this for *free* 17 | - Uses NSStream/CFNetworking. Earlier implementations used ``dispatch_io``, 18 | however, this proved to be make TLS nearly impossible. Also I wanted this to 19 | work in iOS 4.x. (SocketRocket only supports 5.0 and above now) 20 | - Uses ARC. It uses the 4.0 compatible subset (no weak refs). 21 | - Seems to perform quite well 22 | - Parallel architecture. Most of the work is done in background worker queues. 23 | - Delegate-based. Had older versions that could use blocks too, but I felt it 24 | didn't blend well with retain cycles and just objective C in general. 25 | 26 | Changes 27 | ------- 28 | 29 | v0.3.1-beta2 - 2013-01-12 30 | ````````````````````````` 31 | 32 | - Stability fix for ``closeWithCode:reason:`` (Thanks @michaelpetrov!) 33 | - Actually clean up the NSStreams and remove them from their runloops 34 | - ``_SRRunLoopThread``'s ``main`` wasn't correctly wrapped with 35 | ``@autoreleasepool`` 36 | 37 | v0.3.1-beta1 - 2013-01-12 38 | ````````````````````````` 39 | 40 | - Cleaned up GCD so OS_OBJECT_USE_OBJC_RETAIN_RELEASE is optional 41 | - Removed deprecated ``dispatch_get_current_queue`` in favor of ``dispatch_queue_set_specific`` and ``dispatch_get_specific`` 42 | - Dropping support for iOS 4.0 (it may still work) 43 | 44 | 45 | Installing (iOS) 46 | ---------------- 47 | There's a few options. Choose one, or just figure it out 48 | 49 | - You can copy all the files in the SocketRocket group into your app. 50 | - Include SocketRocket as a subproject and use libSocketRocket 51 | 52 | If you do this, you must add -ObjC to your "other linker flags" option 53 | 54 | - For OS X you will have to repackage make a .framework target. I will take 55 | contributions. Message me if you are interested. 56 | 57 | 58 | Depending on how you configure your project you may need to ``#import`` either 59 | ```` or ``"SRWebSocket.h"`` 60 | 61 | Framework Dependencies 62 | `````````````````````` 63 | Your .app must be linked against the following frameworks/dylibs 64 | 65 | - libicucore.dylib 66 | - CFNetwork.framework 67 | - Security.framework 68 | - Foundation.framework 69 | 70 | Installing (OS X) 71 | ----------------- 72 | SocketRocket now has (64-bit only) OS X support. ``SocketRocket.framework`` 73 | inside Xcode project is for OS X only. It should be identical in function aside 74 | from the unicode validation. ICU isn't shipped with OS X which is what the 75 | original implementation used for unicode validation. The workaround is much 76 | more rudimentary and less robust. 77 | 78 | 1. Add SocketRocket.xcodeproj as either a subproject of your app or in your workspace. 79 | 2. Add ``SocketRocket.framework`` to the link libraries 80 | 3. If you don't have a "copy files" step for ``Framework``, create one 81 | 4. Add ``SocketRocket.framework`` to the "copy files" step. 82 | 83 | API 84 | --- 85 | The classes 86 | 87 | ``SRWebSocket`` 88 | ``````````````` 89 | The Web Socket. 90 | 91 | .. note:: ``SRWebSocket`` will retain itself between ``-(void)open`` and when it 92 | closes, errors, or fails. This is similar to how ``NSURLConnection`` behaves. 93 | (unlike ``NSURLConnection``, ``SRWebSocket`` won't retain the delegate) 94 | 95 | What you need to know 96 | 97 | .. code-block:: objective-c 98 | 99 | @interface SRWebSocket : NSObject 100 | 101 | // Make it with this 102 | - (id)initWithURLRequest:(NSURLRequest *)request; 103 | 104 | // Set this before opening 105 | @property (nonatomic, assign) id delegate; 106 | 107 | - (void)open; 108 | 109 | // Close it with this 110 | - (void)close; 111 | 112 | // Send a UTF8 String or Data 113 | - (void)send:(id)data; 114 | 115 | @end 116 | 117 | ``SRWebSocketDelegate`` 118 | ``````````````````````` 119 | You implement this 120 | 121 | .. code-block:: objective-c 122 | 123 | @protocol SRWebSocketDelegate 124 | 125 | - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message; 126 | 127 | @optional 128 | 129 | - (void)webSocketDidOpen:(SRWebSocket *)webSocket; 130 | - (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error; 131 | - (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean; 132 | 133 | @end 134 | 135 | Known Issues/Server Todo's 136 | -------------------------- 137 | - Needs auth delegates (like in NSURLConnection) 138 | - Move the streams off the main runloop (most of the work is backgrounded uses 139 | GCD, but I just haven't gotten around to moving it off the main loop since I 140 | converted it from dispatch_io) 141 | - Re-implement server. I removed an existing implementation as well because it 142 | wasn't being used and I wasn't super happy with the interface. Will revisit 143 | this. 144 | - Separate framer and client logic. This will make it nicer when having a 145 | server. 146 | 147 | Testing 148 | ------- 149 | Included are setup scripts for the python testing environment. It comes 150 | packaged with vitualenv so all the dependencies are installed in userland. 151 | 152 | To run the short test from the command line, run:: 153 | 154 | make test 155 | 156 | To run all the tests, run:: 157 | 158 | make test_all 159 | 160 | The short tests don't include the performance tests. (the test harness is 161 | actually the bottleneck, not SocketRocket). 162 | 163 | The first time this is run, it may take a while to install the dependencies. It 164 | will be smooth sailing after that. After the test runs the makefile will open 165 | the results page in your browser. If nothing comes up, you failed. Working on 166 | making this interface a bit nicer. 167 | 168 | To run from the app, choose the ``SocketRocket`` target and run the test action 169 | (``cmd+u``). It runs the same thing, but makes it easier to debug. There is 170 | some serious pre/post hooks in the Test action. You can edit it to customize 171 | behavior. 172 | 173 | .. note:: Xcode only up to version 4.4 is currently supported for the test 174 | harness 175 | 176 | TestChat Demo Application 177 | ------------------------- 178 | SocketRocket includes a demo app, TestChat. It will "chat" with a listening 179 | websocket on port 9900. 180 | 181 | It's a simple project. Uses storyboard. Storyboard is sweet. 182 | 183 | 184 | TestChat Server 185 | ``````````````` 186 | We've included a small server for the chat app. It has a simple function. 187 | It will take a message and broadcast it to all other connected clients. 188 | 189 | We have to get some dependencies. We also want to reuse the virtualenv we made 190 | when we ran the tests. If you haven't run the tests yet, go into the 191 | SocketRocket root directory and type:: 192 | 193 | make test 194 | 195 | This will set up your `virtualenv `_. 196 | Now, in your terminal:: 197 | 198 | source .env/bin/activate 199 | pip install git+https://github.com/facebook/tornado.git 200 | 201 | In the same terminal session, start the chatroom server:: 202 | 203 | python TestChatServer/py/chatroom.py 204 | 205 | There's also a Go implementation (with the latest weekly) where you can:: 206 | 207 | cd TestChatServer/go 208 | go run chatroom.go 209 | 210 | Chatting 211 | ```````` 212 | Now, start TestChat.app (just run the target in the XCode project). If you had 213 | it started already you can hit the refresh button to reconnect. It should say 214 | "Connected!" on top. 215 | 216 | To talk with the app, open up your browser to `http://localhost:9000 `_ and 217 | start chatting. 218 | 219 | 220 | WebSocket Server Implementation Recommendations 221 | ----------------------------------------------- 222 | SocketRocket has been used with the following libraries: 223 | 224 | - `Tornado `_ 225 | - Go's `WebSocket package `_ or Gorilla's `version `_ 226 | - `Autobahn `_ (using its fuzzing 227 | client) 228 | 229 | The Tornado one is dirt simple and works like a charm. (`IPython notebook 230 | `_ uses it 231 | too). It's much easier to configure handlers and routes than in 232 | Autobahn/twisted. 233 | 234 | As far as Go's goes, it works in my limited testing. I much prefer go's 235 | concurrency model as well. Try it! You may like it. 236 | It could use some more control over things such as pings, etc., but I 237 | am sure it will come in time. 238 | 239 | Autobahn is a great test suite. The Python server code is good, and conforms 240 | well (obviously). However for me, twisted would be a deal-breaker for writing 241 | something new. I find it a bit too complex and heavy for a simple service. If 242 | you are already using twisted though, Autobahn is probably for you. 243 | 244 | Contributing 245 | ------------ 246 | Any contributors to the master SocketRocket repository must sign the `Individual 247 | Contributor License Agreement 248 | (CLA) 249 | `_. 250 | It's a short form that covers our bases and makes sure you're eligible to 251 | contribute. 252 | 253 | When you have a change you'd like to see in the master repository, `send a pull 254 | request `_. Before we merge your 255 | request, we'll make sure you're in the list of people who have signed a CLA. 256 | -------------------------------------------------------------------------------- /Pods/SocketRocket/SocketRocket/SRWebSocket.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2012 Square Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | #import 18 | #import 19 | 20 | typedef NS_ENUM(NSInteger, SRReadyState) { 21 | SR_CONNECTING = 0, 22 | SR_OPEN = 1, 23 | SR_CLOSING = 2, 24 | SR_CLOSED = 3, 25 | }; 26 | 27 | typedef enum SRStatusCode : NSInteger { 28 | SRStatusCodeNormal = 1000, 29 | SRStatusCodeGoingAway = 1001, 30 | SRStatusCodeProtocolError = 1002, 31 | SRStatusCodeUnhandledType = 1003, 32 | // 1004 reserved. 33 | SRStatusNoStatusReceived = 1005, 34 | // 1004-1006 reserved. 35 | SRStatusCodeInvalidUTF8 = 1007, 36 | SRStatusCodePolicyViolated = 1008, 37 | SRStatusCodeMessageTooBig = 1009, 38 | } SRStatusCode; 39 | 40 | @class SRWebSocket; 41 | 42 | extern NSString *const SRWebSocketErrorDomain; 43 | extern NSString *const SRHTTPResponseErrorKey; 44 | 45 | #pragma mark - SRWebSocketDelegate 46 | 47 | @protocol SRWebSocketDelegate; 48 | 49 | #pragma mark - SRWebSocket 50 | 51 | @interface SRWebSocket : NSObject 52 | 53 | @property (nonatomic, weak) id delegate; 54 | 55 | @property (nonatomic, readonly) SRReadyState readyState; 56 | @property (nonatomic, readonly, retain) NSURL *url; 57 | 58 | 59 | @property (nonatomic, readonly) CFHTTPMessageRef receivedHTTPHeaders; 60 | 61 | // Optional array of cookies (NSHTTPCookie objects) to apply to the connections 62 | @property (nonatomic, readwrite) NSArray * requestCookies; 63 | 64 | // This returns the negotiated protocol. 65 | // It will be nil until after the handshake completes. 66 | @property (nonatomic, readonly, copy) NSString *protocol; 67 | 68 | // Protocols should be an array of strings that turn into Sec-WebSocket-Protocol. 69 | - (id)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray *)protocols allowsUntrustedSSLCertificates:(BOOL)allowsUntrustedSSLCertificates; 70 | - (id)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray *)protocols; 71 | - (id)initWithURLRequest:(NSURLRequest *)request; 72 | 73 | // Some helper constructors. 74 | - (id)initWithURL:(NSURL *)url protocols:(NSArray *)protocols allowsUntrustedSSLCertificates:(BOOL)allowsUntrustedSSLCertificates; 75 | - (id)initWithURL:(NSURL *)url protocols:(NSArray *)protocols; 76 | - (id)initWithURL:(NSURL *)url; 77 | 78 | // Delegate queue will be dispatch_main_queue by default. 79 | // You cannot set both OperationQueue and dispatch_queue. 80 | - (void)setDelegateOperationQueue:(NSOperationQueue*) queue; 81 | - (void)setDelegateDispatchQueue:(dispatch_queue_t) queue; 82 | 83 | // By default, it will schedule itself on +[NSRunLoop SR_networkRunLoop] using defaultModes. 84 | - (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode; 85 | - (void)unscheduleFromRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode; 86 | 87 | // SRWebSockets are intended for one-time-use only. Open should be called once and only once. 88 | - (void)open; 89 | 90 | - (void)close; 91 | - (void)closeWithCode:(NSInteger)code reason:(NSString *)reason; 92 | 93 | // Send a UTF8 String or Data. 94 | - (void)send:(id)data; 95 | 96 | // Send Data (can be nil) in a ping message. 97 | - (void)sendPing:(NSData *)data; 98 | 99 | @end 100 | 101 | #pragma mark - SRWebSocketDelegate 102 | 103 | @protocol SRWebSocketDelegate 104 | 105 | // message will either be an NSString if the server is using text 106 | // or NSData if the server is using binary. 107 | - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message; 108 | 109 | @optional 110 | 111 | - (void)webSocketDidOpen:(SRWebSocket *)webSocket; 112 | - (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error; 113 | - (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean; 114 | - (void)webSocket:(SRWebSocket *)webSocket didReceivePong:(NSData *)pongPayload; 115 | 116 | @end 117 | 118 | #pragma mark - NSURLRequest (CertificateAdditions) 119 | 120 | @interface NSURLRequest (CertificateAdditions) 121 | 122 | @property (nonatomic, retain, readonly) NSArray *SR_SSLPinnedCertificates; 123 | 124 | @end 125 | 126 | #pragma mark - NSMutableURLRequest (CertificateAdditions) 127 | 128 | @interface NSMutableURLRequest (CertificateAdditions) 129 | 130 | @property (nonatomic, retain) NSArray *SR_SSLPinnedCertificates; 131 | 132 | @end 133 | 134 | #pragma mark - NSRunLoop (SRWebSocket) 135 | 136 | @interface NSRunLoop (SRWebSocket) 137 | 138 | + (NSRunLoop *)SR_networkRunLoop; 139 | 140 | @end 141 | -------------------------------------------------------------------------------- /Pods/TLKSimpleWebRTC/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2014 Jon Hjelle 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Pods/TLKSimpleWebRTC/README.md: -------------------------------------------------------------------------------- 1 | # TLKSimpleWebRTC 2 | 3 | A iOS interface to connect to WebRTC sessions using a [Signalmaster](https://github.com/andyet/signalmaster) 4 | based signaling server using Socket.io. 5 | 6 | Usage 7 | ----- 8 | 9 | See [otalk/iOS-demo](https://github.com/otalk/iOS-demo) for an example application using the interface. 10 | 11 | **Build Environment** 12 | 13 | We recommend pulling the open source code (TLKSimpleWebRTC, as well as TLKWebRTC - a small part of the project 14 | that is independent of the signaling server) and the precompiled iOS libraries via CocoaPods. 15 | 16 | Here's the Podfile that we use for that: 17 | 18 | target "ios-demo" do 19 | 20 | pod 'libjingle_peerconnection' 21 | pod 'TLKWebRTC', :git => 'https://github.com/otalk/TLKWebRTC.git' 22 | pod 'TLKSimpleWebRTC', :git => 'https://github.com/otalk/TLKSimpleWebRTC.git' 23 | 24 | end 25 | 26 | **Connecting to the signaling server** 27 | 28 | You can connect to the signaling server by allocating a TLKSocketIOSignaling object. You'll also need to set 29 | a delegate to receive messages from the signaling server. 30 | 31 | self.signaling = [[TLKSocketIOSignaling alloc] initWithVideo:YES]; 32 | self.signaling.delegate = self; 33 | 34 | To join a chat, you need to both connect to a server and join a room. 35 | 36 | [self.signaling connectToServer:@"signaling.simplewebrtc.com" port:80 secure:NO success:^{ 37 | [self.signaling joinRoom:@"ios-demo" success:^{ 38 | NSLog(@"join success"); 39 | } failure:^{ 40 | NSLog(@"join failure"); 41 | }]; 42 | NSLog(@"connect success"); 43 | } failure:^(NSError* error) { 44 | NSLog(@"connect failure"); 45 | }]; 46 | 47 | 48 | **Showing the video** 49 | 50 | TLKSimpleWebRTC doesn't provide any interfaces for showing the video, but you can do it with the WebRTC Objective-C 51 | interface (headers included with the precompiled WebRTC libs). Create a RTCEAGLVideoView to render in response to delegate calls from TLKSocketIOSignaling. 52 | 53 | @interface ViewController () 54 | @property (strong, nonatomic) RTCEAGLVideoView* remoteView; 55 | @end 56 | 57 | //... 58 | 59 | - (void)addedStream:(TLKMediaStream *)stream { 60 | if (!self.remoteView) { 61 | self.remoteView = [[RTCEAGLVideoView alloc] initWithFrame:CGRectMake(0, 0, 640, 480)]; 62 | self.remoteView.delegate = self; 63 | [self.view addSubview:self.renderView]; 64 | 65 | [(RTCVideoTrack*)stream.stream.videoTracks[0] addRenderer:self.remoteView]; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Pods/TLKWebRTC/Classes/TLKWebRTC.h: -------------------------------------------------------------------------------- 1 | // 2 | // TLKWebRTC.h 3 | // Copyright (c) 2014 &yet, LLC and TLKWebRTC contributors 4 | // 5 | 6 | #import 7 | 8 | #import "RTCSessionDescription.h" 9 | #import "RTCICECandidate.h" 10 | #import "RTCMediaStream.h" 11 | #import "RTCTypes.h" 12 | 13 | @class RTCICEServer; 14 | 15 | @class AVCaptureDevice; 16 | 17 | @protocol TLKWebRTCDelegate; 18 | 19 | @interface TLKWebRTC : NSObject 20 | 21 | @property (nonatomic, weak) id delegate; 22 | 23 | - (instancetype)initWithVideoDevice:(AVCaptureDevice *)device; 24 | - (instancetype)initWithVideo:(BOOL)allowVideo; 25 | 26 | - (void)addPeerConnectionForID:(NSString *)identifier; 27 | - (void)removePeerConnectionForID:(NSString *)identifier; 28 | 29 | - (void)createOfferForPeerWithID:(NSString *)peerID; 30 | - (void)setRemoteDescription:(RTCSessionDescription *)remoteSDP forPeerWithID:(NSString *)peerID receiver:(BOOL)isReceiver; 31 | - (void)addICECandidate:(RTCICECandidate *)candidate forPeerWithID:(NSString *)peerID; 32 | 33 | // Add a STUN or TURN server, adding a STUN server replaces the previous STUN server, adding a TURN server appends it to the list 34 | - (void)addICEServer:(RTCICEServer *)server; 35 | 36 | // The WebRTC stream captured locally that will be sent to peers, useful for displaying a preview of the local camera 37 | // in an RTCVideoRenderer and muting or blacking out th stream sent to peers 38 | @property (readonly, nonatomic) RTCMediaStream *localMediaStream; 39 | 40 | @end 41 | 42 | // WebRTC signal delegate protocol 43 | @protocol TLKWebRTCDelegate 44 | @required 45 | - (void)webRTC:(TLKWebRTC *)webRTC didSendSDPOffer:(RTCSessionDescription *)offer forPeerWithID:(NSString *)peerID; 46 | - (void)webRTC:(TLKWebRTC *)webRTC didSendSDPAnswer:(RTCSessionDescription *)answer forPeerWithID:(NSString* )peerID; 47 | - (void)webRTC:(TLKWebRTC *)webRTC didSendICECandidate:(RTCICECandidate *)candidate forPeerWithID:(NSString *)peerID; 48 | - (void)webRTC:(TLKWebRTC *)webRTC didObserveICEConnectionStateChange:(RTCICEConnectionState)state forPeerWithID:(NSString *)peerID; 49 | 50 | - (void)webRTC:(TLKWebRTC *)webRTC addedStream:(RTCMediaStream *)stream forPeerWithID:(NSString *)peerID; 51 | - (void)webRTC:(TLKWebRTC *)webRTC removedStream:(RTCMediaStream *)stream forPeerWithID:(NSString *)peerID; 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /Pods/TLKWebRTC/Classes/TLKWebRTC.m: -------------------------------------------------------------------------------- 1 | // 2 | // TLKWebRTC.m 3 | // Copyright (c) 2014 &yet, LLC and TLKWebRTC contributors 4 | // 5 | 6 | #import "TLKWebRTC.h" 7 | 8 | #import 9 | 10 | #import "RTCPeerConnectionFactory.h" 11 | #import "RTCPeerConnection.h" 12 | #import "RTCICEServer.h" 13 | #import "RTCPair.h" 14 | #import "RTCMediaConstraints.h" 15 | #import "RTCSessionDescription.h" 16 | #import "RTCSessionDescriptionDelegate.h" 17 | #import "RTCPeerConnectionDelegate.h" 18 | 19 | #import "RTCAudioTrack.h" 20 | #import "RTCAVFoundationVideoSource.h" 21 | #import "RTCVideoTrack.h" 22 | 23 | @interface TLKWebRTC () < 24 | RTCSessionDescriptionDelegate, 25 | RTCPeerConnectionDelegate> 26 | 27 | @property (readwrite, nonatomic) RTCMediaStream *localMediaStream; 28 | 29 | @property (nonatomic, strong) RTCPeerConnectionFactory *peerFactory; 30 | @property (nonatomic, strong) NSMutableDictionary *peerConnections; 31 | @property (nonatomic, strong) NSMutableDictionary *peerToRoleMap; 32 | @property (nonatomic, strong) NSMutableDictionary *peerToICEMap; 33 | 34 | @property (nonatomic) BOOL allowVideo; 35 | @property (nonatomic, strong) AVCaptureDevice *videoDevice; 36 | 37 | @property (nonatomic, strong) NSMutableArray *iceServers; 38 | 39 | @end 40 | 41 | static NSString * const TLKPeerConnectionRoleInitiator = @"TLKPeerConnectionRoleInitiator"; 42 | static NSString * const TLKPeerConnectionRoleReceiver = @"TLKPeerConnectionRoleReceiver"; 43 | static NSString * const TLKWebRTCSTUNHostname = @"stun:stun.l.google.com:19302"; 44 | 45 | @implementation TLKWebRTC 46 | 47 | #pragma mark - object lifecycle 48 | 49 | - (instancetype)initWithVideoDevice:(AVCaptureDevice *)device { 50 | self = [super init]; 51 | if (self) { 52 | if (device) { 53 | _allowVideo = YES; 54 | _videoDevice = device; 55 | } 56 | [self _commonSetup]; 57 | } 58 | return self; 59 | } 60 | 61 | - (instancetype)initWithVideo:(BOOL)allowVideo { 62 | // Set front camera as the default device 63 | AVCaptureDevice* frontCamera; 64 | if (allowVideo) { 65 | frontCamera = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo] lastObject]; 66 | } 67 | return [self initWithVideoDevice:frontCamera]; 68 | } 69 | 70 | - (instancetype)init { 71 | // Use default device 72 | return [self initWithVideo:YES]; 73 | } 74 | 75 | - (void)_commonSetup { 76 | _peerFactory = [[RTCPeerConnectionFactory alloc] init]; 77 | _peerConnections = [NSMutableDictionary dictionary]; 78 | _peerToRoleMap = [NSMutableDictionary dictionary]; 79 | _peerToICEMap = [NSMutableDictionary dictionary]; 80 | 81 | self.iceServers = [NSMutableArray new]; 82 | RTCICEServer *defaultStunServer = [[RTCICEServer alloc] initWithURI:[NSURL URLWithString:TLKWebRTCSTUNHostname] username:@"" password:@""]; 83 | [self.iceServers addObject:defaultStunServer]; 84 | 85 | [RTCPeerConnectionFactory initializeSSL]; 86 | 87 | [self _createLocalStream]; 88 | } 89 | 90 | - (void)_createLocalStream { 91 | self.localMediaStream = [self.peerFactory mediaStreamWithLabel:[[NSUUID UUID] UUIDString]]; 92 | 93 | RTCAudioTrack *audioTrack = [self.peerFactory audioTrackWithID:[[NSUUID UUID] UUIDString]]; 94 | [self.localMediaStream addAudioTrack:audioTrack]; 95 | 96 | if (self.allowVideo) { 97 | RTCAVFoundationVideoSource *videoSource = [[RTCAVFoundationVideoSource alloc] initWithFactory:self.peerFactory constraints:nil]; 98 | videoSource.useBackCamera = NO; 99 | RTCVideoTrack *videoTrack = [[RTCVideoTrack alloc] initWithFactory:self.peerFactory source:videoSource trackId:[[NSUUID UUID] UUIDString]]; 100 | [self.localMediaStream addVideoTrack:videoTrack]; 101 | } 102 | } 103 | 104 | - (RTCMediaConstraints *)_mediaConstraints { 105 | RTCPair *audioConstraint = [[RTCPair alloc] initWithKey:@"OfferToReceiveAudio" value:@"true"]; 106 | RTCPair *videoConstraint = [[RTCPair alloc] initWithKey:@"OfferToReceiveVideo" value:self.allowVideo ? @"true" : @"false"]; 107 | RTCPair *sctpConstraint = [[RTCPair alloc] initWithKey:@"internalSctpDataChannels" value:@"true"]; 108 | RTCPair *dtlsConstraint = [[RTCPair alloc] initWithKey:@"DtlsSrtpKeyAgreement" value:@"true"]; 109 | 110 | return [[RTCMediaConstraints alloc] initWithMandatoryConstraints:@[audioConstraint, videoConstraint] optionalConstraints:@[sctpConstraint, dtlsConstraint]]; 111 | } 112 | 113 | #pragma mark - ICE server 114 | 115 | - (void)addICEServer:(RTCICEServer *)server { 116 | BOOL isStun = [server.URI.scheme isEqualToString:@"stun"]; 117 | if (isStun) { 118 | // Array of servers is always stored with stun server in first index, and we only want one, 119 | // so if this is a stun server, replace it 120 | [self.iceServers replaceObjectAtIndex:0 withObject:server]; 121 | } 122 | else { 123 | [self.iceServers addObject:server]; 124 | } 125 | } 126 | 127 | #pragma mark - Peer Connections 128 | 129 | - (NSString *)identifierForPeer:(RTCPeerConnection *)peer { 130 | NSArray *keys = [self.peerConnections allKeysForObject:peer]; 131 | return (keys.count == 0) ? nil : keys[0]; 132 | } 133 | 134 | - (void)addPeerConnectionForID:(NSString *)identifier { 135 | RTCPeerConnection *peer = [self.peerFactory peerConnectionWithICEServers:[self iceServers] constraints:[self _mediaConstraints] delegate:self]; 136 | [peer addStream:self.localMediaStream]; 137 | [self.peerConnections setObject:peer forKey:identifier]; 138 | } 139 | 140 | - (void)removePeerConnectionForID:(NSString *)identifier { 141 | RTCPeerConnection* peer = self.peerConnections[identifier]; 142 | [self.peerConnections removeObjectForKey:identifier]; 143 | [self.peerToRoleMap removeObjectForKey:identifier]; 144 | [peer close]; 145 | } 146 | 147 | #pragma mark - 148 | 149 | - (void)createOfferForPeerWithID:(NSString *)peerID { 150 | RTCPeerConnection *peerConnection = [self.peerConnections objectForKey:peerID]; 151 | [self.peerToRoleMap setObject:TLKPeerConnectionRoleInitiator forKey:peerID]; 152 | [peerConnection createOfferWithDelegate:self constraints:[self _mediaConstraints]]; 153 | } 154 | 155 | - (void)setRemoteDescription:(RTCSessionDescription *)remoteSDP forPeerWithID:(NSString *)peerID receiver:(BOOL)isReceiver { 156 | RTCPeerConnection *peerConnection = [self.peerConnections objectForKey:peerID]; 157 | if (isReceiver) { 158 | [self.peerToRoleMap setObject:TLKPeerConnectionRoleReceiver forKey:peerID]; 159 | } 160 | [peerConnection setRemoteDescriptionWithDelegate:self sessionDescription:remoteSDP]; 161 | } 162 | 163 | - (void)addICECandidate:(RTCICECandidate*)candidate forPeerWithID:(NSString *)peerID { 164 | RTCPeerConnection *peerConnection = [self.peerConnections objectForKey:peerID]; 165 | if (peerConnection.iceGatheringState == RTCICEGatheringNew) { 166 | NSMutableArray *candidates = [self.peerToICEMap objectForKey:peerID]; 167 | if (!candidates) { 168 | candidates = [NSMutableArray array]; 169 | [self.peerToICEMap setObject:candidates forKey:peerID]; 170 | } 171 | [candidates addObject:candidate]; 172 | } else { 173 | [peerConnection addICECandidate:candidate]; 174 | } 175 | } 176 | 177 | #pragma mark - RTCSessionDescriptionDelegate 178 | 179 | // Note: all these delegate calls come back on a random background thread inside WebRTC, 180 | // so all are bridged across to the main thread 181 | 182 | - (void)peerConnection:(RTCPeerConnection *)peerConnection didCreateSessionDescription:(RTCSessionDescription *)sdp error:(NSError *)error { 183 | dispatch_async(dispatch_get_main_queue(), ^{ 184 | RTCSessionDescription* sessionDescription = [[RTCSessionDescription alloc] initWithType:sdp.type sdp:sdp.description]; 185 | [peerConnection setLocalDescriptionWithDelegate:self sessionDescription:sessionDescription]; 186 | }); 187 | } 188 | 189 | - (void)peerConnection:(RTCPeerConnection *)peerConnection didSetSessionDescriptionWithError:(NSError *)error { 190 | dispatch_async(dispatch_get_main_queue(), ^{ 191 | if (peerConnection.iceGatheringState == RTCICEGatheringGathering) { 192 | NSArray *keys = [self.peerConnections allKeysForObject:peerConnection]; 193 | if ([keys count] > 0) { 194 | NSArray *candidates = [self.peerToICEMap objectForKey:keys[0]]; 195 | for (RTCICECandidate* candidate in candidates) { 196 | [peerConnection addICECandidate:candidate]; 197 | } 198 | [self.peerToICEMap removeObjectForKey:keys[0]]; 199 | } 200 | } 201 | 202 | if (peerConnection.signalingState == RTCSignalingHaveLocalOffer) { 203 | NSArray *keys = [self.peerConnections allKeysForObject:peerConnection]; 204 | if ([keys count] > 0) { 205 | [self.delegate webRTC:self didSendSDPOffer:peerConnection.localDescription forPeerWithID:keys[0]]; 206 | } 207 | } else if (peerConnection.signalingState == RTCSignalingHaveRemoteOffer) { 208 | [peerConnection createAnswerWithDelegate:self constraints:[self _mediaConstraints]]; 209 | } else if (peerConnection.signalingState == RTCSignalingStable) { 210 | NSArray* keys = [self.peerConnections allKeysForObject:peerConnection]; 211 | if ([keys count] > 0) { 212 | NSString* role = [self.peerToRoleMap objectForKey:keys[0]]; 213 | if (role == TLKPeerConnectionRoleReceiver) { 214 | [self.delegate webRTC:self didSendSDPAnswer:peerConnection.localDescription forPeerWithID:keys[0]]; 215 | } 216 | } 217 | } 218 | }); 219 | } 220 | 221 | #pragma mark - String utilities 222 | 223 | - (NSString *)stringForSignalingState:(RTCSignalingState)state { 224 | NSString *signalingStateString = nil; 225 | switch (state) { 226 | case RTCSignalingStable: 227 | signalingStateString = @"Stable"; 228 | break; 229 | case RTCSignalingHaveLocalOffer: 230 | signalingStateString = @"Have Local Offer"; 231 | break; 232 | case RTCSignalingHaveRemoteOffer: 233 | signalingStateString = @"Have Remote Offer"; 234 | break; 235 | case RTCSignalingClosed: 236 | signalingStateString = @"Closed"; 237 | break; 238 | default: 239 | signalingStateString = @"Other state"; 240 | break; 241 | } 242 | 243 | return signalingStateString; 244 | } 245 | 246 | - (NSString *)stringForConnectionState:(RTCICEConnectionState)state { 247 | NSString *connectionStateString = nil; 248 | switch (state) { 249 | case RTCICEConnectionNew: 250 | connectionStateString = @"New"; 251 | break; 252 | case RTCICEConnectionChecking: 253 | connectionStateString = @"Checking"; 254 | break; 255 | case RTCICEConnectionConnected: 256 | connectionStateString = @"Connected"; 257 | break; 258 | case RTCICEConnectionCompleted: 259 | connectionStateString = @"Completed"; 260 | break; 261 | case RTCICEConnectionFailed: 262 | connectionStateString = @"Failed"; 263 | break; 264 | case RTCICEConnectionDisconnected: 265 | connectionStateString = @"Disconnected"; 266 | break; 267 | case RTCICEConnectionClosed: 268 | connectionStateString = @"Closed"; 269 | break; 270 | default: 271 | connectionStateString = @"Other state"; 272 | break; 273 | } 274 | return connectionStateString; 275 | } 276 | 277 | - (NSString *)stringForGatheringState:(RTCICEGatheringState)state { 278 | NSString *gatheringState = nil; 279 | switch (state) { 280 | case RTCICEGatheringNew: 281 | gatheringState = @"New"; 282 | break; 283 | case RTCICEGatheringGathering: 284 | gatheringState = @"Gathering"; 285 | break; 286 | case RTCICEGatheringComplete: 287 | gatheringState = @"Complete"; 288 | break; 289 | default: 290 | gatheringState = @"Other state"; 291 | break; 292 | } 293 | return gatheringState; 294 | } 295 | 296 | #pragma mark - RTCPeerConnectionDelegate 297 | 298 | // Note: all these delegate calls come back on a random background thread inside WebRTC, 299 | // so all are bridged across to the main thread 300 | 301 | - (void)peerConnectionOnError:(RTCPeerConnection *)peerConnection { 302 | // dispatch_async(dispatch_get_main_queue(), ^{ 303 | // }); 304 | } 305 | 306 | - (void)peerConnection:(RTCPeerConnection *)peerConnection signalingStateChanged:(RTCSignalingState)stateChanged { 307 | dispatch_async(dispatch_get_main_queue(), ^{ 308 | // I'm seeing this, but not sure what to do with it yet 309 | }); 310 | } 311 | 312 | - (void)peerConnection:(RTCPeerConnection *)peerConnection addedStream:(RTCMediaStream *)stream { 313 | dispatch_async(dispatch_get_main_queue(), ^{ 314 | [self.delegate webRTC:self addedStream:stream forPeerWithID:[self identifierForPeer:peerConnection]]; 315 | }); 316 | } 317 | 318 | - (void)peerConnection:(RTCPeerConnection *)peerConnection removedStream:(RTCMediaStream *)stream { 319 | dispatch_async(dispatch_get_main_queue(), ^{ 320 | [self.delegate webRTC:self removedStream:stream forPeerWithID:[self identifierForPeer:peerConnection]]; 321 | }); 322 | } 323 | 324 | - (void)peerConnectionOnRenegotiationNeeded:(RTCPeerConnection *)peerConnection { 325 | dispatch_async(dispatch_get_main_queue(), ^{ 326 | // [self.peerConnection createOfferWithDelegate:self constraints:[self mediaConstraints]]; 327 | // Is this delegate called when creating a PC that is going to *receive* an offer and return an answer? 328 | NSLog(@"peerConnectionOnRenegotiationNeeded ?"); 329 | }); 330 | } 331 | 332 | - (void)peerConnection:(RTCPeerConnection *)peerConnection iceConnectionChanged:(RTCICEConnectionState)newState { 333 | dispatch_async(dispatch_get_main_queue(), ^{ 334 | [self.delegate webRTC:self didObserveICEConnectionStateChange:newState forPeerWithID:[self identifierForPeer:peerConnection]]; 335 | }); 336 | } 337 | 338 | - (void)peerConnection:(RTCPeerConnection *)peerConnection iceGatheringChanged:(RTCICEGatheringState)newState { 339 | dispatch_async(dispatch_get_main_queue(), ^{ 340 | NSLog(@"peerConnection iceGatheringChanged?"); 341 | }); 342 | } 343 | 344 | - (void)peerConnection:(RTCPeerConnection *)peerConnection gotICECandidate:(RTCICECandidate *)candidate { 345 | dispatch_async(dispatch_get_main_queue(), ^{ 346 | 347 | NSArray* keys = [self.peerConnections allKeysForObject:peerConnection]; 348 | if ([keys count] > 0) { 349 | [self.delegate webRTC:self didSendICECandidate:candidate forPeerWithID:keys[0]]; 350 | } 351 | }); 352 | } 353 | 354 | - (void)peerConnection:(RTCPeerConnection *)peerConnection didOpenDataChannel:(RTCDataChannel *)dataChannel { 355 | dispatch_async(dispatch_get_main_queue(), ^{ 356 | NSLog(@"peerConnection didOpenDataChannel?"); 357 | }); 358 | } 359 | 360 | @end 361 | -------------------------------------------------------------------------------- /Pods/TLKWebRTC/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2014 Jon Hjelle 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Pods/TLKWebRTC/README.md: -------------------------------------------------------------------------------- 1 | # TLKWebRTC 2 | 3 | A helper for creating and managing WebRTC connections. 4 | 5 | Last tested with https://cocoapods.org/pods/libjingle_peerconnection v9297.2.0. 6 | -------------------------------------------------------------------------------- /ios-demo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 7F438559218F4EE8820B6C27 /* libPods-ios-demo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BFF7C121D12E442B8BA4FDEB /* libPods-ios-demo.a */; }; 11 | A64107D319B1241F00725AA0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A64107D219B1241F00725AA0 /* Foundation.framework */; }; 12 | A64107D519B1241F00725AA0 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A64107D419B1241F00725AA0 /* CoreGraphics.framework */; }; 13 | A64107D719B1241F00725AA0 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A64107D619B1241F00725AA0 /* UIKit.framework */; }; 14 | A64107DD19B1241F00725AA0 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A64107DB19B1241F00725AA0 /* InfoPlist.strings */; }; 15 | A64107DF19B1241F00725AA0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = A64107DE19B1241F00725AA0 /* main.m */; }; 16 | A64107E319B1241F00725AA0 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A64107E219B1241F00725AA0 /* AppDelegate.m */; }; 17 | A64107E619B1241F00725AA0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A64107E419B1241F00725AA0 /* Main.storyboard */; }; 18 | A64107E919B1241F00725AA0 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A64107E819B1241F00725AA0 /* ViewController.m */; }; 19 | A64107EB19B1241F00725AA0 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A64107EA19B1241F00725AA0 /* Images.xcassets */; }; 20 | A64107F219B1241F00725AA0 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A64107F119B1241F00725AA0 /* XCTest.framework */; }; 21 | A64107F319B1241F00725AA0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A64107D219B1241F00725AA0 /* Foundation.framework */; }; 22 | A64107F419B1241F00725AA0 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A64107D619B1241F00725AA0 /* UIKit.framework */; }; 23 | A64107FC19B1241F00725AA0 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A64107FA19B1241F00725AA0 /* InfoPlist.strings */; }; 24 | A64107FE19B1241F00725AA0 /* ios_demoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A64107FD19B1241F00725AA0 /* ios_demoTests.m */; }; 25 | /* End PBXBuildFile section */ 26 | 27 | /* Begin PBXContainerItemProxy section */ 28 | A64107F519B1241F00725AA0 /* PBXContainerItemProxy */ = { 29 | isa = PBXContainerItemProxy; 30 | containerPortal = A64107C719B1241F00725AA0 /* Project object */; 31 | proxyType = 1; 32 | remoteGlobalIDString = A64107CE19B1241F00725AA0; 33 | remoteInfo = "ios-demo"; 34 | }; 35 | /* End PBXContainerItemProxy section */ 36 | 37 | /* Begin PBXFileReference section */ 38 | 7F19ECF91B16025C00D4C69D /* libWebRTC.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libWebRTC.a; path = Pods/libjingle_peerconnection/libjingle_peerconnection/libWebRTC.a; sourceTree = ""; }; 39 | A64107CF19B1241F00725AA0 /* ios-demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ios-demo.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 40 | A64107D219B1241F00725AA0 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 41 | A64107D419B1241F00725AA0 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 42 | A64107D619B1241F00725AA0 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 43 | A64107DA19B1241F00725AA0 /* ios-demo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ios-demo-Info.plist"; sourceTree = ""; }; 44 | A64107DC19B1241F00725AA0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 45 | A64107DE19B1241F00725AA0 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 46 | A64107E019B1241F00725AA0 /* ios-demo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ios-demo-Prefix.pch"; sourceTree = ""; }; 47 | A64107E119B1241F00725AA0 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 48 | A64107E219B1241F00725AA0 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 49 | A64107E519B1241F00725AA0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 50 | A64107E719B1241F00725AA0 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 51 | A64107E819B1241F00725AA0 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 52 | A64107EA19B1241F00725AA0 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 53 | A64107F019B1241F00725AA0 /* ios-demoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ios-demoTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 54 | A64107F119B1241F00725AA0 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 55 | A64107F919B1241F00725AA0 /* ios-demoTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ios-demoTests-Info.plist"; sourceTree = ""; }; 56 | A64107FB19B1241F00725AA0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 57 | A64107FD19B1241F00725AA0 /* ios_demoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ios_demoTests.m; sourceTree = ""; }; 58 | BFF7C121D12E442B8BA4FDEB /* libPods-ios-demo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ios-demo.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 59 | D71C4F837B6C38F625B89397 /* Pods-ios-demo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios-demo.release.xcconfig"; path = "Pods/Target Support Files/Pods-ios-demo/Pods-ios-demo.release.xcconfig"; sourceTree = ""; }; 60 | E1FAF0C6D825B902631032A5 /* Pods-ios-demo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios-demo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ios-demo/Pods-ios-demo.debug.xcconfig"; sourceTree = ""; }; 61 | /* End PBXFileReference section */ 62 | 63 | /* Begin PBXFrameworksBuildPhase section */ 64 | A64107CC19B1241F00725AA0 /* Frameworks */ = { 65 | isa = PBXFrameworksBuildPhase; 66 | buildActionMask = 2147483647; 67 | files = ( 68 | A64107D519B1241F00725AA0 /* CoreGraphics.framework in Frameworks */, 69 | A64107D719B1241F00725AA0 /* UIKit.framework in Frameworks */, 70 | A64107D319B1241F00725AA0 /* Foundation.framework in Frameworks */, 71 | 7F438559218F4EE8820B6C27 /* libPods-ios-demo.a in Frameworks */, 72 | ); 73 | runOnlyForDeploymentPostprocessing = 0; 74 | }; 75 | A64107ED19B1241F00725AA0 /* Frameworks */ = { 76 | isa = PBXFrameworksBuildPhase; 77 | buildActionMask = 2147483647; 78 | files = ( 79 | A64107F219B1241F00725AA0 /* XCTest.framework in Frameworks */, 80 | A64107F419B1241F00725AA0 /* UIKit.framework in Frameworks */, 81 | A64107F319B1241F00725AA0 /* Foundation.framework in Frameworks */, 82 | ); 83 | runOnlyForDeploymentPostprocessing = 0; 84 | }; 85 | /* End PBXFrameworksBuildPhase section */ 86 | 87 | /* Begin PBXGroup section */ 88 | 518A64E66FFDFE4E91077D16 /* Pods */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | E1FAF0C6D825B902631032A5 /* Pods-ios-demo.debug.xcconfig */, 92 | D71C4F837B6C38F625B89397 /* Pods-ios-demo.release.xcconfig */, 93 | ); 94 | name = Pods; 95 | sourceTree = ""; 96 | }; 97 | A64107C619B1241F00725AA0 = { 98 | isa = PBXGroup; 99 | children = ( 100 | A64107D819B1241F00725AA0 /* ios-demo */, 101 | A64107F719B1241F00725AA0 /* ios-demoTests */, 102 | A64107D119B1241F00725AA0 /* Frameworks */, 103 | A64107D019B1241F00725AA0 /* Products */, 104 | 518A64E66FFDFE4E91077D16 /* Pods */, 105 | ); 106 | sourceTree = ""; 107 | }; 108 | A64107D019B1241F00725AA0 /* Products */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | A64107CF19B1241F00725AA0 /* ios-demo.app */, 112 | A64107F019B1241F00725AA0 /* ios-demoTests.xctest */, 113 | ); 114 | name = Products; 115 | sourceTree = ""; 116 | }; 117 | A64107D119B1241F00725AA0 /* Frameworks */ = { 118 | isa = PBXGroup; 119 | children = ( 120 | 7F19ECF91B16025C00D4C69D /* libWebRTC.a */, 121 | A64107D219B1241F00725AA0 /* Foundation.framework */, 122 | A64107D419B1241F00725AA0 /* CoreGraphics.framework */, 123 | A64107D619B1241F00725AA0 /* UIKit.framework */, 124 | A64107F119B1241F00725AA0 /* XCTest.framework */, 125 | BFF7C121D12E442B8BA4FDEB /* libPods-ios-demo.a */, 126 | ); 127 | name = Frameworks; 128 | sourceTree = ""; 129 | }; 130 | A64107D819B1241F00725AA0 /* ios-demo */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | A64107E119B1241F00725AA0 /* AppDelegate.h */, 134 | A64107E219B1241F00725AA0 /* AppDelegate.m */, 135 | A64107E419B1241F00725AA0 /* Main.storyboard */, 136 | A64107E719B1241F00725AA0 /* ViewController.h */, 137 | A64107E819B1241F00725AA0 /* ViewController.m */, 138 | A64107EA19B1241F00725AA0 /* Images.xcassets */, 139 | A64107D919B1241F00725AA0 /* Supporting Files */, 140 | ); 141 | path = "ios-demo"; 142 | sourceTree = ""; 143 | }; 144 | A64107D919B1241F00725AA0 /* Supporting Files */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | A64107DA19B1241F00725AA0 /* ios-demo-Info.plist */, 148 | A64107DB19B1241F00725AA0 /* InfoPlist.strings */, 149 | A64107DE19B1241F00725AA0 /* main.m */, 150 | A64107E019B1241F00725AA0 /* ios-demo-Prefix.pch */, 151 | ); 152 | name = "Supporting Files"; 153 | sourceTree = ""; 154 | }; 155 | A64107F719B1241F00725AA0 /* ios-demoTests */ = { 156 | isa = PBXGroup; 157 | children = ( 158 | A64107FD19B1241F00725AA0 /* ios_demoTests.m */, 159 | A64107F819B1241F00725AA0 /* Supporting Files */, 160 | ); 161 | path = "ios-demoTests"; 162 | sourceTree = ""; 163 | }; 164 | A64107F819B1241F00725AA0 /* Supporting Files */ = { 165 | isa = PBXGroup; 166 | children = ( 167 | A64107F919B1241F00725AA0 /* ios-demoTests-Info.plist */, 168 | A64107FA19B1241F00725AA0 /* InfoPlist.strings */, 169 | ); 170 | name = "Supporting Files"; 171 | sourceTree = ""; 172 | }; 173 | /* End PBXGroup section */ 174 | 175 | /* Begin PBXNativeTarget section */ 176 | A64107CE19B1241F00725AA0 /* ios-demo */ = { 177 | isa = PBXNativeTarget; 178 | buildConfigurationList = A641080119B1241F00725AA0 /* Build configuration list for PBXNativeTarget "ios-demo" */; 179 | buildPhases = ( 180 | E05E3A9CF55D41138D88552F /* Check Pods Manifest.lock */, 181 | A64107CB19B1241F00725AA0 /* Sources */, 182 | A64107CC19B1241F00725AA0 /* Frameworks */, 183 | A64107CD19B1241F00725AA0 /* Resources */, 184 | 04AEFA5B88914E20B7B165B1 /* Copy Pods Resources */, 185 | 1C88C46B9E8DFAA887F79ED3 /* Embed Pods Frameworks */, 186 | ); 187 | buildRules = ( 188 | ); 189 | dependencies = ( 190 | ); 191 | name = "ios-demo"; 192 | productName = "ios-demo"; 193 | productReference = A64107CF19B1241F00725AA0 /* ios-demo.app */; 194 | productType = "com.apple.product-type.application"; 195 | }; 196 | A64107EF19B1241F00725AA0 /* ios-demoTests */ = { 197 | isa = PBXNativeTarget; 198 | buildConfigurationList = A641080419B1241F00725AA0 /* Build configuration list for PBXNativeTarget "ios-demoTests" */; 199 | buildPhases = ( 200 | A64107EC19B1241F00725AA0 /* Sources */, 201 | A64107ED19B1241F00725AA0 /* Frameworks */, 202 | A64107EE19B1241F00725AA0 /* Resources */, 203 | ); 204 | buildRules = ( 205 | ); 206 | dependencies = ( 207 | A64107F619B1241F00725AA0 /* PBXTargetDependency */, 208 | ); 209 | name = "ios-demoTests"; 210 | productName = "ios-demoTests"; 211 | productReference = A64107F019B1241F00725AA0 /* ios-demoTests.xctest */; 212 | productType = "com.apple.product-type.bundle.unit-test"; 213 | }; 214 | /* End PBXNativeTarget section */ 215 | 216 | /* Begin PBXProject section */ 217 | A64107C719B1241F00725AA0 /* Project object */ = { 218 | isa = PBXProject; 219 | attributes = { 220 | LastUpgradeCheck = 0510; 221 | ORGANIZATIONNAME = OTalk; 222 | TargetAttributes = { 223 | A64107EF19B1241F00725AA0 = { 224 | TestTargetID = A64107CE19B1241F00725AA0; 225 | }; 226 | }; 227 | }; 228 | buildConfigurationList = A64107CA19B1241F00725AA0 /* Build configuration list for PBXProject "ios-demo" */; 229 | compatibilityVersion = "Xcode 3.2"; 230 | developmentRegion = English; 231 | hasScannedForEncodings = 0; 232 | knownRegions = ( 233 | en, 234 | Base, 235 | ); 236 | mainGroup = A64107C619B1241F00725AA0; 237 | productRefGroup = A64107D019B1241F00725AA0 /* Products */; 238 | projectDirPath = ""; 239 | projectRoot = ""; 240 | targets = ( 241 | A64107CE19B1241F00725AA0 /* ios-demo */, 242 | A64107EF19B1241F00725AA0 /* ios-demoTests */, 243 | ); 244 | }; 245 | /* End PBXProject section */ 246 | 247 | /* Begin PBXResourcesBuildPhase section */ 248 | A64107CD19B1241F00725AA0 /* Resources */ = { 249 | isa = PBXResourcesBuildPhase; 250 | buildActionMask = 2147483647; 251 | files = ( 252 | A64107EB19B1241F00725AA0 /* Images.xcassets in Resources */, 253 | A64107DD19B1241F00725AA0 /* InfoPlist.strings in Resources */, 254 | A64107E619B1241F00725AA0 /* Main.storyboard in Resources */, 255 | ); 256 | runOnlyForDeploymentPostprocessing = 0; 257 | }; 258 | A64107EE19B1241F00725AA0 /* Resources */ = { 259 | isa = PBXResourcesBuildPhase; 260 | buildActionMask = 2147483647; 261 | files = ( 262 | A64107FC19B1241F00725AA0 /* InfoPlist.strings in Resources */, 263 | ); 264 | runOnlyForDeploymentPostprocessing = 0; 265 | }; 266 | /* End PBXResourcesBuildPhase section */ 267 | 268 | /* Begin PBXShellScriptBuildPhase section */ 269 | 04AEFA5B88914E20B7B165B1 /* Copy Pods Resources */ = { 270 | isa = PBXShellScriptBuildPhase; 271 | buildActionMask = 2147483647; 272 | files = ( 273 | ); 274 | inputPaths = ( 275 | ); 276 | name = "Copy Pods Resources"; 277 | outputPaths = ( 278 | ); 279 | runOnlyForDeploymentPostprocessing = 0; 280 | shellPath = /bin/sh; 281 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ios-demo/Pods-ios-demo-resources.sh\"\n"; 282 | showEnvVarsInLog = 0; 283 | }; 284 | 1C88C46B9E8DFAA887F79ED3 /* Embed Pods Frameworks */ = { 285 | isa = PBXShellScriptBuildPhase; 286 | buildActionMask = 2147483647; 287 | files = ( 288 | ); 289 | inputPaths = ( 290 | ); 291 | name = "Embed Pods Frameworks"; 292 | outputPaths = ( 293 | ); 294 | runOnlyForDeploymentPostprocessing = 0; 295 | shellPath = /bin/sh; 296 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ios-demo/Pods-ios-demo-frameworks.sh\"\n"; 297 | showEnvVarsInLog = 0; 298 | }; 299 | E05E3A9CF55D41138D88552F /* Check Pods Manifest.lock */ = { 300 | isa = PBXShellScriptBuildPhase; 301 | buildActionMask = 2147483647; 302 | files = ( 303 | ); 304 | inputPaths = ( 305 | ); 306 | name = "Check Pods Manifest.lock"; 307 | outputPaths = ( 308 | ); 309 | runOnlyForDeploymentPostprocessing = 0; 310 | shellPath = /bin/sh; 311 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 312 | showEnvVarsInLog = 0; 313 | }; 314 | /* End PBXShellScriptBuildPhase section */ 315 | 316 | /* Begin PBXSourcesBuildPhase section */ 317 | A64107CB19B1241F00725AA0 /* Sources */ = { 318 | isa = PBXSourcesBuildPhase; 319 | buildActionMask = 2147483647; 320 | files = ( 321 | A64107E919B1241F00725AA0 /* ViewController.m in Sources */, 322 | A64107E319B1241F00725AA0 /* AppDelegate.m in Sources */, 323 | A64107DF19B1241F00725AA0 /* main.m in Sources */, 324 | ); 325 | runOnlyForDeploymentPostprocessing = 0; 326 | }; 327 | A64107EC19B1241F00725AA0 /* Sources */ = { 328 | isa = PBXSourcesBuildPhase; 329 | buildActionMask = 2147483647; 330 | files = ( 331 | A64107FE19B1241F00725AA0 /* ios_demoTests.m in Sources */, 332 | ); 333 | runOnlyForDeploymentPostprocessing = 0; 334 | }; 335 | /* End PBXSourcesBuildPhase section */ 336 | 337 | /* Begin PBXTargetDependency section */ 338 | A64107F619B1241F00725AA0 /* PBXTargetDependency */ = { 339 | isa = PBXTargetDependency; 340 | target = A64107CE19B1241F00725AA0 /* ios-demo */; 341 | targetProxy = A64107F519B1241F00725AA0 /* PBXContainerItemProxy */; 342 | }; 343 | /* End PBXTargetDependency section */ 344 | 345 | /* Begin PBXVariantGroup section */ 346 | A64107DB19B1241F00725AA0 /* InfoPlist.strings */ = { 347 | isa = PBXVariantGroup; 348 | children = ( 349 | A64107DC19B1241F00725AA0 /* en */, 350 | ); 351 | name = InfoPlist.strings; 352 | sourceTree = ""; 353 | }; 354 | A64107E419B1241F00725AA0 /* Main.storyboard */ = { 355 | isa = PBXVariantGroup; 356 | children = ( 357 | A64107E519B1241F00725AA0 /* Base */, 358 | ); 359 | name = Main.storyboard; 360 | sourceTree = ""; 361 | }; 362 | A64107FA19B1241F00725AA0 /* InfoPlist.strings */ = { 363 | isa = PBXVariantGroup; 364 | children = ( 365 | A64107FB19B1241F00725AA0 /* en */, 366 | ); 367 | name = InfoPlist.strings; 368 | sourceTree = ""; 369 | }; 370 | /* End PBXVariantGroup section */ 371 | 372 | /* Begin XCBuildConfiguration section */ 373 | A64107FF19B1241F00725AA0 /* Debug */ = { 374 | isa = XCBuildConfiguration; 375 | buildSettings = { 376 | ALWAYS_SEARCH_USER_PATHS = NO; 377 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 378 | CLANG_CXX_LIBRARY = "libc++"; 379 | CLANG_ENABLE_MODULES = YES; 380 | CLANG_ENABLE_OBJC_ARC = YES; 381 | CLANG_WARN_BOOL_CONVERSION = YES; 382 | CLANG_WARN_CONSTANT_CONVERSION = YES; 383 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 384 | CLANG_WARN_EMPTY_BODY = YES; 385 | CLANG_WARN_ENUM_CONVERSION = YES; 386 | CLANG_WARN_INT_CONVERSION = YES; 387 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 388 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 389 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 390 | COPY_PHASE_STRIP = NO; 391 | GCC_C_LANGUAGE_STANDARD = gnu99; 392 | GCC_DYNAMIC_NO_PIC = NO; 393 | GCC_OPTIMIZATION_LEVEL = 0; 394 | GCC_PREPROCESSOR_DEFINITIONS = ( 395 | "DEBUG=1", 396 | "$(inherited)", 397 | ); 398 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 399 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 400 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 401 | GCC_WARN_UNDECLARED_SELECTOR = YES; 402 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 403 | GCC_WARN_UNUSED_FUNCTION = YES; 404 | GCC_WARN_UNUSED_VARIABLE = YES; 405 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 406 | ONLY_ACTIVE_ARCH = YES; 407 | SDKROOT = iphoneos; 408 | }; 409 | name = Debug; 410 | }; 411 | A641080019B1241F00725AA0 /* Release */ = { 412 | isa = XCBuildConfiguration; 413 | buildSettings = { 414 | ALWAYS_SEARCH_USER_PATHS = NO; 415 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 416 | CLANG_CXX_LIBRARY = "libc++"; 417 | CLANG_ENABLE_MODULES = YES; 418 | CLANG_ENABLE_OBJC_ARC = YES; 419 | CLANG_WARN_BOOL_CONVERSION = YES; 420 | CLANG_WARN_CONSTANT_CONVERSION = YES; 421 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 422 | CLANG_WARN_EMPTY_BODY = YES; 423 | CLANG_WARN_ENUM_CONVERSION = YES; 424 | CLANG_WARN_INT_CONVERSION = YES; 425 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 426 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 427 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 428 | COPY_PHASE_STRIP = YES; 429 | ENABLE_NS_ASSERTIONS = NO; 430 | GCC_C_LANGUAGE_STANDARD = gnu99; 431 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 432 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 433 | GCC_WARN_UNDECLARED_SELECTOR = YES; 434 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 435 | GCC_WARN_UNUSED_FUNCTION = YES; 436 | GCC_WARN_UNUSED_VARIABLE = YES; 437 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 438 | SDKROOT = iphoneos; 439 | VALIDATE_PRODUCT = YES; 440 | }; 441 | name = Release; 442 | }; 443 | A641080219B1241F00725AA0 /* Debug */ = { 444 | isa = XCBuildConfiguration; 445 | baseConfigurationReference = E1FAF0C6D825B902631032A5 /* Pods-ios-demo.debug.xcconfig */; 446 | buildSettings = { 447 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 448 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 449 | CODE_SIGN_IDENTITY = "iPhone Developer"; 450 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 451 | ENABLE_BITCODE = NO; 452 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 453 | GCC_PREFIX_HEADER = "ios-demo/ios-demo-Prefix.pch"; 454 | INFOPLIST_FILE = "ios-demo/ios-demo-Info.plist"; 455 | LIBRARY_SEARCH_PATHS = ( 456 | "$(inherited)", 457 | "$(PROJECT_DIR)/Pods/libjingle_peerconnection/libjingle_peerconnection", 458 | ); 459 | PRODUCT_NAME = "$(TARGET_NAME)"; 460 | PROVISIONING_PROFILE = ""; 461 | WRAPPER_EXTENSION = app; 462 | }; 463 | name = Debug; 464 | }; 465 | A641080319B1241F00725AA0 /* Release */ = { 466 | isa = XCBuildConfiguration; 467 | baseConfigurationReference = D71C4F837B6C38F625B89397 /* Pods-ios-demo.release.xcconfig */; 468 | buildSettings = { 469 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 470 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 471 | CODE_SIGN_IDENTITY = "iPhone Developer"; 472 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 473 | ENABLE_BITCODE = NO; 474 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 475 | GCC_PREFIX_HEADER = "ios-demo/ios-demo-Prefix.pch"; 476 | INFOPLIST_FILE = "ios-demo/ios-demo-Info.plist"; 477 | LIBRARY_SEARCH_PATHS = ( 478 | "$(inherited)", 479 | "$(PROJECT_DIR)/Pods/libjingle_peerconnection/libjingle_peerconnection", 480 | ); 481 | PRODUCT_NAME = "$(TARGET_NAME)"; 482 | PROVISIONING_PROFILE = ""; 483 | WRAPPER_EXTENSION = app; 484 | }; 485 | name = Release; 486 | }; 487 | A641080519B1241F00725AA0 /* Debug */ = { 488 | isa = XCBuildConfiguration; 489 | buildSettings = { 490 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/ios-demo.app/ios-demo"; 491 | FRAMEWORK_SEARCH_PATHS = ( 492 | "$(SDKROOT)/Developer/Library/Frameworks", 493 | "$(inherited)", 494 | "$(DEVELOPER_FRAMEWORKS_DIR)", 495 | ); 496 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 497 | GCC_PREFIX_HEADER = "ios-demo/ios-demo-Prefix.pch"; 498 | GCC_PREPROCESSOR_DEFINITIONS = ( 499 | "DEBUG=1", 500 | "$(inherited)", 501 | ); 502 | INFOPLIST_FILE = "ios-demoTests/ios-demoTests-Info.plist"; 503 | PRODUCT_NAME = "$(TARGET_NAME)"; 504 | TEST_HOST = "$(BUNDLE_LOADER)"; 505 | WRAPPER_EXTENSION = xctest; 506 | }; 507 | name = Debug; 508 | }; 509 | A641080619B1241F00725AA0 /* Release */ = { 510 | isa = XCBuildConfiguration; 511 | buildSettings = { 512 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/ios-demo.app/ios-demo"; 513 | FRAMEWORK_SEARCH_PATHS = ( 514 | "$(SDKROOT)/Developer/Library/Frameworks", 515 | "$(inherited)", 516 | "$(DEVELOPER_FRAMEWORKS_DIR)", 517 | ); 518 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 519 | GCC_PREFIX_HEADER = "ios-demo/ios-demo-Prefix.pch"; 520 | INFOPLIST_FILE = "ios-demoTests/ios-demoTests-Info.plist"; 521 | PRODUCT_NAME = "$(TARGET_NAME)"; 522 | TEST_HOST = "$(BUNDLE_LOADER)"; 523 | WRAPPER_EXTENSION = xctest; 524 | }; 525 | name = Release; 526 | }; 527 | /* End XCBuildConfiguration section */ 528 | 529 | /* Begin XCConfigurationList section */ 530 | A64107CA19B1241F00725AA0 /* Build configuration list for PBXProject "ios-demo" */ = { 531 | isa = XCConfigurationList; 532 | buildConfigurations = ( 533 | A64107FF19B1241F00725AA0 /* Debug */, 534 | A641080019B1241F00725AA0 /* Release */, 535 | ); 536 | defaultConfigurationIsVisible = 0; 537 | defaultConfigurationName = Release; 538 | }; 539 | A641080119B1241F00725AA0 /* Build configuration list for PBXNativeTarget "ios-demo" */ = { 540 | isa = XCConfigurationList; 541 | buildConfigurations = ( 542 | A641080219B1241F00725AA0 /* Debug */, 543 | A641080319B1241F00725AA0 /* Release */, 544 | ); 545 | defaultConfigurationIsVisible = 0; 546 | defaultConfigurationName = Release; 547 | }; 548 | A641080419B1241F00725AA0 /* Build configuration list for PBXNativeTarget "ios-demoTests" */ = { 549 | isa = XCConfigurationList; 550 | buildConfigurations = ( 551 | A641080519B1241F00725AA0 /* Debug */, 552 | A641080619B1241F00725AA0 /* Release */, 553 | ); 554 | defaultConfigurationIsVisible = 0; 555 | defaultConfigurationName = Release; 556 | }; 557 | /* End XCConfigurationList section */ 558 | }; 559 | rootObject = A64107C719B1241F00725AA0 /* Project object */; 560 | } 561 | -------------------------------------------------------------------------------- /ios-demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios-demo.xcodeproj/xcuserdata/nigel.xcuserdatad/xcschemes/ios-demo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 61 | 62 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /ios-demo.xcodeproj/xcuserdata/nigel.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ios-demo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | A64107CE19B1241F00725AA0 16 | 17 | primary 18 | 19 | 20 | A64107EF19B1241F00725AA0 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /ios-demo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ios-demo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // Copyright (c) 2014 &yet, LLC and otalk contributors 4 | // 5 | 6 | #import 7 | 8 | @interface AppDelegate : UIResponder 9 | 10 | @property (strong, nonatomic) UIWindow *window; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /ios-demo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // Copyright (c) 2014 &yet, LLC and otalk contributors 4 | // 5 | 6 | #import "AppDelegate.h" 7 | 8 | @implementation AppDelegate 9 | 10 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 11 | { 12 | // Override point for customization after application launch. 13 | return YES; 14 | } 15 | 16 | - (void)applicationWillResignActive:(UIApplication *)application 17 | { 18 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 19 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 20 | } 21 | 22 | - (void)applicationDidEnterBackground:(UIApplication *)application 23 | { 24 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 25 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 26 | } 27 | 28 | - (void)applicationWillEnterForeground:(UIApplication *)application 29 | { 30 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 31 | } 32 | 33 | - (void)applicationDidBecomeActive:(UIApplication *)application 34 | { 35 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 36 | } 37 | 38 | - (void)applicationWillTerminate:(UIApplication *)application 39 | { 40 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /ios-demo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /ios-demo/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /ios-demo/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /ios-demo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // Copyright (c) 2014 &yet, LLC and otalk contributors 4 | // 5 | 6 | #import 7 | 8 | @interface ViewController : UIViewController 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /ios-demo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // Copyright (c) 2014 &yet, LLC and otalk contributors 4 | // 5 | 6 | #import "ViewController.h" 7 | #import "TLKSocketIOSignaling.h" 8 | #import "TLKMediaStream.h" 9 | #import "RTCMediaStream.h" 10 | #import "RTCEAGLVideoView.h" 11 | #import "RTCVideoTrack.h" 12 | #import "RTCAVFoundationVideoSource.h" 13 | 14 | @interface ViewController () 15 | 16 | @property (strong, nonatomic) TLKSocketIOSignaling* signaling; 17 | @property (strong, nonatomic) IBOutlet RTCEAGLVideoView *remoteView; 18 | @property (strong, nonatomic) IBOutlet UIView *localView; 19 | @property (strong, nonatomic) RTCVideoTrack *localVideoTrack; 20 | @property (strong, nonatomic) RTCVideoTrack *remoteVideoTrack; 21 | 22 | @property (strong, nonatomic) AVCaptureVideoPreviewLayer *previewLayer; 23 | 24 | @end 25 | 26 | @implementation ViewController 27 | 28 | - (void)viewDidLoad 29 | { 30 | [super viewDidLoad]; 31 | 32 | [[NSNotificationCenter defaultCenter] addObserver:self 33 | selector:@selector(captureSessionDidStartRunning) 34 | name:AVCaptureSessionDidStartRunningNotification 35 | object:nil]; 36 | 37 | //RTCEAGLVideoViewDelegate provides notifications on video frame dimensions 38 | [self.remoteView setDelegate:self]; 39 | 40 | self.signaling = [[TLKSocketIOSignaling alloc] initWithVideo:YES]; 41 | //TLKSocketIOSignalingDelegate provides signaling notifications 42 | self.signaling.delegate = self; 43 | [self.signaling connectToServer:@"signaling.simplewebrtc.com" port:80 secure:NO success:^{ 44 | [self.signaling joinRoom:@"ios-demo" success:^{ 45 | NSLog(@"join success"); 46 | } failure:^{ 47 | NSLog(@"join failure"); 48 | }]; 49 | NSLog(@"connect success"); 50 | } failure:^(NSError* error) { 51 | NSLog(@"connect failure"); 52 | }]; 53 | } 54 | 55 | - (void)captureSessionDidStartRunning { 56 | dispatch_async(dispatch_get_main_queue(), ^{ 57 | [self configureLocalPreview]; 58 | }); 59 | } 60 | 61 | - (void)configureLocalPreview { 62 | RTCVideoTrack *videoTrack = [self.signaling.localMediaStream.videoTracks firstObject]; 63 | // There is a chance that this video source is not an RTCAVFoundationVideoSource, but we know it should be from TLKWebRTC 64 | RTCAVFoundationVideoSource *videoSource = (RTCAVFoundationVideoSource*)videoTrack.source; 65 | AVCaptureSession *captureSession = [videoSource captureSession]; 66 | 67 | self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:captureSession]; 68 | self.previewLayer.frame = self.localView.bounds; 69 | 70 | [self.localView.layer addSublayer:self.previewLayer]; 71 | } 72 | 73 | #pragma mark - TLKSocketIOSignalingDelegate 74 | 75 | - (void)socketIOSignaling:(TLKSocketIOSignaling *)socketIOSignaling addedStream:(TLKMediaStream *)stream { 76 | NSLog(@"addedStream"); 77 | 78 | RTCVideoTrack *remoteVideoTrack = stream.stream.videoTracks[0]; 79 | 80 | if(self.remoteVideoTrack) { 81 | [self.remoteVideoTrack removeRenderer:self.remoteView]; 82 | self.remoteVideoTrack = nil; 83 | [self.remoteView renderFrame:nil]; 84 | } 85 | 86 | self.remoteVideoTrack = remoteVideoTrack; 87 | [self.remoteVideoTrack addRenderer:self.remoteView]; 88 | 89 | } 90 | 91 | -(void)serverRequiresPassword:(TLKSocketIOSignaling*)server{ 92 | NSLog(@"serverRequiresPassword"); 93 | } 94 | -(void)removedStream:(TLKMediaStream*)stream{ 95 | NSLog(@"removedStream"); 96 | } 97 | -(void)peer:(NSString*)peer toggledAudioMute:(BOOL)mute{ 98 | NSLog(@"toggledAudioMute"); 99 | } 100 | -(void)peer:(NSString*)peer toggledVideoMute:(BOOL)mute{ 101 | NSLog(@"toggledVideoMute"); 102 | } 103 | -(void)lockChange:(BOOL)locked{ 104 | NSLog(@"locked"); 105 | } 106 | 107 | 108 | #pragma mark - RTCEAGLVideoViewDelegate 109 | 110 | -(void)videoView:(RTCEAGLVideoView *)videoView didChangeVideoSize:(CGSize)size { 111 | NSLog(@"videoView ?"); 112 | } 113 | 114 | 115 | @end 116 | -------------------------------------------------------------------------------- /ios-demo/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /ios-demo/ios-demo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | org.otalk.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSExceptionDomains 30 | 31 | signaling.simplewebrtc.com 32 | 33 | NSExceptionAllowsInsecureHTTPLoads 34 | 35 | 36 | 37 | 38 | UIMainStoryboardFile 39 | Main 40 | UIRequiredDeviceCapabilities 41 | 42 | armv7 43 | 44 | UISupportedInterfaceOrientations 45 | 46 | UIInterfaceOrientationPortrait 47 | UIInterfaceOrientationLandscapeLeft 48 | UIInterfaceOrientationLandscapeRight 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /ios-demo/ios-demo-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /ios-demo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ios-demo 4 | // 5 | // Created by Nigel Brooke on 2014-08-29. 6 | // Copyright (c) 2014 OTalk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ios-demoTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /ios-demoTests/ios-demoTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | org.otalk.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /ios-demoTests/ios_demoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ios_demoTests.m 3 | // ios-demoTests 4 | // 5 | // Created by Nigel Brooke on 2014-08-29. 6 | // Copyright (c) 2014 OTalk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ios_demoTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation ios_demoTests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | --------------------------------------------------------------------------------