diff --git a/UnityAds/AdUnit/UADSViewController.m b/UnityAds/AdUnit/UADSViewController.m index d063efbf..25ef67cc 100644 --- a/UnityAds/AdUnit/UADSViewController.m +++ b/UnityAds/AdUnit/UADSViewController.m @@ -28,8 +28,6 @@ - (instancetype)initWithViews:(NSArray *)views supportedOrientations:(NSNumber * - (void)viewDidLoad { [super viewDidLoad]; [self.view setBackgroundColor:[UIColor blackColor]]; - - [self setViews:self.currentViews]; [[UADSWebViewApp getCurrentApp] sendEvent:NSStringFromAdUnitEvent(kUnityAdsViewControllerDidLoad) category:NSStringFromWebViewEventCategory(kUnityAdsWebViewEventCategoryAdunit) param1:nil]; } @@ -40,6 +38,12 @@ - (void)viewDidAppear:(BOOL)animated { [[UADSWebViewApp getCurrentApp] sendEvent:NSStringFromAdUnitEvent(kUnityAdsViewControllerDidAppear) category:NSStringFromWebViewEventCategory(kUnityAdsWebViewEventCategoryAdunit) param1:nil]; } +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + [self setViews:self.currentViews]; +} + - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; diff --git a/UnityAds/AppSheet/UADSAppSheet.m b/UnityAds/AppSheet/UADSAppSheet.m index 7027ddf9..3c461035 100644 --- a/UnityAds/AppSheet/UADSAppSheet.m +++ b/UnityAds/AppSheet/UADSAppSheet.m @@ -19,11 +19,12 @@ @interface UADSAppSheet () @implementation UADSAppSheet + (instancetype)instance { - static UADSAppSheet *sharedInstance = nil; + static UADSAppSheet *sharedInstance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedInstance = [[UADSAppSheet alloc] init]; }); + return sharedInstance; } @@ -46,10 +47,12 @@ - (void)prepareAppSheet:(NSDictionary *)parameters prepareTimeoutInSeconds:(int) block(true, nil); } else if(![self.appSheetLoading containsObject:iTunesId]) { [self.appSheetLoading addObject:iTunesId]; - SKStoreProductViewController *viewController = [[UADSAppSheetViewController alloc] init]; - [viewController setDelegate:self]; - [viewController setModalPresentationCapturesStatusBarAppearance:true]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + SKStoreProductViewController *viewController = [[UADSAppSheetViewController alloc] init]; + [viewController setDelegate:self]; + [viewController setModalPresentationCapturesStatusBarAppearance:true]; + __block BOOL finished = NO; __block BOOL cancelled = NO; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.prepareTimeoutInSeconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ @@ -91,11 +94,14 @@ - (void)presentAppSheet:(NSDictionary *)parameters animated:(BOOL)animated compl } self.presentingParameters = parameters; self.presentingAnimated = animated; - [[UADSApiAdUnit getAdUnit] presentViewController:cachedController animated:animated completion:^{ - if ([UADSWebViewApp getCurrentApp]) { - [[UADSWebViewApp getCurrentApp] sendEvent:NSStringFromAppSheetEvent(kAppSheetOpened) category:NSStringFromWebViewEventCategory(kUnityAdsWebViewEventCategoryAppSheet) param1:parameters, nil]; - } - }]; + dispatch_async(dispatch_get_main_queue(), ^{ + [[UADSApiAdUnit getAdUnit] presentViewController:cachedController animated:animated completion:^{ + if ([UADSWebViewApp getCurrentApp]) { + [[UADSWebViewApp getCurrentApp] sendEvent:NSStringFromAppSheetEvent(kAppSheetOpened) category:NSStringFromWebViewEventCategory(kUnityAdsWebViewEventCategoryAppSheet) param1:parameters, nil]; + } + }]; + }); + block(true, nil); } else { block(false, NSStringFromAppSheetError(kUnityAdsAppSheetErrorNotFound)); diff --git a/UnityAds/Configuration/UADSConfiguration.m b/UnityAds/Configuration/UADSConfiguration.m index 4a5b6b5e..84856ae3 100644 --- a/UnityAds/Configuration/UADSConfiguration.m +++ b/UnityAds/Configuration/UADSConfiguration.m @@ -28,6 +28,7 @@ - (void)makeRequest { NSString *urlString = [NSString stringWithFormat:@"%@%@", [self configUrl], [self buildQueryString]]; UADSLogDebug(@"Requesting configuration with: %@", urlString); + [self setError:nil]; NSError *error; UADSWebRequest *request = [[UADSWebRequest alloc] initWithUrl:urlString requestType:@"GET" headers:NULL connectTimeout:30000]; NSData *responseData = [request makeRequest]; diff --git a/UnityAds/Configuration/UADSInitialize.h b/UnityAds/Configuration/UADSInitialize.h index 5c38675c..56fd1a9f 100644 --- a/UnityAds/Configuration/UADSInitialize.h +++ b/UnityAds/Configuration/UADSInitialize.h @@ -14,7 +14,6 @@ @interface UADSInitializeState : NSOperation @property (nonatomic, assign) UADSConfiguration *configuration; -@property (nonatomic, assign) NSOperationQueue *queue; - (instancetype)execute; - (instancetype)initWithConfiguration:(UADSConfiguration *)configuration; @@ -61,7 +60,7 @@ @interface UADSInitializeStateCreate : UADSInitializeState -@property (atomic, retain) NSString *webViewData; +@property (atomic, strong) NSString *webViewData; - (instancetype)initWithConfiguration:(UADSConfiguration *)configuration webViewData:(NSString *)webViewData; diff --git a/UnityAds/Configuration/UADSInitialize.m b/UnityAds/Configuration/UADSInitialize.m index a231baaf..29ebcbb8 100644 --- a/UnityAds/Configuration/UADSInitialize.m +++ b/UnityAds/Configuration/UADSInitialize.m @@ -7,6 +7,7 @@ #import "UADSWebRequestQueue.h" #import "UADSCacheQueue.h" #import "UADSPlacement.h" +#import "UADSNotificationObserver.h" #import "NSString+Hash.h" @implementation UADSInitialize @@ -26,7 +27,6 @@ + (void)initialize:(UADSConfiguration *)configuration { if (initializeQueue && initializeQueue.operationCount == 0) { currentConfiguration = configuration; id state = [[UADSInitializeStateReset alloc] initWithConfiguration:currentConfiguration]; - [state setQueue:initializeQueue]; [initializeQueue addOperation:state]; } } @@ -41,8 +41,8 @@ @implementation UADSInitializeState - (void)main { id nextState = [self execute]; - if (nextState && self.queue) { - [self.queue addOperation:nextState]; + if (nextState && initializeQueue) { + [initializeQueue addOperation:nextState]; } } @@ -103,11 +103,14 @@ - (instancetype)execute { [UADSSdkProperties setInitialized:false]; [UADSPlacement reset]; [UADSCacheQueue cancelAllDownloads]; - [UADSConnectivityMonitor stopAll]; + [UADSWebRequestQueue cancelAllOperations]; + dispatch_async(dispatch_get_main_queue(), ^{ + [UADSConnectivityMonitor stopAll]; + }); [UADSStorageManager init]; + [UADSNotificationObserver unregisterNotificationObserver]; id nextState = [[UADSInitializeStateConfig alloc] initWithConfiguration:self.configuration retries:0]; - [nextState setQueue:self.queue]; return nextState; } @@ -137,20 +140,17 @@ - (instancetype)execute { if (!self.configuration.error) { id nextState = [[UADSInitializeStateLoadCache alloc] initWithConfiguration:self.configuration]; - [nextState setQueue:self.queue]; return nextState; } else if (self.configuration.error && self.retries < self.maxRetries) { self.retries++; id retryState = [[UADSInitializeStateConfig alloc] initWithConfiguration:self.configuration retries:self.retries]; id nextState = [[UADSInitializeStateRetry alloc] initWithConfiguration:self.configuration retryState:retryState retryDelay:self.retryDelay]; - [nextState setQueue:self.queue]; return nextState; } else { id erroredState = [[UADSInitializeStateConfig alloc] initWithConfiguration:self.configuration retries:self.retries]; id nextState = [[UADSInitializeStateNetworkError alloc] initWithConfiguration:self.configuration erroredState:erroredState]; - [nextState setQueue:self.queue]; return nextState; } } @@ -173,13 +173,11 @@ - (instancetype)execute { if (!localWebViewHash || (localWebViewHash && [localWebViewHash isEqualToString:self.configuration.webViewHash])) { UADSLogInfo(@"Unity Ads init: webapp loaded from local cache"); id nextState = [[UADSInitializeStateCreate alloc] initWithConfiguration:self.configuration webViewData:fileString]; - [nextState setQueue:self.queue]; return nextState; } } id nextState = [[UADSInitializeStateLoadWeb alloc] initWithConfiguration:self.configuration retries:0]; - [nextState setQueue:self.queue]; return nextState; } @@ -216,19 +214,16 @@ - (instancetype)execute { self.retries++; id retryState = [[UADSInitializeStateLoadWeb alloc] initWithConfiguration:self.configuration retries:self.retries]; id nextState = [[UADSInitializeStateRetry alloc] initWithConfiguration:self.configuration retryState:retryState retryDelay:self.retryDelay]; - [nextState setQueue:self.queue]; return nextState; } else if (webRequest.error) { id erroredState = [[UADSInitializeStateLoadWeb alloc] initWithConfiguration:self.configuration retries:self.retries]; id nextState = [[UADSInitializeStateNetworkError alloc] initWithConfiguration:self.configuration erroredState:erroredState]; - [nextState setQueue:self.queue]; return nextState; } NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; id nextState = [[UADSInitializeStateCreate alloc] initWithConfiguration:self.configuration webViewData:responseString]; - [nextState setQueue:self.queue]; return nextState; } @@ -246,7 +241,6 @@ - (instancetype)execute { [UADSWebViewApp create:self.configuration]; id nextState = [[UADSInitializeStateComplete alloc] initWithConfiguration:self.configuration]; - [nextState setQueue:self.queue]; return nextState; } @@ -313,19 +307,29 @@ - (void)disconnected { - (instancetype)execute { UADSLogError(@"Unity Ads init: network error, waiting for connection events"); - - [UADSConnectivityMonitor startListening:self]; - + self.blockCondition = [[NSCondition alloc] init]; [self.blockCondition lock]; + + dispatch_async(dispatch_get_main_queue(), ^{ + [UADSConnectivityMonitor startListening:self]; + }); + BOOL success = [self.blockCondition waitUntilDate:[[NSDate alloc] initWithTimeIntervalSinceNow:10000 * 60]]; if (success) { - [UADSConnectivityMonitor stopListening:self]; + dispatch_async(dispatch_get_main_queue(), ^{ + [UADSConnectivityMonitor stopListening:self]; + }); + + [self.blockCondition unlock]; return self.erroredState; } else { - [UADSConnectivityMonitor stopListening:self]; + dispatch_async(dispatch_get_main_queue(), ^{ + [UADSConnectivityMonitor stopListening:self]; + + }); } [self.blockCondition unlock]; diff --git a/UnityAds/Connectivity/UADSConnectivityMonitor.m b/UnityAds/Connectivity/UADSConnectivityMonitor.m index 67f32dec..e0ca4f38 100644 --- a/UnityAds/Connectivity/UADSConnectivityMonitor.m +++ b/UnityAds/Connectivity/UADSConnectivityMonitor.m @@ -125,7 +125,7 @@ + (void)sendToWebview:(SCNetworkReachabilityRef)reachabilityRef flags:(SCNetwork [webViewApp sendEvent: Connected category:NSStringFromWebViewEventCategory(kUnityAdsWebViewEventCategoryConnectivity) param1:[NSNumber numberWithBool:TRUE], [NSNumber numberWithInt:0], nil]; break; case ReachableViaWWAN: - [webViewApp sendEvent: Connected category:NSStringFromWebViewEventCategory(kUnityAdsWebViewEventCategoryConnectivity) param1:[NSNumber numberWithBool:FALSE], [UADSConnectivityUtils getNetworkType], nil]; + [webViewApp sendEvent: Connected category:NSStringFromWebViewEventCategory(kUnityAdsWebViewEventCategoryConnectivity) param1:[NSNumber numberWithBool:FALSE], [NSNumber numberWithInteger:[UADSConnectivityUtils getNetworkType]], nil]; break; default: break; diff --git a/UnityAds/Device/UADSStorage.h b/UnityAds/Device/UADSStorage.h index e6387d43..d6313010 100644 --- a/UnityAds/Device/UADSStorage.h +++ b/UnityAds/Device/UADSStorage.h @@ -9,7 +9,7 @@ typedef NS_ENUM(NSInteger, UnityAdsStorageType) { @property (nonatomic, assign) NSString *targetFileName; @property (nonatomic, assign) UnityAdsStorageType type; -@property (nonatomic, retain) NSMutableDictionary *storageContents; +@property (nonatomic, strong) NSMutableDictionary *storageContents; - (instancetype)initWithLocation:(NSString *)fileLocation type:(UnityAdsStorageType)type; - (BOOL)setValue:(id)value forKey:(NSString *)key; diff --git a/UnityAds/Properties/UADSSdkProperties.m b/UnityAds/Properties/UADSSdkProperties.m index 9e96518a..259bd751 100644 --- a/UnityAds/Properties/UADSSdkProperties.m +++ b/UnityAds/Properties/UADSSdkProperties.m @@ -3,7 +3,7 @@ NSString * const kUnityAdsCacheDirName = @"UnityAdsCache"; NSString * const kUnityAdsLocalCacheFilePrefix = @"UnityAdsCache-"; NSString * const kUnityAdsLocalStorageFilePrefix = @"UnityAdsStorage-"; -NSString * const kUnityAdsVersionName = @"2.0.0-beta2"; +NSString * const kUnityAdsVersionName = @"2.0.0-beta3"; NSString * const kUnityAdsFlavorDebug = @"debug"; NSString * const kUnityAdsFlavorRelease = @"release"; int const kUnityAdsVersionCode = 2000; @@ -101,7 +101,18 @@ + (NSString *)getLocalWebViewFile { + (NSString *)getCacheDirectory { if (cacheDirectory == NULL) { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); - cacheDirectory = [paths firstObject]; + + BOOL cacheLocationIsDirectory = YES; + if (paths.count != 0) { + [[NSFileManager defaultManager] fileExistsAtPath:[paths firstObject] isDirectory:&cacheLocationIsDirectory]; + } + + if (cacheLocationIsDirectory) { + cacheDirectory = [paths firstObject]; + } else { + cacheDirectory = NSTemporaryDirectory(); + } + } return cacheDirectory; diff --git a/UnityAds/Request/UADSResolve.h b/UnityAds/Request/UADSResolve.h index efafec3d..3211acab 100644 --- a/UnityAds/Request/UADSResolve.h +++ b/UnityAds/Request/UADSResolve.h @@ -7,8 +7,10 @@ @property (nonatomic, strong) NSCondition *blockCondition; @property (nonatomic, strong) NSString *error; @property (nonatomic, strong) NSString *errorMessage; +@property (nonatomic, assign) BOOL canceled; - (instancetype)initWithHostName:(NSString *)hostName; - (void)resolve; +- (void)cancel; @end \ No newline at end of file diff --git a/UnityAds/Request/UADSResolve.m b/UnityAds/Request/UADSResolve.m index 06c63307..c6c60749 100644 --- a/UnityAds/Request/UADSResolve.m +++ b/UnityAds/Request/UADSResolve.m @@ -10,6 +10,7 @@ - (instancetype)initWithHostName:(NSString *)hostName { if (self) { [self setHostName:hostName]; + [self setCanceled:false]; } return self; @@ -52,4 +53,9 @@ - (void)openBlock { [self.blockCondition unlock]; } +- (void)cancel { + [self setCanceled:true]; + [self openBlock]; +} + @end \ No newline at end of file diff --git a/UnityAds/Request/UADSResolveOperation.m b/UnityAds/Request/UADSResolveOperation.m index 2867e9a3..7e02beb7 100644 --- a/UnityAds/Request/UADSResolveOperation.m +++ b/UnityAds/Request/UADSResolveOperation.m @@ -14,11 +14,37 @@ - (instancetype)initWithHostName:(NSString *)hostName completeBlock:(UnityAdsRes } - (void)main { + [self startObserving]; [self.resolve resolve]; + [self stopObserving]; - if (self.completeBlock) { + if (self.completeBlock && self.resolve && !self.resolve.canceled) { self.completeBlock(self.resolve.hostName, self.resolve.address, self.resolve.error, self.resolve.errorMessage); } } +- (void)startObserving { + @try { + [self addObserver:self forKeyPath:@"isCancelled" options:NSKeyValueObservingOptionNew context:nil]; + } + @catch (id exception) { + } +} + +- (void)stopObserving { + @try { + [self removeObserver:self forKeyPath:@"isCancelled"]; + } + @catch (id exception) { + } +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { + if ([keyPath isEqualToString:@"isCancelled"]) { + if (self.resolve) { + [self.resolve cancel]; + } + } +} + @end \ No newline at end of file diff --git a/UnityAds/Request/UADSWebRequestOperation.m b/UnityAds/Request/UADSWebRequestOperation.m index 0fe92cb2..aef052d5 100644 --- a/UnityAds/Request/UADSWebRequestOperation.m +++ b/UnityAds/Request/UADSWebRequestOperation.m @@ -17,12 +17,40 @@ - (instancetype)initWithUrl:(NSString *)url requestType:(NSString *)requestType } - (void)main { + [self startObserving]; + NSData *data = [self.request makeRequest]; NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - - if (self.completeBlock) { + + [self stopObserving]; + + if (self.completeBlock && self.request && !self.request.canceled) { self.completeBlock(self.request.url, self.request.error, responseString, self.request.responseCode, self.request.responseHeaders); } } +- (void)startObserving { + @try { + [self addObserver:self forKeyPath:@"isCancelled" options:NSKeyValueObservingOptionNew context:nil]; + } + @catch (id exception) { + } +} + +- (void)stopObserving { + @try { + [self removeObserver:self forKeyPath:@"isCancelled"]; + } + @catch (id exception) { + } +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { + if ([keyPath isEqualToString:@"isCancelled"]) { + if (self.request && !self.request.finished) { + [self.request cancel]; + } + } +} + @end \ No newline at end of file diff --git a/UnityAds/Request/UADSWebRequestQueue.h b/UnityAds/Request/UADSWebRequestQueue.h index fb949652..12e27024 100644 --- a/UnityAds/Request/UADSWebRequestQueue.h +++ b/UnityAds/Request/UADSWebRequestQueue.h @@ -7,5 +7,6 @@ + (void)requestUrl:(NSString *)url type:(NSString *)type headers:(NSDictionary *)headers body:(NSString *)body completeBlock:(UnityAdsWebRequestCompletion)completeBlock connectTimeout:(int)connectTimeout; + (void)requestUrl:(NSString *)url type:(NSString *)type headers:(NSDictionary *)headers completeBlock:(UnityAdsWebRequestCompletion)completeBlock connectTimeout:(int)connectTimeout; + (BOOL)resolve:(NSString *)host completeBlock:(UnityAdsResolveRequestCompletion)completeBlock; ++ (void)cancelAllOperations; @end \ No newline at end of file diff --git a/UnityAds/Request/UADSWebRequestQueue.m b/UnityAds/Request/UADSWebRequestQueue.m index 0005bed8..3cf84db5 100644 --- a/UnityAds/Request/UADSWebRequestQueue.m +++ b/UnityAds/Request/UADSWebRequestQueue.m @@ -44,4 +44,13 @@ + (BOOL)resolve:(NSString *)host completeBlock:(UnityAdsResolveRequestCompletion return false; } ++ (void)cancelAllOperations { + if (requestQueue) { + [requestQueue cancelAllOperations]; + } + if (resolveQueue) { + [resolveQueue cancelAllOperations]; + } +} + @end \ No newline at end of file diff --git a/UnityAds/WebView/Bridge/UADSInvocation.h b/UnityAds/WebView/Bridge/UADSInvocation.h index ec0b83ae..16f1b168 100644 --- a/UnityAds/WebView/Bridge/UADSInvocation.h +++ b/UnityAds/WebView/Bridge/UADSInvocation.h @@ -2,8 +2,8 @@ @interface UADSInvocation : NSObject -@property (nonatomic, retain) NSMutableArray *invocations; -@property (nonatomic, retain) NSMutableArray *responses; +@property (nonatomic, strong) NSMutableArray *invocations; +@property (nonatomic, strong) NSMutableArray *responses; @property (nonatomic, assign) int invocationId; - (void)addInvocation:(NSString *)className methodName:(NSString *)methodName parameters:(NSArray *)parameters callback:(UADSWebViewCallback *)callback; diff --git a/UnityAdsTests/WebRequestTests.swift b/UnityAdsTests/WebRequestTests.swift index ba8f861b..78d503c6 100644 --- a/UnityAdsTests/WebRequestTests.swift +++ b/UnityAdsTests/WebRequestTests.swift @@ -49,4 +49,160 @@ class WebRequestTest: XCTestCase { XCTAssertEqual(request.url, url, "URL's should still be the same") XCTAssertNotNil(data, "Data should not be null") } + + func testEmptyGetUrl () { + let url = "" + let request:UADSWebRequest = UADSWebRequest.init(url: url, requestType: "GET", headers: nil, connectTimeout: 30000) + let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) + var data:NSData = NSData.init() + let expectation = self.expectationWithDescription("requestEndExpectation") + + dispatch_async(queue) { + data = request.makeRequest() + expectation.fulfill() + } + + self.waitForExpectationsWithTimeout(30) { + error in + XCTAssertTrue(true, "Did complete") + } + + XCTAssertNotNil(request.error, "Error should not be null") + let message:String = request.error.userInfo["message"] as! String; + XCTAssertTrue(message.containsString("unsupported URL"), "Error message should contain 'unsupported URL'"); + XCTAssertTrue(data.length == 0, "Data length should be zero"); + } + + func testEmptyPostUrl () { + let url = "" + let request:UADSWebRequest = UADSWebRequest.init(url: url, requestType: "POST", headers: nil, connectTimeout: 30000) + let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) + var data:NSData = NSData.init() + let expectation = self.expectationWithDescription("requestEndExpectation") + + dispatch_async(queue) { + data = request.makeRequest() + expectation.fulfill() + } + + self.waitForExpectationsWithTimeout(30) { + error in + XCTAssertTrue(true, "Did complete") + } + + XCTAssertNotNil(request.error, "Error should not be null") + let message:String = request.error.userInfo["message"] as! String; + XCTAssertTrue(message.containsString("unsupported URL"), "Error message should contain 'unsupported URL'"); + XCTAssertTrue(data.length == 0, "Data length should be zero"); + } + + func testNullGetUrl () { + let request:UADSWebRequest = UADSWebRequest.init(url: nil, requestType: "GET", headers: nil, connectTimeout: 30000) + let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) + var data:NSData = NSData.init() + let expectation = self.expectationWithDescription("requestEndExpectation") + + dispatch_async(queue) { + data = request.makeRequest() + expectation.fulfill() + } + + self.waitForExpectationsWithTimeout(30) { + error in + XCTAssertTrue(true, "Did complete") + } + + XCTAssertNotNil(request.error, "Error should not be null") + let message:String = request.error.userInfo["message"] as! String; + XCTAssertTrue(message.containsString("unsupported URL"), "Error message should contain 'unsupported URL'"); + XCTAssertTrue(data.length == 0, "Data length should be zero"); + } + + func testNullPostUrl () { + let request:UADSWebRequest = UADSWebRequest.init(url: nil, requestType: "POST", headers: nil, connectTimeout: 30000) + let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) + var data:NSData = NSData.init() + let expectation = self.expectationWithDescription("requestEndExpectation") + + dispatch_async(queue) { + data = request.makeRequest() + expectation.fulfill() + } + + self.waitForExpectationsWithTimeout(30) { + error in + XCTAssertTrue(true, "Did complete") + } + + XCTAssertNotNil(request.error, "Error should not be null") + let message:String = request.error.userInfo["message"] as! String; + XCTAssertTrue(message.containsString("unsupported URL"), "Error message should contain 'unsupported URL'"); + XCTAssertTrue(data.length == 0, "Data length should be zero"); + } + + func testInvalidGetUrl () { + let url = "https://gougle.fi/"; + let request:UADSWebRequest = UADSWebRequest.init(url: url, requestType: "GET", headers: nil, connectTimeout: 30000) + let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) + var data:NSData = NSData.init() + let expectation = self.expectationWithDescription("requestEndExpectation") + + dispatch_async(queue) { + data = request.makeRequest() + expectation.fulfill() + } + + self.waitForExpectationsWithTimeout(30) { + error in + XCTAssertTrue(true, "Did complete") + } + + XCTAssertNotNil(request.error, "Error should not be null") + let message:String = request.error.userInfo["message"] as! String; + XCTAssertTrue(message.containsString("A server with the specified hostname could not be found."), "Error message should contain 'A server with the specified hostname could not be found.'"); + XCTAssertTrue(data.length == 0, "Data length should be zero"); + } + + func testInvalidPostUrl () { + let url = "https://gougle.fi/"; + let request:UADSWebRequest = UADSWebRequest.init(url: url, requestType: "GET", headers: nil, connectTimeout: 30000) + let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) + var data:NSData = NSData.init() + let expectation = self.expectationWithDescription("requestEndExpectation") + + dispatch_async(queue) { + data = request.makeRequest() + expectation.fulfill() + } + + self.waitForExpectationsWithTimeout(30) { + error in + XCTAssertTrue(true, "Did complete") + } + + XCTAssertNotNil(request.error, "Error should not be null") + let message:String = request.error.userInfo["message"] as! String; + XCTAssertTrue(message.containsString("A server with the specified hostname could not be found."), "Error message should contain 'A server with the specified hostname could not be found.'"); + XCTAssertTrue(data.length == 0, "Data length should be zero"); + } + + func testResolveHost () { + let resolve:UADSResolve = UADSResolve.init(hostName: "google-public-dns-a.google.com"); + let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) + let expectation = self.expectationWithDescription("requestEndExpectation") + + dispatch_async(queue) { + resolve.resolve(); + expectation.fulfill() + } + + self.waitForExpectationsWithTimeout(30) { + error in + XCTAssertTrue(true, "Did complete") + } + + XCTAssertNil(resolve.error, "Error should be null"); + XCTAssertEqual("google-public-dns-a.google.com", resolve.hostName, "Hosname should still be the same"); + XCTAssertEqual("8.8.8.8", resolve.address, "Address should've resolved to 8.8.8.8"); + } } diff --git a/build-framework.sh b/build-framework.sh index 53ee82d3..efe623d9 100755 --- a/build-framework.sh +++ b/build-framework.sh @@ -1,4 +1,85 @@ +CONFIGURATION_TARGET_TYPE="Release" +BUILD_BOTH_TARGETS=true + +USAGE="$(basename $0) is program that compiles the iOS DEBUG or RELEASE frameworks +USAGE + ./build-framework Build both DEBUG and RELEASE versions of the framework + ./build-framework -c DEBUG Builds the DEBUG version of the framework + ./build-framework -c RELEASE Builds the RELEASE version of the framework +" + +while getopts hc: OPTIONS; do + case $OPTIONS in + h ) + echo "$USAGE" + exit ;; + c ) + echo "got options: $OPTARG" + + CONFIGURATION_TARGET_TYPE=$(echo "$OPTARG" | tr '[:upper:]' '[:lower:]') + CONFIGURATION_TARGET_TYPE="$(tr '[:lower:]' '[:upper:]' <<< ${CONFIGURATION_TARGET_TYPE:0:1})${CONFIGURATION_TARGET_TYPE:1}" + + if [ "$CONFIGURATION_TARGET_TYPE" != "Release" ] && [ "$CONFIGURATION_TARGET_TYPE" != "Debug" ]; then + echo "Invalid Target type defined '$CONFIGURATION_TARGET_TYPE'" + echo "$USAGE" + exit 1 + fi + echo "building $CONFIGURATION_TARGET_TYPE Framework" + BUILD_BOTH_TARGETS=false + ;; + * ) + echo "Invalid args passed" + echo + echo "$USAGE" + exit ;; + esac +done + +############################################################# +# Build the Framework with xcodebuild +# Globals: +# None +# Arguments: +# CONFIGURATION_TARGET_TYPE +# Returns: +# exit status +############################################################# +function build_frameworks { + if [ $# -ne 1 ];then + echo "FUNC '$FUNCNAME': Invalid amount of arguments passed" + echo "PASSED ARGS: $*" + exit 1 + fi + + local configuration_target_type="$1" + + echo "FUNC '$FUNCNAME': configuration_target_type: '$configuration_target_type'" + + # Do the build + xcodebuild -project UnityAdsStaticLibrary.xcodeproj -configuration "$configuration_target_type" +} + + + +echo "Generating XCODE project file" +./generate-project.rb +if [ $? -ne 0 ]; then + echo -e "\n\nGenerating XCODE project file errored\n\n" + exit 1 +fi + rm -rf build rm -rf ~/Library/Developer/Xcode/DerivedData/UnityAds* -xcodebuild -project UnityAdsStaticLibrary.xcodeproj -configuration Release \ No newline at end of file + +if $BUILD_BOTH_TARGETS; then + echo "Building both targets DEBUG and RELEASE" + CONFIGURATION_TARGET_TYPE="Release" + build_frameworks $CONFIGURATION_TARGET_TYPE + + CONFIGURATION_TARGET_TYPE="Debug" + build_frameworks $CONFIGURATION_TARGET_TYPE +else + echo "Building Single Target $CONFIGURATION_TARGET_TYPE" + build_frameworks $CONFIGURATION_TARGET_TYPE +fi \ No newline at end of file