├── .github └── fabricbot.json ├── .gitignore ├── Docs ├── Content │ └── Batching.md └── Tasks │ ├── LargeFileUpload.md │ └── PageIterator.md ├── LICENSE ├── MSGraphClientSDK.podspec ├── MSGraphClientSDK ├── MSGraphClientSDK.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── MSGraphClientSDK.xcscheme ├── MSGraphClientSDK │ ├── Authentication │ │ ├── MSAuthenticationProvider.h │ │ └── MSAuthenticationProviderOptions.h │ ├── Common │ │ ├── MSConstants.h │ │ ├── MSConstants.m │ │ ├── MSErrorCodes.h │ │ ├── MSErrorCodes.m │ │ └── Session Tasks │ │ │ ├── MSURLSessionDataTask.h │ │ │ ├── MSURLSessionDataTask.m │ │ │ ├── MSURLSessionDownloadTask.h │ │ │ ├── MSURLSessionDownloadTask.m │ │ │ ├── MSURLSessionTask.h │ │ │ ├── MSURLSessionTask.m │ │ │ ├── MSURLSessionUploadTask.h │ │ │ └── MSURLSessionUploadTask.m │ ├── GraphContent │ │ └── BatchContent │ │ │ ├── MSBatchRequestContent.h │ │ │ ├── MSBatchRequestContent.m │ │ │ ├── MSBatchRequestStep.h │ │ │ ├── MSBatchRequestStep.m │ │ │ ├── MSBatchResponseContent.h │ │ │ └── MSBatchResponseContent.m │ ├── GraphTasks │ │ ├── MSGraphOneDriveLargeFileUploadTask.h │ │ ├── MSGraphOneDriveLargeFileUploadTask.m │ │ ├── MSLargeFileUploadTask.h │ │ ├── MSLargeFileUploadTask.m │ │ ├── MSPageIterator.h │ │ └── MSPageIterator.m │ ├── HTTPClient │ │ ├── MSClientFactory.h │ │ ├── MSClientFactory.m │ │ ├── MSHTTPClient.h │ │ ├── MSHTTPClient.m │ │ ├── MSMiddlewareFactory.h │ │ └── MSMiddlewareFactory.m │ ├── Info.plist │ ├── MSGraphClientSDK.h │ └── Middleware │ │ ├── Implementations │ │ ├── Authentication │ │ │ ├── MSAuthenticationHandler.h │ │ │ └── MSAuthenticationHandler.m │ │ ├── HTTPProvider │ │ │ ├── MSHttpProvider.h │ │ │ ├── MSURLSessionManager.h │ │ │ ├── MSURLSessionManager.m │ │ │ ├── MSURLSessionTaskDelegate.h │ │ │ └── MSURLSessionTaskDelegate.m │ │ ├── RedirectHandler │ │ │ ├── MSRedirectHandler.h │ │ │ └── MSRedirectHandler.m │ │ └── RetryHandler │ │ │ ├── MSRetryHandler.h │ │ │ └── MSRetryHandler.m │ │ ├── Options │ │ ├── MSAuthenticationHandlerOptions.h │ │ ├── MSAuthenticationHandlerOptions.m │ │ ├── MSMiddlewareOptions.h │ │ ├── MSRedirectHandlerOptions.h │ │ ├── MSRedirectHandlerOptions.m │ │ ├── MSRetryHandlerOptions.h │ │ └── MSRetryHandlerOptions.m │ │ └── Protocols │ │ └── MSGraphMiddleware.h └── MSGraphClientSDKTests │ ├── Frameworks │ ├── OCMock │ │ ├── NSNotificationCenter+OCMAdditions.h │ │ ├── OCMArg.h │ │ ├── OCMConstraint.h │ │ ├── OCMFunctions.h │ │ ├── OCMLocation.h │ │ ├── OCMMacroState.h │ │ ├── OCMRecorder.h │ │ ├── OCMStubRecorder.h │ │ ├── OCMock.h │ │ └── OCMockObject.h │ └── libOCMock.a │ ├── GraphContent │ └── BatchContent │ │ ├── MSBatchRequestContentTests.m │ │ ├── MSBatchRequestStepTests.m │ │ └── MSBatchResponseContentTests.m │ ├── GraphTasks │ ├── MSGraphOneDriveLargeFileUploadTests.m │ ├── MSLargeFileUploadTaskTests.m │ └── MSPageIteratorTests.m │ ├── HTTPClient │ ├── MSClientFactoryTests.m │ ├── MSHTTPClientTests.m │ └── MSMiddlewareFactoryTests.m │ ├── Info.plist │ ├── MSGraphClientSDKTests.h │ ├── MSGraphClientSDKTests.m │ ├── MSGraphWorkloadsTests.m │ ├── Middleware │ ├── Implementations │ │ ├── MSAuthenticationHandlerTests.m │ │ ├── MSRedirectHandlerTests.m │ │ ├── MSRetryHandlerTests.m │ │ ├── MSURLSessionManagerTests.m │ │ └── MSURLSessionTaskDelegateTests.m │ └── Options │ │ ├── MSAuthenticationHandlerOptionsTests.m │ │ ├── MSRedirectHandlerOptionsTests.m │ │ └── MSRetryHandlerOptionsTests.m │ ├── Resources │ ├── BatchResponse.json │ ├── LargeFileUploadResource.bmp │ ├── PagedResponse.json │ └── UserPhoto.jpg │ └── SessionTask │ ├── MSURLSessionDataTaskTests.m │ ├── MSURLSessionDownloadTaskTests.m │ ├── MSURLSessionTaskTests.m │ └── MSURLSessionUploadTaskTests.m ├── README.md └── SECURITY.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | # CocoaPods 32 | # 33 | # We recommend against adding the Pods directory to your .gitignore. However 34 | # you should judge for yourself, the pros and cons are mentioned at: 35 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 36 | # 37 | # Pods/ 38 | 39 | # Carthage 40 | # 41 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 42 | # Carthage/Checkouts 43 | 44 | Carthage/Build 45 | 46 | # fastlane 47 | # 48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 49 | # screenshots whenever they are needed. 50 | # For more information about the recommended setup visit: 51 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 52 | 53 | fastlane/report.xml 54 | fastlane/Preview.html 55 | fastlane/screenshots/**/*.png 56 | fastlane/test_output 57 | 58 | # Code Injection 59 | # 60 | # After new code Injection tools there's a generated folder /iOSInjectionProject 61 | # https://github.com/johnno1962/injectionforxcode 62 | 63 | iOSInjectionProject/ 64 | -------------------------------------------------------------------------------- /Docs/Tasks/LargeFileUpload.md: -------------------------------------------------------------------------------- 1 | # Large File Upload Task - Uploading large files to OneDrive. 2 | 3 | This task can be used for of onedrive's [Upload large files with an upload session](https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/driveitem_createuploadsession) feature. 4 | 5 | ## Creating the client instance 6 | 7 | Refer [this part](https://github.com/microsoftgraph/msgraph-sdk-objc#how-to-use-sdk) of Readme file and follow the steps to create an HTTP Client configured with authentication provider. 8 | 9 | ## Uploading the file 10 | 11 | Once you have an MSHTTPClient instance you just need to use `MSGraphOneDriveLargeFileUploadTask` class in below fashion to successfully upload the file: 12 | ``` 13 | //Get file url 14 | NSURL *fileURL = [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"LargeFileUploadResource" ofType:@".bmp"]]; 15 | NSError *fileReadError; 16 | //Create file data 17 | NSData *fileData = [NSData dataWithContentsOfFile:[fileURL absoluteString] options:kNilOptions error:&fileReadError]; 18 | if(!fileReadError) 19 | { 20 | //Create an MSGraphOneDriveLargeFileUploadTask. 21 | [MSGraphOneDriveLargeFileUploadTask createOneDriveLargeFileUploadTaskWithHTTPClient:httpClient fileData:fileData fileName:@"LargeFile" filePath:@"Documents" andChunkSize:5*1024*1024 withCompletion:^(MSGraphOneDriveLargeFileUploadTask *fileUploadTask, NSData *data, NSURLResponse *response, NSError *error) { 22 | if(error) 23 | { 24 | //Handle any error which might have occurred during upload session creation 25 | NSLog(@"There was some error while creating upload session %@",error); 26 | } 27 | else if([(NSHTTPURLResponse *)response statusCode] == 200 && fileUploadTask) 28 | { 29 | //Use successfully created fileUploadTask to upload the file. 30 | [fileUploadTask uploadWithCompletion:^(NSData *data, NSURLResponse *response, NSError *error) { 31 | if(!error) 32 | { 33 | NSLog(@"Response from server %@",[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]); 34 | } 35 | }]; 36 | } 37 | }]; 38 | } 39 | ``` 40 | 41 | -------------------------------------------------------------------------------- /Docs/Tasks/PageIterator.md: -------------------------------------------------------------------------------- 1 | # PageIterator 2 | 3 | This task enables the consumers of the SDK to iterate through paged collections in a simplified manner. 4 | 5 | To understand the objectives and requirements for this feature in more detail, please refer [PageIterator](https://github.com/microsoftgraph/msgraph-sdk-design/blob/master/tasks/PageIteratorTask.md). 6 | 7 | ## Usage 8 | 9 | ### Creating the client instance 10 | 11 | Refer [this part](https://github.com/microsoftgraph/msgraph-sdk-objc#how-to-use-sdk) of Readme file and follow the steps to create an HTTP Client configured with authentication provider. 12 | 13 | ### Using the MSPageIterator class 14 | //Create a request for the API which will have paged collection response. For example:/me/messages 15 | NSMutableURLRequest *messageRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[MSGraphBaseURL stringByAppendingString:@"/me/messages?$top=10"]]]; 16 | 17 | //Create a data task to get the initial response 18 | MSURLSessionDataTask *dataTask = [httpClient dataTaskWithRequest:messageRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 19 | if(!error){ 20 | __block int itemCount = 0; 21 | //If there is no error, use MSPageIterator instance to perform intra-page iteration and then onwards inter-page iteration. 22 | MSPageIterator *pageIterator = [[MSPageIterator alloc] initWithData:data client:httpClient andIteratorBlock:^(NSDictionary *itemDictionary, BOOL *stop) { 23 | //The itemDictionary in callback block corresponds to individual message in the list. 24 | if(itemCount == 21){ 25 | //You can stop the iteration in below fashion. 26 | *stop = TRUE; 27 | } 28 | itemCount++; 29 | }]; 30 | //Start the iteration 31 | [pageIterator iterate]; 32 | } 33 | }]; 34 | [dataTask execute]; 35 | ``` 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Microsoft Graph 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MSGraphClientSDK.podspec: -------------------------------------------------------------------------------- 1 | 2 | Pod::Spec.new do |s| 3 | 4 | s.name = "MSGraphClientSDK" 5 | s.version = "1.0.0" 6 | s.summary = "Microsoft Graph ObjC SDK." 7 | 8 | s.description = <<-DESC 9 | Integrate the Microsoft Graph API into your iOS App! 10 | DESC 11 | 12 | s.homepage = "http://graph.microsoft.io" 13 | s.license = { :type => "MIT", :file => "LICENSE" } 14 | s.author = 'Microsoft Graph' 15 | 16 | 17 | s.ios.deployment_target = "9.0" 18 | s.osx.deployment_target = "10.10" 19 | 20 | s.source = { :git => "https://github.com/microsoftgraph/msgraph-sdk-objc.git", :tag=> s.version } 21 | 22 | s.source_files = "MSGraphClientSDK/MSGraphClientSDK/MSGraphClientSDK.h" 23 | s.exclude_files = "MSGraphClientSDK/MSGraphClientSDKTests/*" 24 | s.public_header_files = "MSGraphClientSDK/MSGraphClientSDK/MSGraphClientSDK.h" 25 | 26 | s.subspec "Authentication" do |authentication| 27 | authentication.source_files = "MSGraphClientSDK/MSGraphClientSDK/Authentication/*.{h,m}" 28 | authentication.public_header_files = "MSGraphClientSDK/MSGraphClientSDK/Authentication/*.h" 29 | end 30 | 31 | s.subspec "Common" do |common| 32 | common.dependency 'MSGraphClientSDK/Authentication' 33 | common.source_files = "MSGraphClientSDK/MSGraphClientSDK/{Common,Middleware,GraphContent,HTTPClient,GraphTasks}/**/*.{h,m}" 34 | common.public_header_files = "MSGraphClientSDK/MSGraphClientSDK/{Common,Middleware,GraphContent,HTTPClient,GraphTasks}/**/*.h" 35 | end 36 | 37 | end 38 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK.xcodeproj/xcshareddata/xcschemes/MSGraphClientSDK.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 65 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 84 | 90 | 91 | 92 | 93 | 95 | 96 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Authentication/MSAuthenticationProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSAuthenticationProviderOptions.h" 7 | 8 | typedef void(^MSAuthenticationCompletion)(NSMutableURLRequest *request, NSError *error); 9 | 10 | /** 11 | The `MSAuthenticationProvider` is a protocol that is used to inject authentication into the MSHTTPClient. 12 | It should handle all initial authentication, refreshing, and returning the access token. 13 | */ 14 | @protocol MSAuthenticationProvider 15 | 16 | /** 17 | Gets the access token. This method should be implemented by a class which should provide the capability of providing the access token. 18 | @param authProviderOptions Options which can be used to control the behaviour of AuthenticationProvider 19 | @param completion The completion handler to be called when access token or an error can be returned. 20 | */ 21 | 22 | - (void) getAccessTokenForProviderOptions:(id)authProviderOptions andCompletion:(void (^)(NSString *accessToken, NSError *error))completion; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Authentication/MSAuthenticationProviderOptions.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | 7 | /** 8 | The `MSAuthenticationProviderOptions` is a protocol that is used to define the contract for the options required by AuthenticationProvider */ 9 | @protocol MSAuthenticationProviderOptions 10 | 11 | @required 12 | 13 | /* 14 | This property is added to ensure that every option class sets the type of it so that during execution middlewares can pick up the option which is requried by it's implementation. 15 | */ 16 | @property NSArray *scopesArray; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Common/MSConstants.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | 7 | #ifndef MSConstants_h 8 | #define MSConstants_h 9 | 10 | typedef NS_ENUM(NSInteger, MSClientErrorCode) 11 | { 12 | MSCLientErrorCodeSDKUpperLimitReached = -1, 13 | MSClientErrorCodeBadRequest = 400, 14 | MSClientErrorCodeUnauthorized = 401, 15 | MSClientErrorCodeForbidden = 403, 16 | MSClientErrorCodeNotFound = 404, 17 | MSClientErrorCodeMethodNotAllowed = 405, 18 | MSClientErrorCodeUNACCEPTABLE = 406, 19 | MSClientErrorCodeConflict = 409, 20 | MSClientErrorCodeLengthRequired = 411, 21 | MSClientErrorCodePreconditionFailed = 412, 22 | MSClientErrorCodeRequestEntityTooLarge = 413, 23 | MSClientErrorCodeUnsupportedMediaType = 415, 24 | MSClientErrorCodeRequestRangeNotSatisfiable = 416, 25 | MSClientErrorCodeUnprocessableEntity = 422, 26 | MSClientErrorCodeTooManyRequests = 429, 27 | MSClientErrorCodeInternalServerError = 500, 28 | MSClientErrorCodeNotImplemented = 501, 29 | MSClientErrorCodeServiceUnavailable = 503, 30 | MSClientErrorCodeGatewayTimeout = 504, 31 | MSClientErrorCodeInsufficientStorage = 507, 32 | MSClientErrorCodeUnknownError = 999, 33 | }; 34 | 35 | typedef NS_ENUM(NSInteger, MSExpectedResponseCodes) 36 | { 37 | MSExpectedResponseCodesOK = 200, 38 | MSExpectedResponseCodesCreated = 201, 39 | MSExpectedResponseCodesAccepted = 202, 40 | MSExpectedResponseCodesMovedPermanantly = 301, 41 | MSExpectedResponseCodesFound = 302, 42 | MSExpectedResponseCodesSeeOther = 303, 43 | MSExpectedResponseCodesNotModified = 304, 44 | MSExpectedResponseCodesTemporaryRedirect = 307, 45 | }; 46 | 47 | typedef NS_ENUM(NSInteger, MSMiddlewareOptionsType) 48 | { 49 | MSMiddlewareOptionsTypeNone, 50 | MSMiddlewareOptionsTypeAuth, 51 | MSMiddlewareOptionsTypeRedirect, 52 | MSMiddlewareOptionsTypeRetry 53 | }; 54 | 55 | extern NSString *const MSGraphBaseURL; 56 | extern NSString *const MSGraphChinaBaseURL; 57 | extern NSString *const MSGraphUSBaseURL; 58 | extern NSString *const MSGraphGermanyBaseURL; 59 | 60 | extern NSString *const MSHeaderSdkVersion; 61 | extern NSString *const MSGraphiOSSdkVersionHeaderPrefix; 62 | extern NSString *const MSGraphMacSdkVersionHeaderPrefix; 63 | 64 | extern NSString *const MSErrorDomain; 65 | 66 | extern NSString *const MSErrorTooManyRedirectsFormatString; 67 | extern NSString *const MSErrorLocationHeaderNotFoundString; 68 | extern NSString *const MSErrorOperationUnsuccessfulString; 69 | extern NSString *const MSErrorMaxRedirectsLimitExceededString; 70 | 71 | extern NSString *const MSErrorTooManyRetries; 72 | extern NSString *const MSErrorTooManyRetriesFormatString; 73 | extern NSString *const MSErrorDelayLimitExceededString; 74 | extern NSString *const MSErrorMaxRetriesLimitExceededString; 75 | 76 | extern NSString *const HTTPMethodGet; 77 | extern NSString *const HTTPMethodPut; 78 | extern NSString *const HTTPMethodPatch; 79 | extern NSString *const HTTPMethodPost; 80 | extern NSString *const HTTPMethodDelete; 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Common/MSConstants.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSConstants.h" 6 | 7 | NSString *const MSGraphBaseURL = @"https://graph.microsoft.com/v1.0"; 8 | NSString *const MSGraphChinaBaseURL = @"https://microsoftgraph.chinacloudapi.cn/v1.0"; 9 | NSString *const MSGraphUSBaseURL = @"https://graph.microsoft.us/v1.0"; 10 | NSString *const MSGraphGermanyBaseURL = @"https://graph.microsoft.de/v1.0"; 11 | 12 | NSString *const MSHeaderSdkVersion = @"SdkVersion"; 13 | NSString *const MSGraphiOSSdkVersionHeaderPrefix = @"graph-objc-ios/"; 14 | NSString *const MSGraphMacSdkVersionHeaderPrefix = @"graph-objc-mac/"; 15 | 16 | 17 | NSString *const MSErrorDomain = @"com.microsoft.graph.errors"; 18 | NSString *const MSErrorTooManyRedirectsFormatString = @"More than %ld redirects encountered while sending the request."; 19 | NSString *const MSErrorLocationHeaderNotFoundString = @"There is no location header in the redirect response."; 20 | NSString *const MSErrorOperationUnsuccessfulString = @"Operation was unsuccessful."; 21 | NSString *const MSErrorMaxRedirectsLimitExceededString = @"Limit for maximum redirects allowed is %ld."; 22 | 23 | 24 | NSString *const MSErrorTooManyRetries = @"Too many retries"; 25 | NSString *const MSErrorTooManyRetriesFormatString = @"More than %ld retries encountered while sending the request."; 26 | NSString *const MSErrorDelayLimitExceededString = @"Limit for maximum delay allowed is %ld."; 27 | NSString *const MSErrorMaxRetriesLimitExceededString = @"Limit for maximum retries allowed is %ld"; 28 | 29 | 30 | NSString *const HTTPMethodGet = @"GET"; 31 | NSString *const HTTPMethodPut = @"PUT"; 32 | NSString *const HTTPMethodPatch = @"PATCH"; 33 | NSString *const HTTPMethodPost = @"POST"; 34 | NSString *const HTTPMethodDelete = @"DELETE"; 35 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Common/MSErrorCodes.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | 7 | #ifndef MSErrorCodes_h 8 | #define MSErrorCodes_h 9 | 10 | 11 | typedef NS_ENUM(NSInteger, MSErrorCode) 12 | { 13 | MSErrorCodeEmptyRequestId = -62300, 14 | MSErrorCodeNonUniqueRequestId = -62301, 15 | MSErrorCodeMaximumLimitReached = -62302, 16 | MSErrorCodeRequestIdNotAvailable = -62303 17 | }; 18 | 19 | extern NSString *const MSErrorStringEmptyRequestIdDescription; 20 | extern NSString *const MSErrorStringEmptyRequestIdReason; 21 | 22 | extern NSString *const MSErrorStringNonUniqueRequestIdDescription; 23 | extern NSString *const MSErrorStringNonUniqueRequestIdReason; 24 | 25 | extern NSString *const MSErrorStringMaximumBatchStepLimitReachedDescription; 26 | extern NSString *const MSErrorStringMaximumBatchStepLimitReachedReason; 27 | 28 | extern NSString *const MSErrorStringRequestIdNotAvailableDescription; 29 | extern NSString *const MSErrorStringRequestIdNotAvailableReason; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Common/MSErrorCodes.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSErrorCodes.h" 6 | 7 | NSString *const MSErrorStringEmptyRequestIdDescription = @"Empty id for request"; 8 | NSString *const MSErrorStringEmptyRequestIdReason = @"Id for a request is empty, Please provide a unique id."; 9 | 10 | NSString *const MSErrorStringNonUniqueRequestIdDescription = @"Duplicate RequestId Error"; 11 | NSString *const MSErrorStringNonUniqueRequestIdReason = @"Couldn't add request with duplicate id %@, Make the id of requests unique."; 12 | 13 | NSString *const MSErrorStringMaximumBatchStepLimitReachedDescription = @"Limit Exceeded Error"; 14 | NSString *const MSErrorStringMaximumBatchStepLimitReachedReason = @"Maximum requests limit exceeded, Max allowed number of requests are %ld"; 15 | 16 | NSString *const MSErrorStringRequestIdNotAvailableDescription = @"Request id not found"; 17 | NSString *const MSErrorStringRequestIdNotAvailableReason = @"Request id %@ is not present."; 18 | 19 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Common/Session Tasks/MSURLSessionDataTask.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSURLSessionTask.h" 6 | 7 | /** 8 | An MSURLSessionTask to be used for retrieving data. 9 | @see MSURLSessionTask 10 | */ 11 | @interface MSURLSessionDataTask : MSURLSessionTask 12 | 13 | /** 14 | Creates a Data task with the given request and client. 15 | @param request The mutableURL request. Must not be nil. 16 | @param client The client that will send the request. Must not be nil. 17 | @param completionHandler The completion handler to call when the task has completed. 18 | */ 19 | - (instancetype)initWithRequest:(NSMutableURLRequest *)request 20 | client:(MSHTTPClient *)client 21 | completion:(MSDataCompletionHandler)completionHandler; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Common/Session Tasks/MSURLSessionDataTask.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSURLSessionDataTask.h" 6 | #import "MSHTTPClient.h" 7 | 8 | @interface MSURLSessionDataTask() 9 | 10 | @property (nonatomic, copy) MSDataCompletionHandler completionHandler; 11 | 12 | @end 13 | 14 | @implementation MSURLSessionDataTask 15 | 16 | - (instancetype)initWithRequest:(NSMutableURLRequest *)request 17 | client:(MSHTTPClient *)client 18 | completion:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler 19 | { 20 | self = [super initWithRequest:request client:client]; 21 | if (self) 22 | { 23 | _completionHandler = completionHandler; 24 | } 25 | return self; 26 | } 27 | 28 | - (void)taskCompletedWithData:(id)data response:(NSURLResponse *)response andError:(NSError *)error 29 | { 30 | if(_completionHandler) 31 | { 32 | _completionHandler(data, response, error); 33 | } 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Common/Session Tasks/MSURLSessionDownloadTask.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSURLSessionTask.h" 6 | 7 | /** 8 | An MSURLSessionTask to be used for downloading content. 9 | @see MSURLSessionTask 10 | */ 11 | @interface MSURLSessionDownloadTask : MSURLSessionTask 12 | 13 | /** 14 | The NSProgress to monitor. 15 | */ 16 | 17 | @property (strong, readonly) NSProgress *progress; 18 | 19 | /** 20 | Creates a Download task with the given request and client. 21 | @param request The mutableURL request. Must not be nil. 22 | @param client The client that will send the request. Must not be nil. 23 | @param completionHandler The completion handler to call when the task has completed. 24 | */ 25 | - (instancetype)initWithRequest:(NSMutableURLRequest *)request 26 | client:(MSHTTPClient *)client 27 | completionHandler:(MSDownloadCompletionHandler)completionHandler; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Common/Session Tasks/MSURLSessionDownloadTask.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSURLSessionDownloadTask.h" 6 | #import "MSHTTPClient.h" 7 | 8 | @interface MSURLSessionDownloadTask() 9 | 10 | @property (nonatomic, copy) MSDownloadCompletionHandler completionHandler; 11 | 12 | @end 13 | 14 | @implementation MSURLSessionDownloadTask 15 | 16 | - (instancetype)initWithRequest:(NSMutableURLRequest *)request 17 | client:(MSHTTPClient *)client 18 | completionHandler:(MSDownloadCompletionHandler)completionHandler 19 | { 20 | self = [super initWithRequest:request client:client]; 21 | if (self) 22 | { 23 | [self createProgress]; 24 | _completionHandler = completionHandler; 25 | } 26 | return self; 27 | } 28 | 29 | - (NSProgress *)createProgress 30 | { 31 | NSProgress *progress = [NSProgress progressWithTotalUnitCount:0]; 32 | _progress = progress; 33 | return progress; 34 | } 35 | 36 | - (void)taskCompletedWithData:(id)data response:(NSURLResponse *)response andError:(NSError *)error 37 | { 38 | if(_completionHandler) 39 | { 40 | _completionHandler(data, response, error); 41 | } 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Common/Session Tasks/MSURLSessionTask.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | @class MSHTTPClient; 6 | 7 | #import 8 | #import "MSHttpProvider.h" 9 | #import "MSMiddlewareOptions.h" 10 | 11 | /** 12 | The Upload Completion Handler to be called when an upload is completed. 13 | */ 14 | typedef MSRawUploadCompletionHandler MSUploadCompletionHandler; 15 | 16 | /** 17 | The download completion handler to be called when a download is completed. 18 | */ 19 | typedef MSRawDownloadCompletionHandler MSDownloadCompletionHandler; 20 | 21 | //Completion handler to be called when request finishes 22 | typedef void (^HTTPRequestCompletionHandler)(id data, NSURLResponse * _Nullable response, NSError * _Nullable error); 23 | 24 | @interface MSURLSessionTask : NSObject 25 | 26 | @property (readonly) NSMutableURLRequest *request; 27 | 28 | /** 29 | The NSURLSessionTask that is created and used to make the actual request. 30 | This may be nil until the inner task is actually created. 31 | */ 32 | @property (readonly) NSURLSessionTask *innerTask; 33 | 34 | /** 35 | The client that sends the request. 36 | */ 37 | @property (strong) MSHTTPClient *client; 38 | 39 | /* 40 | This property can be used to set an array of custom middleware options specific for the execution of the Task. 41 | */ 42 | @property (nonatomic, strong) NSArray *middlewareOptionsArray; 43 | 44 | /** 45 | Creates an `MSURLSessionTask` with the given requests and client. 46 | @param request The request to use. Must not be nil. 47 | @param client The client to make the request. Must not be nil. 48 | */ 49 | - (instancetype)initWithRequest:(NSMutableURLRequest *)request client:(MSHTTPClient *)client; 50 | 51 | /** 52 | Executes the task. 53 | @warning The task may send an extra request to reauthenticate the session if the auth token has expired. 54 | */ 55 | - (void)execute; 56 | 57 | /** 58 | Cancels the task. 59 | */ 60 | - (void)cancel; 61 | 62 | /* 63 | This method can be used by to get a specific middleware matching with the type provided in argument. 64 | @param middlewareOptionsType The type of middleware options that needs to be returned 65 | @return An instance of middleware options if a match is found otherwise it will be nil. 66 | */ 67 | - (id)getMiddlewareOptionWithType:(MSMiddlewareOptionsType)middlewareOptionsType; 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Common/Session Tasks/MSURLSessionTask.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSURLSessionTask.h" 6 | #import "MSHTTPClient.h" 7 | #import "MSConstants.h" 8 | 9 | @interface MSURLSessionTask() 10 | 11 | @property (atomic) BOOL isCancelled; 12 | 13 | @end 14 | 15 | @implementation MSURLSessionTask 16 | 17 | - (instancetype)initWithRequest:(NSMutableURLRequest *)request 18 | client:(MSHTTPClient *)client 19 | { 20 | NSParameterAssert(request); 21 | NSParameterAssert(client); 22 | 23 | self = [super init]; 24 | if (self) 25 | { 26 | _client = client; 27 | _request = [request mutableCopy]; 28 | } 29 | return self; 30 | } 31 | 32 | - (void)execute 33 | { 34 | [self.client.middleware execute:self withCompletionHandler:^(id data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 35 | [self taskCompletedWithData:data response:response andError:error]; 36 | }]; 37 | } 38 | 39 | - (void)setRequest:(NSMutableURLRequest *)request 40 | { 41 | _request = request; 42 | } 43 | 44 | - (void)setInnerTask:(NSURLSessionTask *)innerTask 45 | { 46 | if(_isCancelled) 47 | { 48 | [innerTask cancel]; 49 | }else 50 | { 51 | _innerTask = innerTask; 52 | } 53 | } 54 | 55 | - (void)cancel 56 | { 57 | if(_innerTask) 58 | { 59 | [_innerTask cancel]; 60 | 61 | }else 62 | { 63 | _isCancelled = YES; 64 | } 65 | 66 | } 67 | 68 | - (void)setSDKVersionRequestHeader 69 | { 70 | NSDictionary *info = [[NSBundle bundleForClass:[self class]] infoDictionary]; 71 | NSString *version = [info objectForKey:@"CFBundleShortVersionString"]; 72 | if (TARGET_OS_OSX) 73 | { 74 | [_request setValue:[NSString stringWithFormat:@"%@%@", MSGraphMacSdkVersionHeaderPrefix, version] forHTTPHeaderField:MSHeaderSdkVersion]; 75 | }else 76 | { 77 | [_request setValue:[NSString stringWithFormat:@"%@%@", MSGraphiOSSdkVersionHeaderPrefix, version] forHTTPHeaderField:MSHeaderSdkVersion]; 78 | } 79 | } 80 | 81 | - (void)taskCompletedWithData:(id)data response:(NSURLResponse *)response andError:(NSError *)error 82 | { 83 | NSAssert(NO, @"Not Implemented, must implement in sub class"); 84 | } 85 | 86 | - (void)setMiddlewareOptionsArray:(NSArray *)middlewareOptionsArray 87 | { 88 | _middlewareOptionsArray = [middlewareOptionsArray copy]; 89 | } 90 | 91 | - (id)getMiddlewareOptionWithType:(MSMiddlewareOptionsType)middlewareOptionsType 92 | { 93 | id middlewareOptionsToReturn; 94 | for(id middlewareOptions in _middlewareOptionsArray) 95 | { 96 | if(middlewareOptionsType == middlewareOptions.middlewareOptionsType) 97 | { 98 | middlewareOptionsToReturn = middlewareOptions; 99 | break; 100 | } 101 | } 102 | return middlewareOptionsToReturn; 103 | } 104 | 105 | @end 106 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Common/Session Tasks/MSURLSessionUploadTask.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSURLSessionTask.h" 6 | /** 7 | An `MSURLSessionTask` to upload content. 8 | @see MSURLSessionTask 9 | */ 10 | @interface MSURLSessionUploadTask : MSURLSessionTask 11 | 12 | /** 13 | The NSProgress to monitor. 14 | */ 15 | 16 | @property (strong, readonly) NSProgress *progress; 17 | 18 | /** 19 | Creates an UploadSessionTask. 20 | @param request The request to be made. 21 | @param fileURL The URL to the local file to be uploaded. 22 | @param client The client that will make the request. 23 | @param completionHandler The completion to be called on completion. 24 | @warning Request, fileURL, and client must not be nil. 25 | */ 26 | - (instancetype) initWithRequest:(NSMutableURLRequest *)request 27 | fromFile:(NSURL *)fileURL 28 | client:(MSHTTPClient *)client 29 | completionHandler:(MSUploadCompletionHandler)completionHandler; 30 | 31 | /** 32 | Creats an UploadSessionTask. 33 | @param request The request to be made. 34 | @param data The data to be uploaded. 35 | @param client The client that will make the request. 36 | @param completionHandler The completion to be called on completion. 37 | @warning Request, data, and client must not be nil. 38 | */ 39 | - (instancetype)initWithRequest:(NSMutableURLRequest *)request 40 | data:(NSData *)data 41 | client:(MSHTTPClient *)client 42 | completionHandler:(MSUploadCompletionHandler)completionHandler; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Common/Session Tasks/MSURLSessionUploadTask.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSURLSessionUploadTask.h" 6 | 7 | @interface MSURLSessionUploadTask() 8 | 9 | @property NSURL *fileURL; 10 | 11 | @property NSData *data; 12 | 13 | @property BOOL isFileUploadTask; 14 | 15 | @property (nonatomic,copy) MSUploadCompletionHandler completionHandler; 16 | 17 | @end 18 | 19 | @implementation MSURLSessionUploadTask 20 | 21 | - (instancetype) initWithRequest:(NSMutableURLRequest *)request 22 | fromFile:(NSURL *)fileURL 23 | client:(MSHTTPClient *)client 24 | completionHandler:(MSUploadCompletionHandler)completionHandler 25 | { 26 | NSParameterAssert(fileURL); 27 | 28 | self = [super initWithRequest:request client:client]; 29 | if(self) 30 | { 31 | _fileURL = fileURL; 32 | _completionHandler = completionHandler; 33 | _isFileUploadTask = YES; 34 | [self createProgress]; 35 | } 36 | return self; 37 | } 38 | 39 | - (instancetype)initWithRequest:(NSMutableURLRequest *)request 40 | data:(NSData *)data 41 | client:(MSHTTPClient *)client 42 | completionHandler:(MSUploadCompletionHandler)completionHandler 43 | { 44 | NSParameterAssert(data); 45 | 46 | self = [super initWithRequest:request client:client]; 47 | if (self) 48 | { 49 | _data = data; 50 | _completionHandler = completionHandler; 51 | _isFileUploadTask = NO; 52 | [self createProgress]; 53 | } 54 | return self; 55 | } 56 | 57 | - (NSProgress *)createProgress 58 | { 59 | NSProgress *progress = [NSProgress progressWithTotalUnitCount:0]; 60 | _progress = progress; 61 | return progress; 62 | } 63 | 64 | 65 | - (void)taskCompletedWithData:(id)data response:(NSURLResponse *)response andError:(NSError *)error 66 | { 67 | if(_completionHandler) 68 | { 69 | _completionHandler(data, response, error); 70 | } 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/GraphContent/BatchContent/MSBatchRequestContent.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | 7 | @class MSBatchRequestStep; 8 | 9 | /* 10 | To make batch requests, all the individual request needs to be clubbed in one single request body. This class provides mechanism to create that content for batch requests. 11 | Maximum limit of MSBatchRequestSteps in one single MSBatchRequestContent is set to 20. 12 | */ 13 | @interface MSBatchRequestContent : NSObject 14 | 15 | /* 16 | Creates and returns an instance of MSBatchRequestContent 17 | @param batchRequestStepsArray Array of batch request steps with unique ids. 18 | @param error If any error is encountered during the initalization, it will be assigned to this address. 19 | @return The MSBatchRequestContent object containng the Batch Request Steps. 20 | */ 21 | - (instancetype)initWithRequests:(NSArray *)batchRequestStepsArray error:(NSError **)error; 22 | 23 | /* 24 | Adds an MSBatchRequestStep object to MSBatchRequestContent object 25 | @param batchRequestStep The object which needs to be added. 26 | @param error If any error is encountered while adding a batch request step, it will be assigned to this address. 27 | */ 28 | - (void)addBatchRequestStep:(MSBatchRequestStep *)batchRequestStep error:(NSError **)error; 29 | 30 | /* 31 | Removes an MSBatchRequestStep object from MSBatchRequestContent object 32 | @param requestId Id of the MSBatchRequestStep which should be removed. 33 | @param error If any error is encountered during the removal of a batch request step, it will be assigned to this address. 34 | */ 35 | - (void)removeBatchRequesStepWithId:(NSString *)requestId error:(NSError **)error; 36 | 37 | /* 38 | Creates and returns a dictionary object which is created by clubbing all the individual batch request step into a format recognised by Microsoft Graph server. 39 | @return A dictionary object. 40 | */ 41 | - (NSMutableDictionary *)getBatchRequestContent; 42 | 43 | @end 44 | 45 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/GraphContent/BatchContent/MSBatchRequestContent.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSBatchRequestContent.h" 6 | #import "MSBatchRequestStep.h" 7 | #import "MSConstants.h" 8 | #import "MSErrorCodes.h" 9 | 10 | @interface MSBatchRequestContent() 11 | 12 | @property (strong, nonatomic) NSMutableArray * batchRequestStepsArray; 13 | 14 | @end 15 | 16 | @implementation MSBatchRequestContent 17 | { 18 | NSInteger maxNumberOfRequests; 19 | } 20 | 21 | - (instancetype)initWithRequests:(NSArray *)batchRequestStepsArray error:(NSError *__autoreleasing *)error 22 | { 23 | self = [super init]; 24 | if(self) 25 | { 26 | //Batch requests are currently limited to 20 individual requests by Graph server. 27 | maxNumberOfRequests = 20; 28 | //Check whether number of request steps in array are more than the limit 29 | if(batchRequestStepsArray.count > maxNumberOfRequests) 30 | { 31 | NSDictionary *userInfo = @{ 32 | NSLocalizedDescriptionKey: MSErrorStringMaximumBatchStepLimitReachedDescription, 33 | NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:MSErrorStringMaximumBatchStepLimitReachedReason,(long)maxNumberOfRequests] 34 | }; 35 | *error = [NSError errorWithDomain:MSErrorDomain code:MSErrorCodeMaximumLimitReached userInfo:userInfo]; 36 | } 37 | else 38 | { 39 | for(MSBatchRequestStep *batchRequestStep in batchRequestStepsArray) 40 | { 41 | [self addBatchRequestStep:batchRequestStep error:error]; 42 | } 43 | } 44 | } 45 | return self; 46 | } 47 | 48 | - (void)addBatchRequestStep:(MSBatchRequestStep *)requestStep error:(NSError *__autoreleasing *)error 49 | { 50 | //Check for empty requestId 51 | if([requestStep.requestId isEqualToString:@""]) 52 | { 53 | NSDictionary *userInfo = @{ 54 | NSLocalizedDescriptionKey: MSErrorStringEmptyRequestIdDescription, 55 | NSLocalizedFailureReasonErrorKey: MSErrorStringEmptyRequestIdReason 56 | }; 57 | *error = [NSError errorWithDomain:MSErrorDomain code:MSErrorCodeEmptyRequestId userInfo:userInfo]; 58 | return; 59 | } 60 | 61 | //Check whether the limit for maximum number of request steps is reached 62 | if(_batchRequestStepsArray && _batchRequestStepsArray.count==maxNumberOfRequests) 63 | { 64 | NSDictionary *userInfo = @{ 65 | NSLocalizedDescriptionKey: MSErrorStringMaximumBatchStepLimitReachedDescription, 66 | NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:MSErrorStringMaximumBatchStepLimitReachedReason,(long)maxNumberOfRequests] 67 | }; 68 | *error = [NSError errorWithDomain:MSErrorDomain code:MSErrorCodeMaximumLimitReached userInfo:userInfo]; 69 | return; 70 | } 71 | 72 | if(!_batchRequestStepsArray) 73 | { 74 | _batchRequestStepsArray = [NSMutableArray new]; 75 | } 76 | 77 | //Check whether there is alreay a request step with the same requestId in array 78 | for(MSBatchRequestStep *requestStepFromArray in _batchRequestStepsArray) 79 | { 80 | if([requestStep.requestId isEqualToString:requestStepFromArray.requestId]) 81 | { 82 | NSDictionary *userInfo = @{ 83 | NSLocalizedDescriptionKey: MSErrorStringNonUniqueRequestIdDescription, 84 | NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:MSErrorStringNonUniqueRequestIdReason,requestStep.requestId] 85 | }; 86 | *error = [NSError errorWithDomain:MSErrorDomain code:MSErrorCodeNonUniqueRequestId userInfo:userInfo]; 87 | return; 88 | } 89 | } 90 | [_batchRequestStepsArray addObject:requestStep]; 91 | } 92 | 93 | - (void)removeBatchRequesStepWithId:(NSString *)requestId error:(NSError *__autoreleasing *)error 94 | { 95 | BOOL didFindStep = NO; 96 | for (long i = _batchRequestStepsArray.count-1; i >= 0; i--) 97 | { 98 | MSBatchRequestStep *requestStep = _batchRequestStepsArray[i]; 99 | for (long j = requestStep.arrayOfDependsOnIds.count-1; j >= 0; j--) 100 | { 101 | NSString *dependsOnId = requestStep.arrayOfDependsOnIds[j]; 102 | if([dependsOnId isEqualToString:requestId]) 103 | { 104 | [requestStep.arrayOfDependsOnIds removeObjectAtIndex:j]; 105 | } 106 | } 107 | if(!didFindStep && [requestId isEqualToString:requestStep.requestId]) 108 | { 109 | [_batchRequestStepsArray removeObjectAtIndex:i]; 110 | didFindStep = YES; 111 | } 112 | } 113 | if(!didFindStep) 114 | { 115 | NSDictionary *userInfo = @{ 116 | NSLocalizedDescriptionKey: MSErrorStringRequestIdNotAvailableDescription, 117 | NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:MSErrorStringRequestIdNotAvailableReason,requestId] 118 | }; 119 | *error = [NSError errorWithDomain:MSErrorDomain code:MSErrorCodeRequestIdNotAvailable userInfo:userInfo]; 120 | } 121 | } 122 | 123 | - (NSMutableDictionary *)getBatchRequestContent 124 | { 125 | NSMutableDictionary *batchRequestContentDictionary = [NSMutableDictionary new]; 126 | 127 | NSMutableArray *batchContentArray = [NSMutableArray new]; 128 | for(MSBatchRequestStep *requestStep in _batchRequestStepsArray) 129 | { 130 | [batchContentArray addObject:[self getBatchRequestDictionaryFromRequestStep:requestStep]]; 131 | } 132 | [batchRequestContentDictionary setObject:batchContentArray forKey:@"requests"]; 133 | return [batchRequestContentDictionary mutableCopy]; 134 | } 135 | 136 | - (NSMutableDictionary *)getBatchRequestDictionaryFromRequestStep:(MSBatchRequestStep *)batchRequestStep 137 | { 138 | NSMutableDictionary *requestDictionary = [NSMutableDictionary new]; 139 | [requestDictionary setObject:batchRequestStep.requestId forKey:@"id"]; 140 | [requestDictionary setObject:[batchRequestStep.request.URL absoluteString] forKey:@"url"]; 141 | [requestDictionary setObject:batchRequestStep.request.HTTPMethod forKey:@"method"]; 142 | if(batchRequestStep.request.allHTTPHeaderFields) 143 | { 144 | [requestDictionary setObject:batchRequestStep.request.allHTTPHeaderFields forKey:@"headers"]; 145 | } 146 | if(batchRequestStep.request.HTTPBody) 147 | { 148 | id requestBody; 149 | NSError *error; 150 | NSDictionary *requestBodyDictionary = [NSJSONSerialization JSONObjectWithData:batchRequestStep.request.HTTPBody options:kNilOptions error:&error]; 151 | if(!error && requestBodyDictionary) 152 | { 153 | requestBody = requestBodyDictionary; 154 | } 155 | else 156 | { 157 | requestBody = [batchRequestStep.request.HTTPBody base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]; 158 | } 159 | [requestDictionary setObject:requestBody forKey:@"body"]; 160 | } 161 | if(batchRequestStep.arrayOfDependsOnIds) 162 | { 163 | [requestDictionary setObject:batchRequestStep.arrayOfDependsOnIds forKey:@"dependsOn"]; 164 | } 165 | return requestDictionary; 166 | } 167 | 168 | @end 169 | 170 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/GraphContent/BatchContent/MSBatchRequestStep.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | 7 | /* 8 | To make batch request, native request objects needs to be clubbed with some 'id' and 'dependsOn'[optional] values. This class provides a mechanism to build such an object i.e. MSBatchRequestStep. 9 | */ 10 | @interface MSBatchRequestStep : NSObject 11 | 12 | @property (strong, nonatomic) NSString *requestId; 13 | @property (strong, nonatomic) NSMutableURLRequest *request; 14 | @property (strong, nonatomic) NSMutableArray *arrayOfDependsOnIds; 15 | 16 | /* 17 | Creates and returns an instance of MSBatchRequestStep. 18 | @param requestId The id to be associated with the request when creating batch request content. 19 | @param urlRequest The request object to be included in batch request content. 20 | @param requestIds The array of request Ids in string format which this batch request step depends on. 21 | @return The MSBatchRequestStep object created using above parameters. 22 | */ 23 | - (instancetype)initWithId:(nonnull NSString *)requestId request:(nonnull NSMutableURLRequest *)urlRequest andDependsOn:(NSArray *)requestIds; 24 | 25 | @end 26 | 27 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/GraphContent/BatchContent/MSBatchRequestStep.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSBatchRequestStep.h" 6 | 7 | @implementation MSBatchRequestStep 8 | 9 | - (instancetype)initWithId:(NSString *)requestId request:(NSMutableURLRequest *)urlRequest andDependsOn:(NSArray *)requestIds 10 | { 11 | NSParameterAssert(requestId); 12 | NSParameterAssert(urlRequest); 13 | self = [super init]; 14 | if(self) 15 | { 16 | _requestId = requestId; 17 | _request = [urlRequest mutableCopy]; 18 | _arrayOfDependsOnIds = [requestIds mutableCopy]; 19 | } 20 | return self; 21 | } 22 | 23 | @end 24 | 25 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/GraphContent/BatchContent/MSBatchResponseContent.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | 7 | /* 8 | This class can be used to get individual response dictionary or the whole response dictionary from a batch response data. 9 | */ 10 | 11 | @interface MSBatchResponseContent : NSObject 12 | 13 | /* 14 | Creates and returns an instance of MSBatchResopnseContent 15 | @param batchResponseData NSData representation of response body received from API. 16 | @param options NSJSONReading options which will internally be used by NSJSONSerialization 17 | @param error If any error is encountered during the dictionary creation from batchResponseData, it will be assigned to this address. 18 | @return The MSBatchResponseContent object 19 | */ 20 | - (instancetype)initWithBatchResponseData:(nonnull NSData *)batchResponseData options:(NSJSONReadingOptions)options error:(NSError **)error; 21 | 22 | /* 23 | Iterates through the batch response and returns the required response 24 | @param requestId The requestId of the request for which response is needed 25 | @return An NSDictionary object containing the requestId, response status, body and headers. 26 | */ 27 | - (NSDictionary *)getResponseById:(NSString *)requestId; 28 | 29 | /* 30 | Returns the whole Response dictionary created from the batchResponseData 31 | @return An NSDictionary object containing all the individual response dictionaries. 32 | */ 33 | - (NSDictionary *)getResponses; 34 | 35 | @end 36 | 37 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/GraphContent/BatchContent/MSBatchResponseContent.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSBatchResponseContent.h" 6 | 7 | @interface MSBatchResponseContent() 8 | @property (strong, nonatomic) NSDictionary *batchResponseDictionary; 9 | @end 10 | 11 | @implementation MSBatchResponseContent 12 | 13 | -(instancetype)initWithBatchResponseData:(NSData *)batchResponseData options:(NSJSONReadingOptions)options error:(NSError *__autoreleasing *)error 14 | { 15 | NSParameterAssert(batchResponseData); 16 | self = [super init]; 17 | if(self) 18 | { 19 | _batchResponseDictionary = [NSJSONSerialization JSONObjectWithData:batchResponseData options:options error:error]; 20 | } 21 | return self; 22 | } 23 | 24 | - (NSDictionary *)getResponseById:(NSString *)requestId 25 | { 26 | for(NSDictionary *responseDict in [_batchResponseDictionary objectForKey:@"responses"]) 27 | { 28 | if([[responseDict objectForKey:@"id"] isEqualToString:requestId]) 29 | { 30 | return responseDict; 31 | } 32 | } 33 | return nil; 34 | } 35 | 36 | - (NSDictionary *)getResponses 37 | { 38 | return _batchResponseDictionary; 39 | } 40 | 41 | @end 42 | 43 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/GraphTasks/MSGraphOneDriveLargeFileUploadTask.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | #import 5 | #import "MSLargeFileUploadTask.h" 6 | 7 | 8 | @class MSGraphOneDriveLargeFileUploadTask; 9 | 10 | /** 11 | Completion handler to be called from MSGraphOneDriveLargeFileUploadTask on instance creation. 12 | */ 13 | typedef void (^OneDriveLargeFileUploadTaskInitCompletionHandler)(MSGraphOneDriveLargeFileUploadTask *fileUploadTask, NSData *data, NSURLResponse *response, NSError *error); 14 | 15 | /** 16 | This class extends the generic MSLargeFileUploadTask to provide one drive specific dependency injection 17 | */ 18 | @interface MSGraphOneDriveLargeFileUploadTask : MSLargeFileUploadTask 19 | 20 | 21 | /* 22 | Creates an instance of MSLargeFileUploadTask class. Please not that you will have to call the base class's uploadWithCompletion: method on the instance which gets returned. 23 | @param httpClient Instance of MSHTTPClient which will be used to make API calls 24 | @param fileData Data of the file which needs to be chunked and uploaded. 25 | @param fileName Name of the file which will be given to item after successfull upload. 26 | @param filePath Path of the file where this should be put in the One Drive. For example - Documents/Office/LargeFiles 27 | @param chunkSize Size of a small chunk which the file will be split into. Should be in multiples of 320KB. Default value is 5MB. 28 | @param completionHandler CompletionHandler to be called on completion of this creation process. 29 | */ 30 | +(void)createOneDriveLargeFileUploadTaskWithHTTPClient:(nonnull MSHTTPClient *)httpClient fileData:(nonnull NSData *)fileData fileName:(nonnull NSString *)fileName filePath:(NSString *)filePath andChunkSize:(NSInteger)chunkSize withCompletion:(OneDriveLargeFileUploadTaskInitCompletionHandler)completionHandler; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/GraphTasks/MSGraphOneDriveLargeFileUploadTask.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSGraphOneDriveLargeFileUploadTask.h" 6 | #import "MSConstants.h" 7 | 8 | @interface MSGraphOneDriveLargeFileUploadTask() 9 | 10 | @end 11 | 12 | @implementation MSGraphOneDriveLargeFileUploadTask 13 | 14 | 15 | +(void)createOneDriveLargeFileUploadTaskWithHTTPClient:(MSHTTPClient *)httpClient fileData:(NSData *)fileData fileName:(NSString *)fileName filePath:(NSString *)filePath andChunkSize:(NSInteger)chunkSize withCompletion:(OneDriveLargeFileUploadTaskInitCompletionHandler)completionHandler 16 | { 17 | NSMutableURLRequest *createSessionRequest = [MSGraphOneDriveLargeFileUploadTask createUploadSessionRequestWithFileName:fileName filePath:filePath]; 18 | 19 | [MSGraphOneDriveLargeFileUploadTask createUploadSessionFromRequest:createSessionRequest andHTTPClient:httpClient completionBlock:^(id data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 20 | if(!error) 21 | { 22 | NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]; 23 | if(dictionary && [dictionary objectForKey:@"uploadUrl"]) 24 | { 25 | completionHandler([[MSGraphOneDriveLargeFileUploadTask alloc] initWithClient:httpClient fileData:fileData uploadSessionDictionary:dictionary andChunkSize:chunkSize], data, response, error); 26 | }else 27 | { 28 | completionHandler(nil, data, response, error); 29 | } 30 | }else 31 | { 32 | completionHandler(nil, data, response, error); 33 | } 34 | }]; 35 | 36 | } 37 | 38 | + (NSMutableURLRequest *)createUploadSessionRequestWithFileName:(NSString *)fileName filePath:(NSString *)filePath 39 | { 40 | NSString *onerDriveUrlString = [NSString stringWithFormat:@"%@/me/drive/root:/%@/%@:/createUploadSession",MSGraphBaseURL,filePath,fileName]; 41 | 42 | NSMutableURLRequest *urlReuqest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:onerDriveUrlString]]; 43 | [urlReuqest setHTTPMethod:@"POST"]; 44 | return urlReuqest; 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/GraphTasks/MSLargeFileUploadTask.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSHTTPClient.h" 7 | 8 | #define DefaultChunkSize 5*1024*1024 9 | #define RequiredChunkSizeIncrement 320*1024 10 | 11 | /* 12 | This class is Generic base class for large file upload tasks and handles all the basic functionalities of a large file uploader 13 | */ 14 | 15 | @interface MSLargeFileUploadTask : NSObject 16 | 17 | /* 18 | Initializes and returns an instance of MSLargeFileUploadTask class 19 | @param httpClient Instance of MSHTTPClient which will be used to make API calls 20 | @param fileData Data of the file which needs to be chunked and uploaded. 21 | @param uploadSessionDictionary Dictionary containing upload session url 22 | @param chunkSize Size of a small chunk which the file will be split into. Should be in multiples of 320KB. Default value is 5MB. 23 | @return MSLargeFileUploadTask instance 24 | */ 25 | -(instancetype)initWithClient:(nonnull MSHTTPClient *)httpClient fileData:(nonnull NSData *)fileData uploadSessionDictionary:(nonnull NSDictionary *)uploadSessionDictionary andChunkSize:(NSInteger)chunkSize; 26 | 27 | /* 28 | This function will start uploading all the small segments of the file one by one returning the response in completion handler in case there is any error or the upload process gets completed. 29 | @param completionHandler Completion Handler to be calles in event of any error or successfull completion 30 | */ 31 | - (void)uploadWithCompletion:(HTTPRequestCompletionHandler)completionHandler; 32 | 33 | /* 34 | This class function can be used to create upload session for a given request object. 35 | @param urlRequest The request object containing target url 36 | @param httpClient The MSHTTPClient object which will be used to make this API call for sesison creation 37 | @param completionHandler The completion handler to be called when this process finishes. 38 | */ 39 | + (void)createUploadSessionFromRequest:(NSMutableURLRequest *)urlRequest andHTTPClient:(MSHTTPClient *)httpClient completionBlock:(HTTPRequestCompletionHandler)completionHandler; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/GraphTasks/MSLargeFileUploadTask.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSLargeFileUploadTask.h" 6 | #import "MSURLSessionDataTask.h" 7 | 8 | @interface MSLargeFileUploadTask() 9 | 10 | @property (nonatomic, strong) MSHTTPClient *httpClient; 11 | @property (nonatomic, strong) NSData *fileData; 12 | @property (nonatomic, strong) NSDictionary *uploadSessionDictionary; 13 | @property (nonatomic) NSInteger chunkSize; 14 | @property (nonatomic) NSRange currentRange; 15 | 16 | @end 17 | 18 | @implementation MSLargeFileUploadTask 19 | 20 | -(instancetype)initWithClient:(MSHTTPClient *)httpClient fileData:(NSData *)fileData uploadSessionDictionary:(NSDictionary *)uploadSessionDictionary andChunkSize:(NSInteger)chunkSize 21 | { 22 | self = [super init]; 23 | if(self) 24 | { 25 | self.httpClient = httpClient; 26 | NSAssert(self.httpClient, @"HTTP Client is requried to make API calls"); 27 | self.fileData = fileData; 28 | NSAssert(self.fileData, @"File data should not nil"); 29 | NSAssert(self.fileData.length!=0, @"File data should not be empty"); 30 | self.uploadSessionDictionary = uploadSessionDictionary; 31 | NSAssert([self.uploadSessionDictionary objectForKey:@"uploadUrl"], @"UploadSessionDictionary should contain a uploadUrl key"); 32 | self.chunkSize = chunkSize<=0 ? DefaultChunkSize : chunkSize; 33 | NSAssert(self.chunkSize % RequiredChunkSizeIncrement ==0, @"Chunk size must be a multiple of 320 KiB"); 34 | 35 | self.currentRange = NSMakeRange(0, self.chunkSize); 36 | } 37 | return self; 38 | } 39 | 40 | - (void)uploadWithCompletion:(HTTPRequestCompletionHandler)completionHandler 41 | { 42 | [self uploadNextSegmentWithCompletion:completionHandler]; 43 | } 44 | 45 | - (void)setNextRange 46 | { 47 | NSInteger start = self.currentRange.location+self.currentRange.length; 48 | NSInteger length = start+_chunkSize>self.fileData.length?self.fileData.length-start:_chunkSize; 49 | self.currentRange = NSMakeRange(start,length); 50 | } 51 | 52 | - (void)uploadNextSegmentWithCompletion:(HTTPRequestCompletionHandler)completionHandler 53 | { 54 | //Create request 55 | NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:self.uploadSessionDictionary[@"uploadUrl"]]]; 56 | 57 | //Set headers 58 | [urlRequest setValue:[NSString stringWithFormat:@"%ld",(long)_chunkSize] forHTTPHeaderField:@"Content-Length"]; 59 | [urlRequest setValue:[NSString stringWithFormat:@"bytes %lu-%lu/%lu",(unsigned long)self.currentRange.location,(unsigned long)self.currentRange.location+self.currentRange.length-1,(unsigned long)self.fileData.length] forHTTPHeaderField:@"Content-Range"]; 60 | 61 | //Set method 62 | [urlRequest setHTTPMethod:@"PUT"]; 63 | 64 | //Set http body 65 | NSData *subData = [self.fileData subdataWithRange:self.currentRange]; 66 | [urlRequest setHTTPBody:subData]; 67 | 68 | //Start upload 69 | MSURLSessionDataTask *uploadTask = [self.httpClient dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 70 | if([(NSHTTPURLResponse *)response statusCode] == MSExpectedResponseCodesAccepted) 71 | { 72 | [self setNextRange]; 73 | [self uploadNextSegmentWithCompletion:completionHandler]; 74 | }else 75 | { 76 | NSDictionary *dataDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]; 77 | if(dataDict[@"id"]) 78 | { 79 | completionHandler(data, response, error); 80 | }else 81 | { 82 | [self uploadNextSegmentWithCompletion:completionHandler]; 83 | } 84 | } 85 | 86 | }]; 87 | [uploadTask execute]; 88 | } 89 | 90 | + (void)createUploadSessionFromRequest:(NSMutableURLRequest *)urlRequest andHTTPClient:(MSHTTPClient *)httpClient completionBlock:(HTTPRequestCompletionHandler)completionHandler 91 | { 92 | MSURLSessionDataTask *dataTask = [httpClient dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 93 | completionHandler(data, response, error); 94 | }]; 95 | [dataTask execute]; 96 | } 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/GraphTasks/MSPageIterator.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | 7 | /* 8 | This class is designed to ease the process of iterating through paged responses. 9 | */ 10 | 11 | #import "MSHTTPClient.h" 12 | 13 | // Block to be called while iterating through the page 14 | typedef void (^MSPageIteratorBlock)(NSDictionary *itemDictionary, BOOL *stop); 15 | 16 | @interface MSPageIterator : NSObject 17 | 18 | // Boolean property indicating whether all the pages have been iterated. 19 | @property (nonatomic, readonly) BOOL isComplete; 20 | 21 | /* 22 | Initializes and returns an instance of MSPageIterator class 23 | 24 | @param data Instance of NSData which will be used to populate the values and next link 25 | @param httpClient Instance of MSHTTPClient which will be used to fetch values from next link URL. 26 | @param iteratorBlock Block to be executed while iterating through the values 27 | @return MSPageIterator instance 28 | */ 29 | - (instancetype)initWithData:(NSData *)data client:(MSHTTPClient *)httpClient andIteratorBlock:(MSPageIteratorBlock)iteratorBlock; 30 | 31 | // This method starts the iteration through the page values. 32 | - (void)iterate; 33 | @end 34 | 35 | 36 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/GraphTasks/MSPageIterator.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSPageIterator.h" 6 | #import "MSURLSessionDataTask.h" 7 | 8 | @interface MSPageIterator() 9 | 10 | @property (nonatomic, strong) MSPageIteratorBlock iteratorCompletionBlock; 11 | @property (nonatomic, strong) NSDictionary *dataDictionary; 12 | @property (nonatomic, strong) MSHTTPClient *httpClient; 13 | @property (nonatomic, strong) MSURLSessionDataTask *dataTask; 14 | 15 | @end 16 | 17 | @implementation MSPageIterator 18 | @synthesize isComplete; 19 | 20 | - (instancetype)initWithData:(nonnull NSData *)data client:(nonnull MSHTTPClient *)httpClient andIteratorBlock:(nonnull MSPageIteratorBlock)iteratorBlock 21 | { 22 | self = [super init]; 23 | if(self) 24 | { 25 | NSParameterAssert(data); 26 | NSParameterAssert(httpClient); 27 | NSParameterAssert(iteratorBlock); 28 | 29 | isComplete = NO; 30 | _dataDictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]; 31 | _httpClient = httpClient; 32 | _iteratorCompletionBlock = iteratorBlock; 33 | } 34 | return self; 35 | } 36 | 37 | - (void)iterate 38 | { 39 | BOOL stop = NO; 40 | for (NSDictionary *dictionary in [self.dataDictionary objectForKey:@"value"]) 41 | { 42 | _iteratorCompletionBlock(dictionary, &stop); 43 | if (stop) 44 | { 45 | break; 46 | } 47 | } 48 | if(![self.dataDictionary objectForKey:@"@odata.nextLink"] || 49 | [[self.dataDictionary objectForKey:@"@odata.nextLink"] isEqualToString:@""]) 50 | { 51 | stop = YES; 52 | isComplete = YES; 53 | _iteratorCompletionBlock(nil, &stop); 54 | }else if(!stop) 55 | { 56 | [self createNextPageTask]; 57 | [self fetchNextPage]; 58 | } 59 | } 60 | 61 | - (void)fetchNextPage 62 | { 63 | [_dataTask execute]; 64 | } 65 | 66 | - (void)createNextPageTask 67 | { 68 | NSString *nextPageURLString = [self.dataDictionary objectForKey:@"@odata.nextLink"]; 69 | _dataTask = [_httpClient dataTaskWithRequest:[NSMutableURLRequest requestWithURL:[NSURL URLWithString:nextPageURLString]] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 70 | if(!error && [(NSHTTPURLResponse *)response statusCode] == 200) 71 | { 72 | self->_dataDictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]; 73 | [self iterate]; 74 | } 75 | }]; 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/HTTPClient/MSClientFactory.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSHTTPClient.h" 7 | #import "MSAuthenticationProvider.h" 8 | 9 | @interface MSClientFactory : NSObject 10 | 11 | /* 12 | Initializes and returns an instance of MSHTTPClient class with a default chain of middleware to handle the HTTP calls. 13 | 14 | @param authenticationProvider Instance of the class which implements the methods of MSAuthenticationProvider 15 | @return MSHTTPClient instance 16 | */ 17 | 18 | +(MSHTTPClient *)createHTTPClientWithAuthenticationProvider:(id)authenticationProvider; 19 | 20 | /* 21 | Initializes and returns an instance of MSHTTPClient class with a default chain of middleware to handle the HTTP calls. 22 | 23 | @param authenticationProvider Instance of the class which implements the methods of MSAuthenticationProvider 24 | @param sessionConfiguration Instance of NSURLSessionConfiguration which will be used to create the NSURLSession for this client Instance. 25 | @return MSHTTPClient instance 26 | */ 27 | +(MSHTTPClient *)createHTTPClientWithAuthenticationProvider:(id)authenticationProvider andSessionConfiguration:(NSURLSessionConfiguration *)sessionConfiguration; 28 | /* 29 | Initializes and returns an instance of MSHTTPClient class with a custom chain of middleware to handle the HTTP calls. 30 | 31 | @param middleware Instance of a class which will be the first node in the custom chain of middleware. 32 | @return MSHTTPClient instance 33 | */ 34 | 35 | +(MSHTTPClient *)createHTTPClientWithMiddleware:(id)middleware; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/HTTPClient/MSClientFactory.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSClientFactory.h" 6 | #import "MSAuthenticationHandler.h" 7 | #import "MSURLSessionManager.h" 8 | #import "MSMiddlewareFactory.h" 9 | #import "MSRedirectHandler.h" 10 | #import "MSRetryHandler.h" 11 | 12 | @implementation MSClientFactory 13 | 14 | +(MSHTTPClient *)createHTTPClientWithAuthenticationProvider:(id)authenticationProvider 15 | { 16 | NSParameterAssert(authenticationProvider); 17 | 18 | //Creating a default chain of middlewares starting from Authentication 19 | 20 | //Initializing different default middlewares 21 | MSAuthenticationHandler *authenticationHandler = (MSAuthenticationHandler *)[MSMiddlewareFactory createMiddleware:MSMiddlewareTypeAuthentication]; 22 | authenticationHandler.authenticationProvider = authenticationProvider; 23 | MSRedirectHandler *redirectHandler = (MSRedirectHandler *)[MSMiddlewareFactory createMiddleware:MSMiddlewareTypeRedirect]; 24 | MSRetryHandler *retryHandler = (MSRetryHandler *)[MSMiddlewareFactory createMiddleware:MSMiddlewareTypeRetry]; 25 | MSURLSessionManager *sessionManager = (MSURLSessionManager *)[MSMiddlewareFactory createMiddleware:MSMiddlewareTypeHTTP]; 26 | //Creating a default chain 27 | [authenticationHandler setNext:redirectHandler]; 28 | [redirectHandler setNext:retryHandler]; 29 | [retryHandler setNext:sessionManager]; 30 | 31 | return [MSClientFactory createHTTPClientWithMiddleware:authenticationHandler]; 32 | } 33 | 34 | +(MSHTTPClient *)createHTTPClientWithAuthenticationProvider:(id)authenticationProvider andSessionConfiguration:(NSURLSessionConfiguration *)sessionConfiguration 35 | { 36 | NSParameterAssert(authenticationProvider); 37 | NSParameterAssert(sessionConfiguration); 38 | 39 | //Creating a default chain of middlewares starting from Authentication 40 | 41 | //Initializing different default middlewares 42 | MSAuthenticationHandler *authenticationHandler = (MSAuthenticationHandler *)[MSMiddlewareFactory createMiddleware:MSMiddlewareTypeAuthentication]; 43 | authenticationHandler.authenticationProvider = authenticationProvider; 44 | MSRedirectHandler *redirectHandler = (MSRedirectHandler *)[MSMiddlewareFactory createMiddleware:MSMiddlewareTypeRedirect]; 45 | MSRetryHandler *retryHandler = (MSRetryHandler *)[MSMiddlewareFactory createMiddleware:MSMiddlewareTypeRetry]; 46 | 47 | //Create session manager with custom session configuration 48 | MSURLSessionManager *sessionManager = [[MSURLSessionManager alloc] initWithSessionConfiguration:sessionConfiguration]; 49 | 50 | //Creating a default chain 51 | [authenticationHandler setNext:redirectHandler]; 52 | [redirectHandler setNext:retryHandler]; 53 | [retryHandler setNext:sessionManager]; 54 | 55 | return [MSClientFactory createHTTPClientWithMiddleware:authenticationHandler]; 56 | } 57 | 58 | +(MSHTTPClient *)createHTTPClientWithMiddleware:(id)middleware 59 | { 60 | NSParameterAssert(middleware); 61 | 62 | MSHTTPClient *httpClient = [[MSHTTPClient alloc] init]; 63 | [httpClient setMiddleware:middleware]; 64 | return httpClient; 65 | } 66 | 67 | @end 68 | 69 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/HTTPClient/MSHTTPClient.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSGraphMiddleware.h" 7 | 8 | @class MSURLSessionDataTask, MSURLSessionDownloadTask, MSURLSessionUploadTask; 9 | 10 | /** 11 | Completion handler to be called from MSHTTPClient on download completion. 12 | */ 13 | typedef void (^MSRawDownloadCompletionHandler)(NSURL *location, NSURLResponse *response, NSError *error); 14 | 15 | /** 16 | Completion handler to be called from MSHTTPClient on upload completion. 17 | */ 18 | typedef void (^MSRawUploadCompletionHandler)(NSData *data, NSURLResponse *response, NSError *error); 19 | 20 | /** 21 | Completion handler to be called form MSHTTPClient on a data task completion. 22 | */ 23 | typedef void (^MSDataCompletionHandler)(NSData *data, NSURLResponse *response, NSError *error); 24 | 25 | /* 26 | This class holds the entry point to middleware chain and exposes methods for making different session tasks. 27 | */ 28 | @interface MSHTTPClient : NSObject 29 | 30 | @property (strong, nonatomic) id middleware; 31 | 32 | /** 33 | Creates an MSURLSessionDataTask ready to be executed. 34 | @param request The request that should be sent. 35 | @param completionHandler The completion handler to be called on completion. It may be nil. 36 | @return The MSURLSessionDataTask ready to be executed. 37 | */ 38 | 39 | - (MSURLSessionDataTask *) dataTaskWithRequest:(nonnull NSMutableURLRequest *)request 40 | completionHandler:(MSDataCompletionHandler)completionHandler; 41 | 42 | /** 43 | Creates an MSURLSessionDownloadTask ready to be executed. 44 | @param request The request that should be sent. 45 | @param completionHandler The completion handler to be called on completion. It may be nil. 46 | @return The MSURLSessionDownloadTask ready to be executed. 47 | */ 48 | 49 | - (MSURLSessionDownloadTask *)downloadTaskWithRequest:(nonnull NSMutableURLRequest *)request completionHandler:(MSRawDownloadCompletionHandler)completionHandler; 50 | 51 | /** 52 | Creates an MSURLSessionUploadTask ready to be executed. 53 | @param request The request that should be sent. 54 | @param bodyData The data to be uploaded 55 | @param completionHandler The completion handler to be called on completion. It may be nil. 56 | @return The MSURLSessionUploadTask ready to be executed. 57 | */ 58 | 59 | - (MSURLSessionUploadTask *)uploadTaskWithRequest:(nonnull NSMutableURLRequest *)request fromData:(nonnull NSData *)bodyData completionHandler:(MSRawUploadCompletionHandler)completionHandler; 60 | 61 | /** 62 | Creates an MSURLSessionUploadTask ready to be executed. 63 | @param request The request that should be sent. 64 | @param fileURL The file to upload 65 | @param completionHandler The completion handler to be called on completion. It may be nil. 66 | @return The MSURLSessionUploadTask ready to be executed. 67 | */ 68 | 69 | - (MSURLSessionUploadTask *)uploadTaskWithRequest:(nonnull NSMutableURLRequest *)request fromFile:(nonnull NSURL *)fileURL completionHandler:(MSRawUploadCompletionHandler)completionHandler; 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/HTTPClient/MSHTTPClient.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSHTTPClient.h" 6 | #import "MSAuthenticationProvider.h" 7 | #import "MSURLSessionDataTask.h" 8 | #import "MSURLSessionDownloadTask.h" 9 | #import "MSURLSessionUploadTask.h" 10 | 11 | @implementation MSHTTPClient 12 | 13 | - (MSURLSessionDataTask *)dataTaskWithRequest:(NSMutableURLRequest *)request completionHandler:(MSDataCompletionHandler)completionHandler 14 | { 15 | MSURLSessionDataTask *dataTask = [[MSURLSessionDataTask alloc] initWithRequest:request client:self completion:completionHandler]; 16 | return dataTask; 17 | } 18 | 19 | - (MSURLSessionDownloadTask *)downloadTaskWithRequest:(NSMutableURLRequest *)request completionHandler:(MSRawDownloadCompletionHandler)completionHandler 20 | { 21 | MSURLSessionDownloadTask *downloadTask = [[MSURLSessionDownloadTask alloc] initWithRequest:request client:self completionHandler:completionHandler]; 22 | return downloadTask; 23 | } 24 | 25 | - (MSURLSessionUploadTask *)uploadTaskWithRequest:(NSMutableURLRequest *)request fromData:(nonnull NSData *)bodyData completionHandler:(MSRawUploadCompletionHandler)completionHandler 26 | { 27 | MSURLSessionUploadTask *uploadTask = [[MSURLSessionUploadTask alloc] initWithRequest:request data:bodyData client:self completionHandler:completionHandler]; 28 | return uploadTask; 29 | } 30 | 31 | - (MSURLSessionUploadTask *)uploadTaskWithRequest:(NSMutableURLRequest *)request fromFile:(nonnull NSURL *)fileURL completionHandler:(MSRawUploadCompletionHandler)completionHandler 32 | { 33 | MSURLSessionUploadTask *uploadTask = [[MSURLSessionUploadTask alloc] initWithRequest:request fromFile:fileURL client:self completionHandler:completionHandler]; 34 | return uploadTask; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/HTTPClient/MSMiddlewareFactory.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSGraphMiddleware.h" 7 | 8 | @interface MSMiddlewareFactory : NSObject 9 | 10 | /* 11 | Defines the different types of middleware options 12 | */ 13 | typedef NS_ENUM(NSInteger, MSMiddlewareType) 14 | { 15 | MSMiddlewareTypeAuthentication, 16 | MSMiddlewareTypeHTTP, 17 | MSMiddlewareTypeRedirect, 18 | MSMiddlewareTypeRetry 19 | }; 20 | 21 | /* 22 | Creates and returns an instance of middleware. 23 | @param middlewareType Type of middleware which this method will create 24 | @return The middleware object of given type. 25 | */ 26 | +(id)createMiddleware:(MSMiddlewareType)middlewareType; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/HTTPClient/MSMiddlewareFactory.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSMiddlewareFactory.h" 6 | #import "MSURLSessionManager.h" 7 | #import "MSAuthenticationHandler.h" 8 | #import "MSRedirectHandler.h" 9 | #import "MSRetryHandler.h" 10 | 11 | @implementation MSMiddlewareFactory 12 | 13 | +(id)createMiddleware:(MSMiddlewareType)middlewareType 14 | { 15 | switch (middlewareType) 16 | { 17 | case MSMiddlewareTypeHTTP: 18 | { 19 | MSURLSessionManager *sessionManager = [[MSURLSessionManager alloc] init]; 20 | return sessionManager; 21 | } 22 | case MSMiddlewareTypeRedirect: 23 | { 24 | MSRedirectHandler *redirectHandler = [[MSRedirectHandler alloc] init]; 25 | return redirectHandler; 26 | } 27 | case MSMiddlewareTypeAuthentication: 28 | { 29 | MSAuthenticationHandler *authenticationHandler = [[MSAuthenticationHandler alloc] init]; 30 | return authenticationHandler; 31 | } 32 | case MSMiddlewareTypeRetry: 33 | { 34 | MSRetryHandler *retryHandler = [[MSRetryHandler alloc] init]; 35 | return retryHandler; 36 | } 37 | default: 38 | break; 39 | } 40 | return nil; 41 | } 42 | @end 43 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/MSGraphClientSDK.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | 7 | //! Project version number for MSGraphClientSDK. 8 | FOUNDATION_EXPORT double MSGraphClientSDKVersionNumber; 9 | 10 | //! Project version string for MSGraphClientSDK. 11 | FOUNDATION_EXPORT const unsigned char MSGraphClientSDKVersionString[]; 12 | 13 | // In this header, you should import all the public headers of your framework using statements like #import 14 | 15 | 16 | 17 | #ifndef MSSDK_h 18 | #define MSSDK_h 19 | 20 | #import "MSGraphClientSDK/MSAuthenticationProvider.h" 21 | #import "MSGraphClientSDK/MSAuthenticationProviderOptions.h" 22 | #import "MSGraphClientSDK/MSHttpProvider.h" 23 | #import "MSGraphClientSDK/MSGraphMiddleware.h" 24 | #import "MSGraphClientSDK/MSMiddlewareOptions.h" 25 | 26 | #import "MSGraphClientSDK/MSURLSessionManager.h" 27 | #import "MSGraphClientSDK/MSClientFactory.h" 28 | #import "MSGraphClientSDK/MSMiddlewareFactory.h" 29 | #import "MSGraphClientSDK/MSConstants.h" 30 | #import "MSGraphClientSDK/MSURLSessionTaskDelegate.h" 31 | #import "MSGraphClientSDK/MSAuthenticationHandler.h" 32 | #import "MSGraphClientSDK/MSRedirectHandler.h" 33 | #import "MSGraphClientSDK/MSRetryHandler.h" 34 | 35 | #import "MSGraphClientSDK/MSURLSessionTask.h" 36 | #import "MSGraphClientSDK/MSURLSessionDataTask.h" 37 | #import "MSGraphClientSDK/MSURLSessionDownloadTask.h" 38 | #import "MSGraphClientSDK/MSURLSessionUploadTask.h" 39 | 40 | #import "MSGraphClientSDK/MSErrorCodes.h" 41 | #import "MSGraphClientSDK/MSBatchRequestStep.h" 42 | #import "MSGraphClientSDK/MSBatchRequestContent.h" 43 | #import "MSGraphClientSDK/MSBatchResponseContent.h" 44 | 45 | #import "MSGraphClientSDK/MSRetryHandlerOptions.h" 46 | #import "MSGraphClientSDK/MSRedirectHandlerOptions.h" 47 | #import "MSGraphClientSDK/MSAuthenticationHandlerOptions.h" 48 | 49 | #import "MSGraphClientSDK/MSPageIterator.h" 50 | #import "MSGraphClientSDK/MSLargeFileUploadTask.h" 51 | #import "MSGraphClientSDK/MSGraphOneDriveLargeFileUploadTask.h" 52 | 53 | #endif 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Middleware/Implementations/Authentication/MSAuthenticationHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSAuthenticationProvider.h" 7 | #import "MSGraphMiddleware.h" 8 | 9 | /* 10 | This class provides the mechanism to communicate with authentication provider. It is implmented as a middleware so it will be called during the execution of network calls. 11 | */ 12 | 13 | @interface MSAuthenticationHandler : NSObject 14 | 15 | //Authentication provider which will be used to get access token 16 | @property (nonatomic, strong) id authenticationProvider; 17 | 18 | /* 19 | This method creates and returns an instance of MSAuthenticationHandler 20 | @param authProvider Authentication Provider instance 21 | @return An instance of MSAuthenticationHandler 22 | */ 23 | - (instancetype)initWithAuthenticationProvider:(id)authProvider; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Middleware/Implementations/Authentication/MSAuthenticationHandler.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSAuthenticationHandler.h" 6 | #import "MSURLSessionTask.h" 7 | #import "MSAuthenticationHandlerOptions.h" 8 | 9 | @interface MSURLSessionTask() 10 | 11 | - (void)setRequest:(NSMutableURLRequest *)request; 12 | 13 | @end 14 | 15 | 16 | @interface MSAuthenticationHandler() 17 | 18 | @property (nonatomic, strong) id nextMiddleware; 19 | 20 | @end 21 | 22 | @implementation MSAuthenticationHandler 23 | 24 | - (instancetype)initWithAuthenticationProvider:(id)authProvider 25 | { 26 | self = [super init]; 27 | if(self) 28 | { 29 | _authenticationProvider = authProvider; 30 | } 31 | return self; 32 | } 33 | 34 | - (void)setAuthenticationProvider:(id)authProvider 35 | { 36 | _authenticationProvider = authProvider; 37 | } 38 | 39 | - (void)execute:(MSURLSessionTask *)task withCompletionHandler:(HTTPRequestCompletionHandler)completionHandler 40 | { 41 | MSAuthenticationHandlerOptions *authHandlerOptions = [task getMiddlewareOptionWithType:MSMiddlewareOptionsTypeAuth]; 42 | 43 | id authProvider = authHandlerOptions.authenticationProvider?authHandlerOptions.authenticationProvider:_authenticationProvider; 44 | 45 | [authProvider getAccessTokenForProviderOptions:authHandlerOptions.authenticationProviderOptions andCompletion:^(NSString *accessToken, NSError *error) { 46 | if(!error) 47 | { 48 | NSMutableURLRequest *urlRequest = [task request]; 49 | [urlRequest setValue:[NSString stringWithFormat:@"Bearer %@",accessToken] forHTTPHeaderField:@"Authorization"]; 50 | [task setRequest:urlRequest]; 51 | [self.nextMiddleware execute:task withCompletionHandler:^(id data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 52 | completionHandler(data, response, error); 53 | }]; 54 | } 55 | else 56 | { 57 | completionHandler(nil, nil, error); 58 | } 59 | }]; 60 | } 61 | 62 | - (void)setNext:(id)nextMiddleware 63 | { 64 | if(_nextMiddleware) 65 | { 66 | [nextMiddleware setNext:_nextMiddleware]; 67 | } 68 | _nextMiddleware = nextMiddleware; 69 | } 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Middleware/Implementations/HTTPProvider/MSHttpProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSGraphMiddleware.h" 7 | 8 | /** 9 | Completion handler to be called from MSHttpProvider on download completion. 10 | */ 11 | typedef void (^MSRawDownloadCompletionHandler)(NSURL *location, NSURLResponse *response, NSError *error); 12 | 13 | /** 14 | Completion handler to be called from MSHttpProvider on upload completion. 15 | */ 16 | typedef void (^MSRawUploadCompletionHandler)(NSData *data, NSURLResponse *response, NSError *error); 17 | 18 | /** 19 | Completion handler to be called form MSHttpProvider on a data task completion. 20 | */ 21 | typedef void (^MSDataCompletionHandler)(NSData *data, NSURLResponse *response, NSError *error); 22 | 23 | /** 24 | The `MSHttpProvider` protocol is meant to inject all network access from MSHTTPClient. 25 | */ 26 | @protocol MSHttpProvider 27 | 28 | /** 29 | Creates an NSURLSessionDataTask ready to be resumed. 30 | @param request The request that should be sent. 31 | @param completionHandler The completion handler to be called on completion. It may be nil. 32 | @return The NSURLSessionDataTask ready to be resumed. 33 | */ 34 | - (NSURLSessionDataTask *) dataTaskWithRequest:(NSURLRequest *)request 35 | completionHandler:(MSDataCompletionHandler)completionHandler; 36 | /** 37 | Creates an NSURLSessionDataTask ready to be resumed. 38 | @param request The request that should be sent. 39 | @param progress A reference to an NSProgress object that will be updated when the download completes. It may be nil. 40 | @param completionHandler The completion handler to be called on completion. It may be nil. 41 | @return The NSURLSessionDownloadTask ready to be resumed. 42 | */ 43 | - (NSURLSessionDownloadTask *) downloadTaskWithRequest:(NSURLRequest *)request 44 | progress:(NSProgress * __autoreleasing *)progress 45 | completionHandler:(MSRawDownloadCompletionHandler)completionHandler; 46 | /** 47 | Creates an NSURLSessionUploadTask ready to be resumed. 48 | @param request The request that should be sent. 49 | @param fileURL The file to upload. 50 | @param progress A reference to an NSProgress to be updated as the upload completes. It may be nil. 51 | @param completionHandler The completion handler to be called on completion. It may be nil. 52 | @return The NSURLSessionDownloadTask ready to be resumed. 53 | */ 54 | - (NSURLSessionUploadTask *) uploadTaskWithRequest:(NSURLRequest *)request 55 | fromFile:(NSURL *)fileURL 56 | progress:(NSProgress * __autoreleasing *)progress 57 | completionHandler:(MSRawUploadCompletionHandler)completionHandler; 58 | /** 59 | Creates an NSURLSessionUploadTask ready to be resumed. 60 | @param request The request to be sent. 61 | @param data The data to be uploaded. 62 | @param progress A reference to an NSProgress to be updated as the upload completes. It may be nil. 63 | @param completionHandler The completion handler to be called on completion. It may be nil. 64 | @return The NSURLSessionDownloadTask ready to be resumed. 65 | */ 66 | - (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request 67 | fromData:(NSData *)data 68 | progress:(NSProgress * __autoreleasing *)progress 69 | completionHandler:(MSRawUploadCompletionHandler)completionHandler; 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Middleware/Implementations/HTTPProvider/MSURLSessionManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSHttpProvider.h" 6 | /** 7 | * 'MSURLSessionManager' manages all Http access from the Graph SDK, it conforms to the MSHttpProvider protocol 8 | */ 9 | @interface MSURLSessionManager : NSObject 14 | 15 | /** 16 | * Creates an instance of MSURLSessionManager with the given configuration. 17 | * @param urlSessionConfiguration the session configuration to use 18 | * @return the instance of MSURLSessionManager 19 | * @warning the MSURLSessionManager currently uses the same NSURLSession for data/download/upload tasks. 20 | * If you use a background session you must be sure to not invoke any data requests. 21 | */ 22 | - (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)urlSessionConfiguration; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Middleware/Implementations/HTTPProvider/MSURLSessionTaskDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | 7 | typedef void(^MSURLSessionTaskCompletion)(id responseObject, NSURLResponse *response, NSError *error); 8 | 9 | /** 10 | * 'MSURLSessionTaskDelegate' the delegate object for a given NSURLSessionTask 11 | */ 12 | @interface MSURLSessionTaskDelegate : NSObject 13 | 14 | /** 15 | Creates an instance of an MSURLSessionTaskDelegate 16 | @param progress an object reference to a progress 17 | @param completion a completion handler to be called when the task completes 18 | */ 19 | - (instancetype)initWithProgressRef:(NSProgress * __autoreleasing *)progress 20 | completion:(MSURLSessionTaskCompletion)completion; 21 | 22 | /** 23 | Updates the progress object with the given bytes 24 | @param sentBytes the number of bytes that have been sent currently, must not be nil. 25 | @param expectedBytes the total number of bytes that are expected to be sent, must not be nil. 26 | */ 27 | - (void)updateProgressWithBytesSent:(int64_t)sentBytes expectedBytes:(int64_t)expectedBytes; 28 | 29 | /** 30 | This method should be called when the NSURLSessionData task received any data 31 | @param data the data that was received 32 | */ 33 | - (void)didReceiveData:(NSData *)data; 34 | 35 | /** 36 | This method should be called when the task is completed 37 | @param task the task that was completed 38 | @param error any error that occurred during the task 39 | */ 40 | - (void)task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error; 41 | 42 | /** 43 | This method should be called when the download task is completed 44 | @param task the task that was completed 45 | @param downloadLocation the location of the file that was downloaded 46 | */ 47 | - (void)task:(NSURLSessionTask *)task didCompleteDownload:(NSURL *)downloadLocation; 48 | 49 | /** 50 | This method should be called when the task is redirected 51 | @param task the task that is redirected 52 | @param response the redirect response which contains the information about next request 53 | */ 54 | - (void)task:(NSURLSessionTask *)task didRedirectWithResponse:(NSURLResponse *)response; 55 | @end 56 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Middleware/Implementations/HTTPProvider/MSURLSessionTaskDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSURLSessionTaskDelegate.h" 6 | 7 | @interface MSURLSessionTaskDelegate() 8 | 9 | @property (strong, nonatomic) NSProgress *progress; 10 | 11 | @property (strong, nonatomic) NSMutableData *mutableData; 12 | 13 | @property (strong, nonatomic) NSURL *downloadPath; 14 | 15 | @property (strong, nonatomic) MSURLSessionTaskCompletion completion; 16 | 17 | @end 18 | 19 | @implementation MSURLSessionTaskDelegate 20 | 21 | - (instancetype)initWithProgressRef:(NSProgress * __autoreleasing *)progress 22 | completion:(MSURLSessionTaskCompletion)completion 23 | { 24 | self = [super init]; 25 | if (self) 26 | { 27 | if (progress) 28 | { 29 | if (!*progress) 30 | { 31 | _progress = [NSProgress progressWithTotalUnitCount:0]; 32 | *progress = _progress; 33 | } 34 | else 35 | { 36 | _progress = *progress; 37 | } 38 | } 39 | else 40 | { 41 | _progress = nil; 42 | } 43 | _mutableData = nil; 44 | _completion = completion; 45 | } 46 | return self; 47 | } 48 | 49 | 50 | - (void)updateProgressWithBytesSent:(int64_t)sentBytes expectedBytes:(int64_t)expectedByes 51 | { 52 | NSParameterAssert(sentBytes); 53 | NSParameterAssert(expectedByes); 54 | 55 | if (self.progress) 56 | { 57 | self.progress.totalUnitCount = expectedByes; 58 | self.progress.completedUnitCount = sentBytes; 59 | } 60 | 61 | } 62 | 63 | - (void)didReceiveData:(NSData *)data 64 | { 65 | if (!self.mutableData) 66 | { 67 | self.mutableData = [NSMutableData data]; 68 | } 69 | [self.mutableData appendData:data]; 70 | } 71 | 72 | - (void)task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error 73 | { 74 | if (self.downloadPath && self.completion) 75 | { 76 | self.completion(self.downloadPath, task.response, error); 77 | } 78 | else if (self.completion) 79 | { 80 | self.completion(self.mutableData, task.response, error); 81 | } 82 | } 83 | 84 | - (void)task:(NSURLSessionTask *)task didCompleteDownload:(NSURL *)downloadLocation 85 | { 86 | self.downloadPath = downloadLocation; 87 | } 88 | 89 | - (void)task:(NSURLSessionTask *)task didRedirectWithResponse:(NSURLResponse *)response 90 | { 91 | if(self.completion) 92 | { 93 | self.completion(nil, response, nil); 94 | } 95 | } 96 | 97 | @end 98 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Middleware/Implementations/RedirectHandler/MSRedirectHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | #import 5 | #import "MSGraphMiddleware.h" 6 | 7 | /* 8 | This class provides the mechanism to handle redirect response from Graph server. It is implmented as a middleware so it will be called during the execution of network calls. 9 | */ 10 | 11 | @class MSRedirectHandlerOptions; 12 | 13 | @interface MSRedirectHandler : NSObject 14 | 15 | /* 16 | This method initializes an instance of MSRedirectHandler with the provided MSRedirectHandlerOptions value. 17 | @param redirectHandlerOptions The options which will be used to control the behavior of this instance 18 | @return Instance of MSRedirectHandler 19 | */ 20 | - (instancetype)initWithOptions:(MSRedirectHandlerOptions *)redirectHandlerOptions; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Middleware/Implementations/RedirectHandler/MSRedirectHandler.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSRedirectHandler.h" 6 | #import "MSURLSessionTask.h" 7 | #import "MSConstants.h" 8 | #import "MSRedirectHandlerOptions.h" 9 | 10 | @interface MSURLSessionTask() 11 | 12 | -(void)setRequest:(NSMutableURLRequest *)request; 13 | 14 | @end 15 | 16 | 17 | @interface MSRedirectHandler() 18 | 19 | @property (nonatomic, strong) id nextMiddleware; 20 | @property (nonatomic, strong) MSRedirectHandlerOptions *redirectHandlerOptions; 21 | @end 22 | 23 | @implementation MSRedirectHandler 24 | 25 | - (instancetype)init 26 | { 27 | return [self initWithOptions:[[MSRedirectHandlerOptions alloc] init]]; 28 | } 29 | 30 | - (instancetype)initWithOptions:(MSRedirectHandlerOptions *)redirectHandlerOptions 31 | { 32 | self = [super init]; 33 | if(self) 34 | { 35 | _redirectHandlerOptions = redirectHandlerOptions; 36 | } 37 | return self; 38 | } 39 | 40 | #pragma mark - MSGraphMiddleware method implmentation 41 | - (void)execute:(MSURLSessionTask *)task withCompletionHandler:(HTTPRequestCompletionHandler)completionHandler 42 | { 43 | [self execute:task redirectsAttempted:0 withCompletionHandler:completionHandler]; 44 | } 45 | 46 | - (void)setNext:(id)nextMiddleware 47 | { 48 | if(_nextMiddleware) 49 | { 50 | [nextMiddleware setNext:_nextMiddleware]; 51 | } 52 | _nextMiddleware = nextMiddleware; 53 | } 54 | 55 | #pragma mark - Redirect handler methods 56 | - (void)execute:(MSURLSessionTask *)task redirectsAttempted:(NSInteger)redirectsAttempted withCompletionHandler:(HTTPRequestCompletionHandler)completionHandler 57 | { 58 | __block NSInteger localRedirectsAttempted = redirectsAttempted; 59 | __block MSURLSessionTask *blockTask = task; 60 | __block MSRedirectHandlerOptions *localRedirectHandlerOptions = [task getMiddlewareOptionWithType:MSMiddlewareOptionsTypeRedirect]; 61 | 62 | if(!localRedirectHandlerOptions) 63 | { 64 | localRedirectHandlerOptions = _redirectHandlerOptions; 65 | } 66 | [self.nextMiddleware execute:blockTask withCompletionHandler:^(id data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 67 | if(response && [response isKindOfClass:[NSHTTPURLResponse class]]) 68 | { 69 | if([self isRedirect:[(NSHTTPURLResponse *)response statusCode]]) 70 | { 71 | //Return the response if maxRedirects allowed are 0 i.e. consumer does not want to redirect 72 | if(localRedirectHandlerOptions.maxRedirects==0) 73 | { 74 | completionHandler(data, response, error); 75 | return ; 76 | } 77 | 78 | if(localRedirectsAttempted==localRedirectHandlerOptions.maxRedirects) 79 | { 80 | NSDictionary *userInfo = @{ 81 | NSLocalizedDescriptionKey: MSErrorOperationUnsuccessfulString, 82 | NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:MSErrorTooManyRedirectsFormatString,localRedirectsAttempted] 83 | }; 84 | completionHandler(data, response, [NSError errorWithDomain:MSErrorDomain code:[(NSHTTPURLResponse *)response statusCode] userInfo:userInfo]); 85 | return ; 86 | } 87 | NSMutableURLRequest *originalRequest = blockTask.request; 88 | NSDictionary *headerDictionary =[(NSHTTPURLResponse *)response allHeaderFields]; 89 | 90 | NSString *newUrlString =[headerDictionary valueForKey:@"Location"]; 91 | if(!newUrlString) 92 | { 93 | NSDictionary *userInfo = @{ 94 | NSLocalizedDescriptionKey: MSErrorOperationUnsuccessfulString, 95 | NSLocalizedFailureReasonErrorKey: MSErrorLocationHeaderNotFoundString 96 | }; 97 | completionHandler(data, response, [NSError errorWithDomain:MSErrorDomain code:[(NSHTTPURLResponse *)response statusCode] userInfo:userInfo]); 98 | return ; 99 | } 100 | 101 | NSMutableURLRequest *newRequest = [originalRequest mutableCopy]; 102 | [newRequest setURL:[NSURL URLWithString:newUrlString]]; 103 | 104 | //If the authority of request has changed then we need to remove access token from request headers. 105 | BOOL shouldRemoveAccessToken = [self shouldRemoveAccessTokenOfRequest:newRequest withRespectToOriginalRequest:originalRequest]; 106 | if (shouldRemoveAccessToken) 107 | { 108 | [newRequest setValue:nil forHTTPHeaderField:@"Authorization"]; 109 | } 110 | // status code == 303: change request method from post to get and content to be null 111 | if([(NSHTTPURLResponse *)response statusCode]==MSExpectedResponseCodesSeeOther) 112 | { 113 | [newRequest setHTTPBody:nil]; 114 | [newRequest setHTTPMethod:@"GET"]; 115 | } 116 | [blockTask setRequest:newRequest]; 117 | localRedirectsAttempted++; 118 | BOOL shouldRedirect = YES; 119 | if(localRedirectHandlerOptions.redirectHandlerDelegate && [localRedirectHandlerOptions.redirectHandlerDelegate respondsToSelector:@selector(task:shouldRedirectForResponse:)]) 120 | { 121 | shouldRedirect = [localRedirectHandlerOptions.redirectHandlerDelegate task:blockTask shouldRedirectForResponse:response]; 122 | } 123 | if(shouldRedirect) 124 | { 125 | [self execute:blockTask redirectsAttempted:localRedirectsAttempted withCompletionHandler:completionHandler]; 126 | }else 127 | { 128 | completionHandler(data, response, error); 129 | } 130 | } 131 | else 132 | { 133 | completionHandler(data, response, error); 134 | } 135 | 136 | } 137 | else{ 138 | completionHandler(data, response, error); 139 | } 140 | }]; 141 | } 142 | 143 | - (BOOL)isRedirect:(NSInteger)statusCode 144 | { 145 | if (statusCode == MSExpectedResponseCodesMovedPermanantly || 146 | statusCode == MSExpectedResponseCodesFound || 147 | statusCode == MSExpectedResponseCodesSeeOther || 148 | statusCode == MSExpectedResponseCodesTemporaryRedirect || 149 | statusCode == 308) 150 | { 151 | return true; 152 | } 153 | return false; 154 | } 155 | 156 | - (BOOL)shouldRemoveAccessTokenOfRequest:(NSMutableURLRequest *)newRequest withRespectToOriginalRequest:(NSURLRequest *)originalRequest 157 | { 158 | if( [newRequest.URL.host caseInsensitiveCompare:originalRequest.URL.host] != NSOrderedSame || 159 | ![newRequest.URL.scheme isEqualToString:originalRequest.URL.scheme]) 160 | { 161 | return YES; 162 | } 163 | return NO; 164 | } 165 | 166 | @end 167 | 168 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Middleware/Implementations/RetryHandler/MSRetryHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSGraphMiddleware.h" 7 | 8 | /* 9 | This class provides the mechanism to handle retry response codes from Graph server. It is implmented as a middleware so it will be called during the execution of network calls. 10 | */ 11 | 12 | @class MSRetryHandlerOptions; 13 | 14 | @interface MSRetryHandler : NSObject 15 | 16 | /* 17 | This method initializes an instance of MSRetryHandler with the provided MSRetryHandlerOptions value. 18 | @param retryHandlerOptions The options which will be used to control the behavior of this instance 19 | @return Instance of MSRetryHandler 20 | */ 21 | - (instancetype)initWithOptions:(MSRetryHandlerOptions *)retryHandlerOptions; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Middleware/Implementations/RetryHandler/MSRetryHandler.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSRetryHandler.h" 6 | #import "MSURLSessionTask.h" 7 | #import "MSConstants.h" 8 | #import "MSRetryHandlerOptions.h" 9 | 10 | NSString * const RETRY_AFTER = @"Retry-After"; 11 | NSString * const RETRY_ATTEMPT = @"Retry-Attempt"; 12 | NSString * const TRANSFER_ENCODING = @"Transfer-Encoding"; 13 | 14 | @interface MSURLSessionTask() 15 | 16 | -(void)setRequest:(NSMutableURLRequest *)request; 17 | 18 | @end 19 | 20 | @interface MSRetryHandler() 21 | 22 | @property (nonatomic, strong) id nextMiddleware; 23 | @property (nonatomic, strong) MSRetryHandlerOptions *retryHandlerOptions; 24 | 25 | @end 26 | 27 | @implementation MSRetryHandler 28 | 29 | - (instancetype)init 30 | { 31 | return [self initWithOptions:[[MSRetryHandlerOptions alloc] init]]; 32 | } 33 | 34 | - (instancetype)initWithOptions:(MSRetryHandlerOptions *)retryHandlerOptions 35 | { 36 | self = [super init]; 37 | if(self) 38 | { 39 | _retryHandlerOptions = retryHandlerOptions; 40 | } 41 | return self; 42 | } 43 | 44 | #pragma mark - MSGraphMiddleware method implmentation 45 | - (void)execute:(MSURLSessionTask *)task withCompletionHandler:(HTTPRequestCompletionHandler)completionHandler 46 | { 47 | [self execute:task retriesAttempted:0 withCompletionHandler:completionHandler]; 48 | } 49 | 50 | - (void)setNext:(id)nextMiddleware 51 | { 52 | if(_nextMiddleware) 53 | { 54 | [nextMiddleware setNext:_nextMiddleware]; 55 | } 56 | _nextMiddleware = nextMiddleware; 57 | 58 | } 59 | 60 | #pragma mark - Retry Handler methods 61 | - (void)execute:(MSURLSessionTask *)task retriesAttempted:(NSInteger)retriesAttempted withCompletionHandler:(HTTPRequestCompletionHandler)completionHandler 62 | { 63 | __block NSInteger localRetriesAttempted = retriesAttempted; 64 | __block MSURLSessionTask *blockTask = task; 65 | __block MSRetryHandlerOptions *localRetryHandlerOptions = [task getMiddlewareOptionWithType:MSMiddlewareOptionsTypeRetry]; 66 | 67 | if(!localRetryHandlerOptions) 68 | { 69 | localRetryHandlerOptions = _retryHandlerOptions; 70 | } 71 | 72 | [self.nextMiddleware execute:blockTask withCompletionHandler:^(id data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 73 | if(response && [response isKindOfClass:[NSHTTPURLResponse class]]) 74 | { 75 | if([self isRetry:[(NSHTTPURLResponse *)response statusCode]] && [self isBuffered:blockTask.request forResponse:(NSHTTPURLResponse *)response]) 76 | { 77 | //Return the response if maxRetries allowed are 0 i.e. consumer does not want to retry 78 | if(localRetryHandlerOptions.maxRetries==0) 79 | { 80 | completionHandler(data, response, error); 81 | return ; 82 | } 83 | //Return an error if maximum retry attempt limit is reached 84 | if(localRetriesAttempted==localRetryHandlerOptions.maxRetries) 85 | { 86 | NSDictionary *userInfo = @{ 87 | NSLocalizedDescriptionKey: MSErrorTooManyRetries, 88 | NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:MSErrorTooManyRetriesFormatString,(long)localRetriesAttempted] 89 | }; 90 | completionHandler(data, response, [NSError errorWithDomain:MSErrorDomain code:[(NSHTTPURLResponse *)response statusCode] userInfo:userInfo]); 91 | return ; 92 | } 93 | 94 | //Get the delay before next retry attempt 95 | double delay = [self retryDelay:(NSHTTPURLResponse *)response andRetryCount:localRetriesAttempted forOptionsDelay:localRetryHandlerOptions.delay]; 96 | 97 | localRetriesAttempted++; 98 | 99 | //Set Retry-Attempt header on request to track how many requests were made via retry handler 100 | [blockTask setRequest:[self updateRetryAttemptHeader:blockTask.request withRetryAttemptCount:localRetriesAttempted]]; 101 | 102 | BOOL shouldRetry = YES; 103 | if(localRetryHandlerOptions.retryHandlerDelegate && [localRetryHandlerOptions.retryHandlerDelegate respondsToSelector:@selector(task:shouldRetryAfter:retryAttempt:forResponse:)]){ 104 | shouldRetry = [localRetryHandlerOptions.retryHandlerDelegate task:blockTask shouldRetryAfter:delay retryAttempt:localRetriesAttempted forResponse:response]; 105 | } 106 | if(shouldRetry){ 107 | //Dispatch the execution of next retry on Global queue after the delay 108 | dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC); 109 | dispatch_after(popTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){ 110 | //code to be executed on the global queue after delay 111 | [self execute:blockTask retriesAttempted:localRetriesAttempted withCompletionHandler:completionHandler]; 112 | }); 113 | } 114 | else{ 115 | completionHandler(data,response,error); 116 | } 117 | } 118 | else 119 | { 120 | completionHandler(data, response, error); 121 | } 122 | } 123 | else 124 | { 125 | completionHandler(data, response, error); 126 | } 127 | }]; 128 | } 129 | 130 | - (BOOL)isRetry:(NSInteger)statusCode 131 | { 132 | if (statusCode == MSClientErrorCodeTooManyRequests || 133 | statusCode == MSClientErrorCodeServiceUnavailable || 134 | statusCode == MSClientErrorCodeGatewayTimeout) 135 | { 136 | return true; 137 | } 138 | return false; 139 | } 140 | 141 | - (BOOL)isBuffered:(NSURLRequest *)request forResponse:(NSHTTPURLResponse *)response 142 | { 143 | NSData *requestBody = request.HTTPBody; 144 | 145 | BOOL isTransferEncodingChunked = [response.allHeaderFields valueForKey:TRANSFER_ENCODING] && [[response.allHeaderFields valueForKey:TRANSFER_ENCODING] isEqualToString:@"chunked"]; 146 | 147 | BOOL isHTTPMethodPutPatchOrPost = ([request.HTTPMethod isEqualToString:HTTPMethodPut] || [request.HTTPMethod isEqualToString:HTTPMethodPatch] || [request.HTTPMethod isEqualToString:HTTPMethodPost]); 148 | 149 | if(isHTTPMethodPutPatchOrPost && requestBody && isTransferEncodingChunked) 150 | { 151 | return false; 152 | } 153 | return true; 154 | } 155 | 156 | - (double)retryDelay:(NSHTTPURLResponse *)response andRetryCount:(NSInteger)retryCount forOptionsDelay:(NSInteger)optionsDelay 157 | { 158 | double delay = 0; 159 | 160 | NSDictionary *responseHeaders = [response allHeaderFields]; 161 | if(responseHeaders && [responseHeaders objectForKey:RETRY_AFTER]) 162 | { 163 | delay = [[responseHeaders objectForKey:RETRY_AFTER] doubleValue]; 164 | } 165 | else 166 | { 167 | delay = retryCount==0 ? optionsDelay : pow(2, retryCount)+optionsDelay; 168 | delay = delay>180 ? 180 : delay; 169 | } 170 | return delay; 171 | } 172 | 173 | - (NSMutableURLRequest *)updateRetryAttemptHeader:(NSMutableURLRequest *)request withRetryAttemptCount:(NSInteger)retryAttempt 174 | { 175 | [request setValue:[NSString stringWithFormat:@"%ld",(long)retryAttempt] forHTTPHeaderField:RETRY_ATTEMPT]; 176 | return request; 177 | } 178 | 179 | @end 180 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Middleware/Options/MSAuthenticationHandlerOptions.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSMiddlewareOptions.h" 7 | #import "MSAuthenticationProvider.h" 8 | #import "MSAuthenticationProviderOptions.h" 9 | /* 10 | This class provides options to control the behaviour of Authentication Handler. 11 | */ 12 | 13 | @interface MSAuthenticationHandlerOptions : NSObject 14 | 15 | /* 16 | Authentication Provider instance which will be used to authenticate the ongoing requests. 17 | */ 18 | @property (nonatomic, strong, readonly) id authenticationProvider; 19 | 20 | @property (nonatomic, strong, readonly) id authenticationProviderOptions; 21 | 22 | /* 23 | This method initializes an instance of MSAuthenticationHandlerOptions with the provided parameter. 24 | @param authProvider The authentication provider instance which will be used to authenticate the ongoing requests. 25 | @param authProviderOptions The authentication provider options which will be used to control the behaviour of authentication provider being used to authenticate the ongoing requests. 26 | @return The MSAuthenticationHandlerOptions instance with the provided value. 27 | */ 28 | - (instancetype)initWithAuthenticationProvider:(id)authProvider andAuthProviderOptions:(id)authProviderOptions; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Middleware/Options/MSAuthenticationHandlerOptions.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | 6 | #import "MSAuthenticationHandlerOptions.h" 7 | 8 | @implementation MSAuthenticationHandlerOptions 9 | 10 | @synthesize middlewareOptionsType; 11 | 12 | - (instancetype)initWithAuthenticationProvider:(id)authProvider andAuthProviderOptions:(id)authProviderOptions 13 | { 14 | self = [super init]; 15 | if(self) 16 | { 17 | _authenticationProvider = authProvider; 18 | _authenticationProviderOptions = authProviderOptions; 19 | middlewareOptionsType = MSMiddlewareOptionsTypeAuth; 20 | } 21 | return self; 22 | } 23 | 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Middleware/Options/MSMiddlewareOptions.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | /* 6 | This protocol defines the requirements to be implemented by the Classes which will define the middleware options. 7 | */ 8 | 9 | #import 10 | #import "MSConstants.h" 11 | 12 | @protocol MSMiddlewareOptions 13 | 14 | @required 15 | 16 | /* 17 | This property is added to ensure that every option class sets the type of it so that during execution middlewares can pick up the option which is requried by it's implementation. 18 | */ 19 | @property MSMiddlewareOptionsType middlewareOptionsType; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Middleware/Options/MSRedirectHandlerOptions.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSMiddlewareOptions.h" 7 | 8 | @class MSURLSessionTask; 9 | 10 | /* 11 | Methods in this protocol keep you updated with the information that Redirect Handler might throw. 12 | */ 13 | @protocol MSRedirectHandlerDelegate 14 | 15 | @optional 16 | - (BOOL)task:(MSURLSessionTask *)task shouldRedirectForResponse:(NSURLResponse *)response; 17 | 18 | @end 19 | 20 | /* 21 | This class provides options to control the behaviour of Redirect Handler. 22 | */ 23 | @interface MSRedirectHandlerOptions : NSObject 24 | 25 | /* 26 | This property is to hold a reference to the class which will implement the Redirect Handler Delegate 27 | */ 28 | @property (nonatomic, weak) id redirectHandlerDelegate; 29 | 30 | /* 31 | If we keep getting the redirect response codes, then this is the Maximum number of redirects which will be done before finising the execution of a request. Upper limit is 20. 32 | */ 33 | @property (nonatomic, readonly ) NSInteger maxRedirects; 34 | 35 | /* 36 | This method initializes an instance of MSRedirectHandlerOptions with the provided parameters. 37 | @param maxRedirects The maximum number of redirects that can be performed in case we keep on getting redirect response codes 38 | @param error If any error is encountered during the initalization, it will be assigned to this address. 39 | @return The MSRedirectHandlerOptions instance with the provided values. 40 | */ 41 | - (instancetype)initWithMaxRedirects:(NSInteger)maxRedirects andError:(NSError **)error; 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Middleware/Options/MSRedirectHandlerOptions.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSRedirectHandlerOptions.h" 6 | 7 | #define UPPER_LIMIT_FOR_REDIRECTS 20 8 | 9 | @implementation MSRedirectHandlerOptions 10 | 11 | @synthesize middlewareOptionsType; 12 | 13 | - (instancetype)init 14 | { 15 | return [self initWithMaxRedirects:5 andError:nil]; 16 | } 17 | 18 | - (instancetype)initWithMaxRedirects:(NSInteger)maxRedirects andError:(NSError *__autoreleasing *)error 19 | { 20 | self = [super init]; 21 | if(self) 22 | { 23 | if(maxRedirects>UPPER_LIMIT_FOR_REDIRECTS) 24 | { 25 | NSDictionary *userInfo = @{ 26 | NSLocalizedDescriptionKey: MSErrorOperationUnsuccessfulString, 27 | NSLocalizedFailureReasonErrorKey:[NSString stringWithFormat:MSErrorMaxRedirectsLimitExceededString,UPPER_LIMIT_FOR_REDIRECTS] 28 | }; 29 | *error = [NSError errorWithDomain:MSErrorDomain code:-1 userInfo:userInfo]; 30 | return nil; 31 | } 32 | _maxRedirects = maxRedirects; 33 | middlewareOptionsType = MSMiddlewareOptionsTypeRedirect; 34 | } 35 | return self; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Middleware/Options/MSRetryHandlerOptions.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSMiddlewareOptions.h" 7 | 8 | @class MSURLSessionTask; 9 | 10 | /* 11 | Methods in this protocol keep you updated with the information that Retry Handler might throw. 12 | */ 13 | @protocol MSRetryHandlerDelegate 14 | 15 | @optional 16 | - (BOOL)task:(MSURLSessionTask *)task shouldRetryAfter:(NSInteger)retryAfter retryAttempt:(NSInteger)retryAttempt forResponse:(NSURLResponse *)response; 17 | 18 | @end 19 | 20 | /* 21 | This class provides options to control the behaviour of Retry Handler. 22 | */ 23 | @interface MSRetryHandlerOptions : NSObject 24 | 25 | /* 26 | This property is to hold a reference to the class which will implement the Retry Handler Delegate 27 | */ 28 | @property (nonatomic, weak) id retryHandlerDelegate; 29 | 30 | /* 31 | Delay which will be used by Retry Handler to determine the interval after which it will retry in case there is no retry-after header present in the response. Upper limit is 180 seconds. 32 | */ 33 | @property (nonatomic, readonly) NSInteger delay; 34 | 35 | /* 36 | If we keep getting the retry response codes, then this is the Maximum number of retries which will be done before finising the execution of a request. Upper limit is 10. 37 | */ 38 | @property (nonatomic, readonly ) NSInteger maxRetries; 39 | 40 | /* 41 | This method initializes an instance of MSRetryHandlerOptions with the provided parameters. 42 | @param delay The delay value to be used in absence of a retry-after header 43 | @param maxRetries The maximum number of retries that can be performed in case we keep on getting retry response codes 44 | @param error If any error is encountered during the initalization, it will be assigned to this address. 45 | @return The MSRetryHandlerOptions instance with the provided values. 46 | */ 47 | - (instancetype)initWithDelay:(NSInteger)delay maxRetries:(NSInteger)maxRetries andError:(NSError **)error; 48 | 49 | @end 50 | 51 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Middleware/Options/MSRetryHandlerOptions.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSRetryHandlerOptions.h" 6 | #import "MSConstants.h" 7 | 8 | #define UPPER_LIMIT_FOR_DELAY 180 9 | #define UPPER_LIMIT_FOR_RETRIES 10 10 | 11 | @implementation MSRetryHandlerOptions 12 | 13 | @synthesize middlewareOptionsType; 14 | 15 | - (instancetype)init 16 | { 17 | return [self initWithDelay:3 maxRetries:3 andError:nil]; 18 | } 19 | 20 | - (instancetype)initWithDelay:(NSInteger)delay maxRetries:(NSInteger)maxRetries andError:(NSError *__autoreleasing *)error 21 | { 22 | self = [super init]; 23 | if(self) 24 | { 25 | if(delay>UPPER_LIMIT_FOR_DELAY) 26 | { 27 | NSDictionary *userInfo = @{ 28 | NSLocalizedDescriptionKey: MSErrorOperationUnsuccessfulString, 29 | 30 | NSLocalizedFailureReasonErrorKey:[NSString stringWithFormat:MSErrorDelayLimitExceededString,UPPER_LIMIT_FOR_DELAY] 31 | }; 32 | *error = [NSError errorWithDomain:MSErrorDomain code:MSCLientErrorCodeSDKUpperLimitReached userInfo:userInfo]; 33 | return nil; 34 | } 35 | if(maxRetries>UPPER_LIMIT_FOR_RETRIES) 36 | { 37 | NSDictionary *userInfo = @{ 38 | NSLocalizedDescriptionKey: MSErrorOperationUnsuccessfulString, 39 | NSLocalizedFailureReasonErrorKey:[NSString stringWithFormat:MSErrorMaxRetriesLimitExceededString,UPPER_LIMIT_FOR_RETRIES] 40 | }; 41 | *error = [NSError errorWithDomain:MSErrorDomain code:MSCLientErrorCodeSDKUpperLimitReached userInfo:userInfo]; 42 | return nil; 43 | } 44 | _delay = delay; 45 | _maxRetries = maxRetries; 46 | middlewareOptionsType = MSMiddlewareOptionsTypeRetry; 47 | } 48 | return self; 49 | } 50 | 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDK/Middleware/Protocols/MSGraphMiddleware.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | 7 | @class MSURLSessionTask; 8 | 9 | /* 10 | This protocol defines the required set of methods to be implemented by the Classes which will become the part of middleware chain. 11 | */ 12 | 13 | //Completion handler to be called when request finishes 14 | typedef void (^HTTPRequestCompletionHandler)(id data, NSURLResponse * _Nullable response, NSError * _Nullable error); 15 | 16 | @protocol MSGraphMiddleware 17 | 18 | /* 19 | This method will be executed to transfer the control from one middleware to next one. 20 | @param task The task object which needs to executed 21 | @completionHandler The completion handler to be called one the control comes back. 22 | */ 23 | - (void)execute:(MSURLSessionTask *)task withCompletionHandler:(HTTPRequestCompletionHandler)completionHandler; 24 | 25 | /* 26 | This method will be used to set the next one in middleware chain. 27 | @param nextMiddleware The next middleware object which will take the control from current one. 28 | */ 29 | - (void)setNext:(id)nextMiddleware; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/Frameworks/OCMock/NSNotificationCenter+OCMAdditions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2016 Erik Doernenburg and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use these files except in compliance with the License. You may obtain 6 | * 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, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | #import 18 | 19 | @class OCObserverMockObject; 20 | 21 | 22 | @interface NSNotificationCenter(OCMAdditions) 23 | 24 | - (void)addMockObserver:(OCObserverMockObject *)notificationObserver name:(NSString *)notificationName object:(id)notificationSender; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/Frameworks/OCMock/OCMArg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2016 Erik Doernenburg and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use these files except in compliance with the License. You may obtain 6 | * 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, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | #import 18 | 19 | @interface OCMArg : NSObject 20 | 21 | // constraining arguments 22 | 23 | + (id)any; 24 | + (SEL)anySelector; 25 | + (void *)anyPointer; 26 | + (id __autoreleasing *)anyObjectRef; 27 | + (id)isNil; 28 | + (id)isNotNil; 29 | + (id)isEqual:(id)value; 30 | + (id)isNotEqual:(id)value; 31 | + (id)isKindOfClass:(Class)cls; 32 | + (id)checkWithSelector:(SEL)selector onObject:(id)anObject; 33 | + (id)checkWithBlock:(BOOL (^)(id obj))block; 34 | 35 | // manipulating arguments 36 | 37 | + (id *)setTo:(id)value; 38 | + (void *)setToValue:(NSValue *)value; 39 | + (id)invokeBlock; 40 | + (id)invokeBlockWithArgs:(id)first,... NS_REQUIRES_NIL_TERMINATION; 41 | 42 | + (id)defaultValue; 43 | 44 | // internal use only 45 | 46 | + (id)resolveSpecialValues:(NSValue *)value; 47 | 48 | @end 49 | 50 | #define OCMOCK_ANY [OCMArg any] 51 | 52 | #if defined(__GNUC__) && !defined(__STRICT_ANSI__) 53 | #define OCMOCK_VALUE(variable) \ 54 | ({ __typeof__(variable) __v = (variable); [NSValue value:&__v withObjCType:@encode(__typeof__(__v))]; }) 55 | #else 56 | #define OCMOCK_VALUE(variable) [NSValue value:&variable withObjCType:@encode(__typeof__(variable))] 57 | #endif 58 | 59 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/Frameworks/OCMock/OCMConstraint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007-2016 Erik Doernenburg and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use these files except in compliance with the License. You may obtain 6 | * 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, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | #import 18 | 19 | 20 | @interface OCMConstraint : NSObject 21 | 22 | + (instancetype)constraint; 23 | - (BOOL)evaluate:(id)value; 24 | 25 | // if you are looking for any, isNil, etc, they have moved to OCMArg 26 | 27 | // try to use [OCMArg checkWith...] instead of the constraintWith... methods below 28 | 29 | + (instancetype)constraintWithSelector:(SEL)aSelector onObject:(id)anObject; 30 | + (instancetype)constraintWithSelector:(SEL)aSelector onObject:(id)anObject withValue:(id)aValue; 31 | 32 | 33 | @end 34 | 35 | @interface OCMAnyConstraint : OCMConstraint 36 | @end 37 | 38 | @interface OCMIsNilConstraint : OCMConstraint 39 | @end 40 | 41 | @interface OCMIsNotNilConstraint : OCMConstraint 42 | @end 43 | 44 | @interface OCMIsNotEqualConstraint : OCMConstraint 45 | { 46 | @public 47 | id testValue; 48 | } 49 | 50 | @end 51 | 52 | @interface OCMInvocationConstraint : OCMConstraint 53 | { 54 | @public 55 | NSInvocation *invocation; 56 | } 57 | 58 | @end 59 | 60 | @interface OCMBlockConstraint : OCMConstraint 61 | { 62 | BOOL (^block)(id); 63 | } 64 | 65 | - (instancetype)initWithConstraintBlock:(BOOL (^)(id))block; 66 | 67 | @end 68 | 69 | 70 | #define CONSTRAINT(aSelector) [OCMConstraint constraintWithSelector:aSelector onObject:self] 71 | #define CONSTRAINTV(aSelector, aValue) [OCMConstraint constraintWithSelector:aSelector onObject:self withValue:(aValue)] 72 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/Frameworks/OCMock/OCMFunctions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2016 Erik Doernenburg and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use these files except in compliance with the License. You may obtain 6 | * 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, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | #import 18 | 19 | 20 | #if defined(__cplusplus) 21 | #define OCMOCK_EXTERN extern "C" 22 | #else 23 | #define OCMOCK_EXTERN extern 24 | #endif 25 | 26 | 27 | OCMOCK_EXTERN BOOL OCMIsObjectType(const char *objCType); 28 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/Frameworks/OCMock/OCMLocation.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2016 Erik Doernenburg and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use these files except in compliance with the License. You may obtain 6 | * 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, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | #import 18 | #import "OCMFunctions.h" 19 | 20 | 21 | @interface OCMLocation : NSObject 22 | { 23 | id testCase; 24 | NSString *file; 25 | NSUInteger line; 26 | } 27 | 28 | + (instancetype)locationWithTestCase:(id)aTestCase file:(NSString *)aFile line:(NSUInteger)aLine; 29 | 30 | - (instancetype)initWithTestCase:(id)aTestCase file:(NSString *)aFile line:(NSUInteger)aLine; 31 | 32 | - (id)testCase; 33 | - (NSString *)file; 34 | - (NSUInteger)line; 35 | 36 | @end 37 | 38 | OCMOCK_EXTERN OCMLocation *OCMMakeLocation(id testCase, const char *file, int line); 39 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/Frameworks/OCMock/OCMMacroState.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2016 Erik Doernenburg and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use these files except in compliance with the License. You may obtain 6 | * 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, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | #import 18 | 19 | @class OCMLocation; 20 | @class OCMRecorder; 21 | @class OCMStubRecorder; 22 | @class OCMockObject; 23 | 24 | 25 | @interface OCMMacroState : NSObject 26 | { 27 | OCMRecorder *recorder; 28 | } 29 | 30 | + (void)beginStubMacro; 31 | + (OCMStubRecorder *)endStubMacro; 32 | 33 | + (void)beginExpectMacro; 34 | + (OCMStubRecorder *)endExpectMacro; 35 | 36 | + (void)beginRejectMacro; 37 | + (OCMStubRecorder *)endRejectMacro; 38 | 39 | + (void)beginVerifyMacroAtLocation:(OCMLocation *)aLocation; 40 | + (void)endVerifyMacro; 41 | 42 | + (OCMMacroState *)globalState; 43 | 44 | - (OCMRecorder *)recorder; 45 | 46 | - (void)switchToClassMethod; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/Frameworks/OCMock/OCMRecorder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2016 Erik Doernenburg and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use these files except in compliance with the License. You may obtain 6 | * 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, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | #import 18 | 19 | @class OCMockObject; 20 | @class OCMInvocationMatcher; 21 | 22 | 23 | @interface OCMRecorder : NSProxy 24 | { 25 | OCMockObject *mockObject; 26 | OCMInvocationMatcher *invocationMatcher; 27 | } 28 | 29 | - (instancetype)init; 30 | - (instancetype)initWithMockObject:(OCMockObject *)aMockObject; 31 | 32 | - (void)setMockObject:(OCMockObject *)aMockObject; 33 | 34 | - (OCMInvocationMatcher *)invocationMatcher; 35 | 36 | - (id)classMethod; 37 | - (id)ignoringNonObjectArgs; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/Frameworks/OCMock/OCMStubRecorder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2004-2016 Erik Doernenburg and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use these files except in compliance with the License. You may obtain 6 | * 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, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | #import 18 | #import 19 | #import 20 | 21 | @interface OCMStubRecorder : OCMRecorder 22 | 23 | - (id)andReturn:(id)anObject; 24 | - (id)andReturnValue:(NSValue *)aValue; 25 | - (id)andThrow:(NSException *)anException; 26 | - (id)andPost:(NSNotification *)aNotification; 27 | - (id)andCall:(SEL)selector onObject:(id)anObject; 28 | - (id)andDo:(void (^)(NSInvocation *invocation))block; 29 | - (id)andForwardToRealObject; 30 | 31 | @end 32 | 33 | 34 | @interface OCMStubRecorder (Properties) 35 | 36 | #define andReturn(aValue) _andReturn(({ \ 37 | __typeof__(aValue) _val = (aValue); \ 38 | NSValue *_nsval = [NSValue value:&_val withObjCType:@encode(__typeof__(_val))]; \ 39 | if (OCMIsObjectType(@encode(__typeof(_val)))) { \ 40 | objc_setAssociatedObject(_nsval, "OCMAssociatedBoxedValue", *(__unsafe_unretained id *) (void *) &_val, OBJC_ASSOCIATION_RETAIN); \ 41 | } \ 42 | _nsval; \ 43 | })) 44 | @property (nonatomic, readonly) OCMStubRecorder *(^ _andReturn)(NSValue *); 45 | 46 | #define andThrow(anException) _andThrow(anException) 47 | @property (nonatomic, readonly) OCMStubRecorder *(^ _andThrow)(NSException *); 48 | 49 | #define andPost(aNotification) _andPost(aNotification) 50 | @property (nonatomic, readonly) OCMStubRecorder *(^ _andPost)(NSNotification *); 51 | 52 | #define andCall(anObject, aSelector) _andCall(anObject, aSelector) 53 | @property (nonatomic, readonly) OCMStubRecorder *(^ _andCall)(id, SEL); 54 | 55 | #define andDo(aBlock) _andDo(aBlock) 56 | @property (nonatomic, readonly) OCMStubRecorder *(^ _andDo)(void (^)(NSInvocation *)); 57 | 58 | #define andForwardToRealObject() _andForwardToRealObject() 59 | @property (nonatomic, readonly) OCMStubRecorder *(^ _andForwardToRealObject)(void); 60 | 61 | @end 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/Frameworks/OCMock/OCMock.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2004-2016 Erik Doernenburg and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use these files except in compliance with the License. You may obtain 6 | * 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, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | #import 18 | #import 19 | #import 20 | #import 21 | #import 22 | #import 23 | #import 24 | #import 25 | #import 26 | 27 | 28 | #define OCMClassMock(cls) [OCMockObject niceMockForClass:cls] 29 | 30 | #define OCMStrictClassMock(cls) [OCMockObject mockForClass:cls] 31 | 32 | #define OCMProtocolMock(protocol) [OCMockObject niceMockForProtocol:protocol] 33 | 34 | #define OCMStrictProtocolMock(protocol) [OCMockObject mockForProtocol:protocol] 35 | 36 | #define OCMPartialMock(obj) [OCMockObject partialMockForObject:obj] 37 | 38 | #define OCMObserverMock() [OCMockObject observerMock] 39 | 40 | 41 | #define OCMStub(invocation) \ 42 | ({ \ 43 | _OCMSilenceWarnings( \ 44 | [OCMMacroState beginStubMacro]; \ 45 | OCMStubRecorder *recorder = nil; \ 46 | @try{ \ 47 | invocation; \ 48 | }@finally{ \ 49 | recorder = [OCMMacroState endStubMacro]; \ 50 | } \ 51 | recorder; \ 52 | ); \ 53 | }) 54 | 55 | #define OCMExpect(invocation) \ 56 | ({ \ 57 | _OCMSilenceWarnings( \ 58 | [OCMMacroState beginExpectMacro]; \ 59 | OCMStubRecorder *recorder = nil; \ 60 | @try{ \ 61 | invocation; \ 62 | }@finally{ \ 63 | recorder = [OCMMacroState endExpectMacro]; \ 64 | } \ 65 | recorder; \ 66 | ); \ 67 | }) 68 | 69 | #define OCMReject(invocation) \ 70 | ({ \ 71 | _OCMSilenceWarnings( \ 72 | [OCMMacroState beginRejectMacro]; \ 73 | OCMStubRecorder *recorder = nil; \ 74 | @try{ \ 75 | invocation; \ 76 | }@finally{ \ 77 | recorder = [OCMMacroState endRejectMacro]; \ 78 | } \ 79 | recorder; \ 80 | ); \ 81 | }) 82 | 83 | #define ClassMethod(invocation) \ 84 | _OCMSilenceWarnings( \ 85 | [[OCMMacroState globalState] switchToClassMethod]; \ 86 | invocation; \ 87 | ); 88 | 89 | 90 | #define OCMVerifyAll(mock) [mock verifyAtLocation:OCMMakeLocation(self, __FILE__, __LINE__)] 91 | 92 | #define OCMVerifyAllWithDelay(mock, delay) [mock verifyWithDelay:delay atLocation:OCMMakeLocation(self, __FILE__, __LINE__)] 93 | 94 | #define OCMVerify(invocation) \ 95 | ({ \ 96 | _OCMSilenceWarnings( \ 97 | [OCMMacroState beginVerifyMacroAtLocation:OCMMakeLocation(self, __FILE__, __LINE__)]; \ 98 | @try{ \ 99 | invocation; \ 100 | }@finally{ \ 101 | [OCMMacroState endVerifyMacro]; \ 102 | } \ 103 | ); \ 104 | }) 105 | 106 | #define _OCMSilenceWarnings(macro) \ 107 | ({ \ 108 | _Pragma("clang diagnostic push") \ 109 | _Pragma("clang diagnostic ignored \"-Wunused-value\"") \ 110 | _Pragma("clang diagnostic ignored \"-Wunused-getter-return-value\"") \ 111 | macro \ 112 | _Pragma("clang diagnostic pop") \ 113 | }) 114 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/Frameworks/OCMock/OCMockObject.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2004-2016 Erik Doernenburg and contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use these files except in compliance with the License. You may obtain 6 | * 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, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | #import 18 | 19 | @class OCMLocation; 20 | @class OCMInvocationStub; 21 | @class OCMStubRecorder; 22 | @class OCMInvocationMatcher; 23 | @class OCMInvocationExpectation; 24 | 25 | 26 | @interface OCMockObject : NSProxy 27 | { 28 | BOOL isNice; 29 | BOOL expectationOrderMatters; 30 | NSMutableArray *stubs; 31 | NSMutableArray *expectations; 32 | NSMutableArray *exceptions; 33 | NSMutableArray *invocations; 34 | } 35 | 36 | + (id)mockForClass:(Class)aClass; 37 | + (id)mockForProtocol:(Protocol *)aProtocol; 38 | + (id)partialMockForObject:(NSObject *)anObject; 39 | 40 | + (id)niceMockForClass:(Class)aClass; 41 | + (id)niceMockForProtocol:(Protocol *)aProtocol; 42 | 43 | + (id)observerMock; 44 | 45 | - (instancetype)init; 46 | 47 | - (void)setExpectationOrderMatters:(BOOL)flag; 48 | 49 | - (id)stub; 50 | - (id)expect; 51 | - (id)reject; 52 | 53 | - (id)verify; 54 | - (id)verifyAtLocation:(OCMLocation *)location; 55 | 56 | - (void)verifyWithDelay:(NSTimeInterval)delay; 57 | - (void)verifyWithDelay:(NSTimeInterval)delay atLocation:(OCMLocation *)location; 58 | 59 | - (void)stopMocking; 60 | 61 | // internal use only 62 | 63 | - (void)addStub:(OCMInvocationStub *)aStub; 64 | - (void)addExpectation:(OCMInvocationExpectation *)anExpectation; 65 | 66 | - (BOOL)handleInvocation:(NSInvocation *)anInvocation; 67 | - (void)handleUnRecordedInvocation:(NSInvocation *)anInvocation; 68 | - (BOOL)handleSelector:(SEL)sel; 69 | 70 | - (void)verifyInvocation:(OCMInvocationMatcher *)matcher; 71 | - (void)verifyInvocation:(OCMInvocationMatcher *)matcher atLocation:(OCMLocation *)location; 72 | 73 | @end 74 | 75 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/Frameworks/libOCMock.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-sdk-objc/1733c3cdd7afe9a0aeffc35c2635eb0cec59b264/MSGraphClientSDK/MSGraphClientSDKTests/Frameworks/libOCMock.a -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/GraphContent/BatchContent/MSBatchRequestStepTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSGraphClientSDKTests.h" 7 | 8 | @interface MSBatchRequestStepTests : MSGraphClientSDKTests 9 | 10 | @end 11 | 12 | @implementation MSBatchRequestStepTests 13 | 14 | - (void)setUp { 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | [super setUp]; 17 | } 18 | 19 | - (void)tearDown { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | } 22 | 23 | - (void)testInitWithDifferentCases { 24 | 25 | XCTAssertThrows([[MSBatchRequestStep alloc] initWithId:nil request:self.requestForMock andDependsOn:nil]); 26 | XCTAssertThrows([[MSBatchRequestStep alloc] initWithId:@"1" request:nil andDependsOn:nil]); 27 | 28 | MSBatchRequestStep *batchRequestStep = [[MSBatchRequestStep alloc] initWithId:@"1" request:self.requestForMock andDependsOn:nil]; 29 | XCTAssertEqual(batchRequestStep.requestId, @"1"); 30 | XCTAssertEqual(batchRequestStep.request.URL.absoluteString, self.requestForMock.URL.absoluteString); 31 | XCTAssertNil(batchRequestStep.arrayOfDependsOnIds); 32 | 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/GraphContent/BatchContent/MSBatchResponseContentTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSGraphClientSDKTests.h" 7 | 8 | @interface MSBatchResponseContent() 9 | @property (strong, nonatomic) NSDictionary *batchResponseDictionary; 10 | @end 11 | 12 | @interface MSBatchResponseContentTests : MSGraphClientSDKTests 13 | 14 | @end 15 | 16 | @implementation MSBatchResponseContentTests 17 | { 18 | NSData *demoBatchResponseData; 19 | } 20 | 21 | - (void)setUp { 22 | // Put setup code here. This method is called before the invocation of each test method in the class. 23 | [super setUp]; 24 | NSString *jsonPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"BatchResponse" ofType:@".json"]; 25 | XCTAssertNotNil(jsonPath); 26 | demoBatchResponseData = [NSData dataWithContentsOfFile:jsonPath]; 27 | } 28 | 29 | - (void)tearDown { 30 | // Put teardown code here. This method is called after the invocation of each test method in the class. 31 | } 32 | 33 | - (void)testInit { 34 | XCTAssertThrows([[MSBatchResponseContent alloc] initWithBatchResponseData:nil options:kNilOptions error:nil]); 35 | NSError *error; 36 | MSBatchResponseContent *batchResponseContent = [[MSBatchResponseContent alloc] initWithBatchResponseData:demoBatchResponseData options:kNilOptions error:&error]; 37 | XCTAssertNil(error); 38 | XCTAssertNotNil(batchResponseContent.batchResponseDictionary); 39 | } 40 | 41 | - (void)testGetResponseById { 42 | NSError *error; 43 | MSBatchResponseContent *batchResponseContent = [[MSBatchResponseContent alloc] initWithBatchResponseData:demoBatchResponseData options:kNilOptions error:&error]; 44 | XCTAssertNil(error); 45 | XCTAssertNil([batchResponseContent getResponseById:@"100"]); 46 | NSDictionary *responseDictioanry = [batchResponseContent getResponseById:@"1"]; 47 | 48 | NSDictionary *originalJsonDictionary = [NSJSONSerialization JSONObjectWithData:demoBatchResponseData options:kNilOptions error:&error]; 49 | XCTAssertNil(error); 50 | NSDictionary *originalResponseDictionary; 51 | for(NSDictionary *responseDict in [originalJsonDictionary objectForKey:@"responses"]) { 52 | if([[responseDict objectForKey:@"id"] isEqualToString:@"1"]) { 53 | originalResponseDictionary = responseDict; 54 | break; 55 | } 56 | } 57 | XCTAssertEqualObjects([responseDictioanry objectForKey:@"id"],[originalResponseDictionary objectForKey:@"id"]); 58 | XCTAssertEqualObjects([responseDictioanry objectForKey:@"status"],[originalResponseDictionary objectForKey:@"status"]); 59 | XCTAssertEqualObjects([[responseDictioanry objectForKey:@"headers"] objectForKey:@"location"],[[originalResponseDictionary objectForKey:@"headers"] objectForKey:@"location"]); 60 | } 61 | 62 | - (void)testGetResponses { 63 | NSError *error; 64 | MSBatchResponseContent *batchResponseContent = [[MSBatchResponseContent alloc] initWithBatchResponseData:demoBatchResponseData options:kNilOptions error:&error]; 65 | XCTAssertNil(error); 66 | 67 | NSDictionary *originalJsonDictionary = [NSJSONSerialization JSONObjectWithData:demoBatchResponseData options:kNilOptions error:&error]; 68 | XCTAssertNil(error); 69 | XCTAssertEqualObjects([batchResponseContent getResponses], originalJsonDictionary); 70 | } 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/GraphTasks/MSGraphOneDriveLargeFileUploadTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSGraphClientSDKTests.h" 7 | #import "MSGraphOneDriveLargeFileUploadTask.h" 8 | 9 | @interface MSGraphOneDriveLargeFileUploadTask() 10 | 11 | + (NSMutableURLRequest *)createUploadSessionRequestWithFileName:(NSString *)fileName filePath:(NSString *)filePath; 12 | 13 | @end 14 | 15 | @interface MSGraphOneDriveLargeFileUploadTests : MSGraphClientSDKTests 16 | 17 | @end 18 | 19 | @implementation MSGraphOneDriveLargeFileUploadTests{ 20 | NSData *fileData; 21 | NSHTTPURLResponse *OKResponse; 22 | NSHTTPURLResponse *failureResponse; 23 | NSData *successData; 24 | } 25 | 26 | - (void)setUp { 27 | [super setUp]; 28 | // Put setup code here. This method is called before the invocation of each test method in the class. 29 | NSString *imagePath = [[NSBundle bundleForClass:[self class]] pathForResource:@"LargeFileUploadResource" ofType:@".bmp"]; 30 | fileData = [NSData dataWithContentsOfFile:imagePath]; 31 | 32 | NSDictionary *successDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:MSGraphBaseURL,@"uploadUrl", nil]; 33 | successData = [NSJSONSerialization dataWithJSONObject:successDictionary options:kNilOptions error:nil]; 34 | 35 | OKResponse = [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:MSGraphBaseURL] statusCode:MSExpectedResponseCodesOK HTTPVersion:@"foo" headerFields:nil]; 36 | failureResponse = [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:MSGraphBaseURL] statusCode:501 HTTPVersion:@"foo" headerFields:nil]; 37 | } 38 | 39 | - (void)tearDown { 40 | // Put teardown code here. This method is called after the invocation of each test method in the class. 41 | [super tearDown]; 42 | } 43 | 44 | 45 | - (void)testCreateUploadSessionRequest { 46 | NSMutableURLRequest *urlRequest = [MSGraphOneDriveLargeFileUploadTask createUploadSessionRequestWithFileName:@"testLargeFile" filePath:@"Documents"]; 47 | XCTAssertEqualObjects(urlRequest.HTTPMethod, @"POST"); 48 | XCTAssertTrue([[urlRequest.URL absoluteString] containsString:@"testLargeFile"]); 49 | XCTAssertTrue([[urlRequest.URL absoluteString] containsString:@"Documents"]); 50 | XCTAssertEqualObjects([urlRequest.URL absoluteString], @"https://graph.microsoft.com/v1.0/me/drive/root:/Documents/testLargeFile:/createUploadSession"); 51 | 52 | } 53 | 54 | - (void)testCreateOneDriveLargeFileUploadTaskSuccessfull { 55 | MSAuthenticationHandler *partialHandler = OCMPartialMock(self.mockClient.middleware); 56 | 57 | OCMStub([partialHandler execute:[OCMArg any] withCompletionHandler:[OCMArg any]]).andDo(^(NSInvocation *invocation){ 58 | HTTPRequestCompletionHandler completionHandler; 59 | [invocation getArgument:&completionHandler atIndex:3]; 60 | completionHandler(self->successData, self->OKResponse, nil); 61 | }); 62 | [MSGraphOneDriveLargeFileUploadTask createOneDriveLargeFileUploadTaskWithHTTPClient:self.mockClient fileData:fileData fileName:@"LargeFile" filePath:@"Documents" andChunkSize:5*1024*1024 withCompletion:^(MSGraphOneDriveLargeFileUploadTask *fileUploadTask, NSData *data, NSURLResponse *response, NSError *error) { 63 | XCTAssertNotNil(fileUploadTask); 64 | XCTAssertNil(error); 65 | XCTAssertNotNil(response); 66 | XCTAssertEqual(((NSHTTPURLResponse *)response).statusCode, MSExpectedResponseCodesOK); 67 | XCTAssertNotNil(data); 68 | XCTAssertEqualObjects([[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil] objectForKey:@"uploadUrl"], [[NSJSONSerialization JSONObjectWithData:self->successData options:kNilOptions error:nil] objectForKey:@"uploadUrl"]); 69 | }]; 70 | } 71 | 72 | - (void)testCreateOneDriveLargeFileWithNilUploadUrl { 73 | MSAuthenticationHandler *partialHandler = OCMPartialMock(self.mockClient.middleware); 74 | 75 | OCMStub([partialHandler execute:[OCMArg any] withCompletionHandler:[OCMArg any]]).andDo(^(NSInvocation *invocation){ 76 | HTTPRequestCompletionHandler completionHandler; 77 | [invocation getArgument:&completionHandler atIndex:3]; 78 | completionHandler([NSData new], self->OKResponse, nil); 79 | }); 80 | [MSGraphOneDriveLargeFileUploadTask createOneDriveLargeFileUploadTaskWithHTTPClient:self.mockClient fileData:fileData fileName:@"LargeFile" filePath:@"Documents" andChunkSize:5*1024*1024 withCompletion:^(MSGraphOneDriveLargeFileUploadTask *fileUploadTask, NSData *data, NSURLResponse *response, NSError *error) { 81 | XCTAssertNil(fileUploadTask); 82 | XCTAssertNil(error); 83 | XCTAssertNotNil(response); 84 | XCTAssertEqual(((NSHTTPURLResponse *)response).statusCode, MSExpectedResponseCodesOK); 85 | XCTAssertNotNil(data); 86 | XCTAssertNil([[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil] objectForKey:@"uploadUrl"]); 87 | }]; 88 | } 89 | 90 | - (void)testCreateOneDriveLargeFileWithFailureResponse { 91 | MSAuthenticationHandler *partialHandler = OCMPartialMock(self.mockClient.middleware); 92 | 93 | OCMStub([partialHandler execute:[OCMArg any] withCompletionHandler:[OCMArg any]]).andDo(^(NSInvocation *invocation){ 94 | HTTPRequestCompletionHandler completionHandler; 95 | [invocation getArgument:&completionHandler atIndex:3]; 96 | completionHandler(nil, self->failureResponse, [NSError errorWithDomain:MSErrorDomain code:501 userInfo:nil]); 97 | }); 98 | [MSGraphOneDriveLargeFileUploadTask createOneDriveLargeFileUploadTaskWithHTTPClient:self.mockClient fileData:fileData fileName:@"LargeFile" filePath:@"Documents" andChunkSize:5*1024*1024 withCompletion:^(MSGraphOneDriveLargeFileUploadTask *fileUploadTask, NSData *data, NSURLResponse *response, NSError *error) { 99 | XCTAssertNil(fileUploadTask); 100 | XCTAssertNotNil(error); 101 | XCTAssertNotNil(response); 102 | XCTAssertEqual(((NSHTTPURLResponse *)response).statusCode, 501); 103 | XCTAssertNil(data); 104 | }]; 105 | } 106 | 107 | @end 108 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/GraphTasks/MSLargeFileUploadTaskTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSGraphClientSDKTests.h" 7 | #import "MSLargeFileUploadTask.h" 8 | 9 | @interface MSLargeFileUploadTask() 10 | 11 | @property (nonatomic, strong) MSHTTPClient *httpClient; 12 | @property (nonatomic, strong) NSData *fileData; 13 | @property (nonatomic, strong) NSDictionary *uploadSessionDictionary; 14 | @property (nonatomic) NSInteger chunkSize; 15 | @property (nonatomic) NSRange currentRange; 16 | 17 | - (void)uploadNextSegmentWithCompletion:(MSRawUploadCompletionHandler)completionHandler; 18 | 19 | @end 20 | 21 | 22 | @interface MSLargeFileUploadTaskTests : MSGraphClientSDKTests 23 | 24 | @property (nonatomic, strong) NSHTTPURLResponse *OKResponse; 25 | @property (nonatomic, strong) NSHTTPURLResponse *acceptedResponse; 26 | 27 | @end 28 | 29 | @implementation MSLargeFileUploadTaskTests{ 30 | NSData *fileData; 31 | NSDictionary *uploadSessionDictionary; 32 | MSLargeFileUploadTask *chunkedUploadTask; 33 | NSData *successData; 34 | } 35 | 36 | - (void)setUp { 37 | [super setUp]; 38 | // Put setup code here. This method is called before the invocation of each test method in the class. 39 | self.OKResponse = [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:MSGraphBaseURL] statusCode:MSExpectedResponseCodesOK HTTPVersion:@"foo" headerFields:nil]; 40 | self.acceptedResponse = [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:MSGraphBaseURL] statusCode:MSExpectedResponseCodesAccepted HTTPVersion:@"foo" headerFields:nil]; 41 | 42 | NSString *imagePath = [[NSBundle bundleForClass:[self class]] pathForResource:@"LargeFileUploadResource" ofType:@".bmp"]; 43 | fileData = [NSData dataWithContentsOfFile:imagePath]; 44 | uploadSessionDictionary = [NSDictionary dictionaryWithObjectsAndKeys:MSGraphBaseURL,@"uploadUrl", nil]; 45 | chunkedUploadTask = [[MSLargeFileUploadTask alloc] initWithClient:self.mockClient fileData:fileData uploadSessionDictionary:uploadSessionDictionary andChunkSize:0]; 46 | 47 | NSDictionary *successDictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"aasd123aad123",@"id", nil]; 48 | successData = [NSJSONSerialization dataWithJSONObject:successDictionary options:kNilOptions error:nil]; 49 | } 50 | 51 | - (void)tearDown { 52 | // Put teardown code here. This method is called after the invocation of each test method in the class. 53 | [super tearDown]; 54 | } 55 | 56 | - (void)testInitWithMalformedInputs { 57 | XCTAssertThrows([[MSLargeFileUploadTask alloc] initWithClient:nil fileData:fileData uploadSessionDictionary:uploadSessionDictionary andChunkSize:0]); 58 | 59 | XCTAssertThrows([[MSLargeFileUploadTask alloc] initWithClient:self.mockClient fileData:nil uploadSessionDictionary:uploadSessionDictionary andChunkSize:0]); 60 | 61 | XCTAssertThrows([[MSLargeFileUploadTask alloc] initWithClient:self.mockClient fileData:fileData uploadSessionDictionary:nil andChunkSize:0]); 62 | 63 | XCTAssertThrows([[MSLargeFileUploadTask alloc] initWithClient:self.mockClient fileData:fileData uploadSessionDictionary:[NSDictionary new] andChunkSize:0]); 64 | } 65 | 66 | - (void)testSuccessfullInit { 67 | MSLargeFileUploadTask *largeFileUploadTask = [[MSLargeFileUploadTask alloc] initWithClient:self.mockClient fileData:fileData uploadSessionDictionary:uploadSessionDictionary andChunkSize:0]; 68 | 69 | XCTAssertEqual(largeFileUploadTask.httpClient, self.mockClient); 70 | XCTAssertEqual(largeFileUploadTask.fileData, fileData); 71 | XCTAssertEqual(largeFileUploadTask.uploadSessionDictionary, uploadSessionDictionary); 72 | XCTAssertEqual(largeFileUploadTask.chunkSize, 5*1024*1024); 73 | } 74 | 75 | - (void)testSetNextRange { 76 | [chunkedUploadTask performSelector:@selector(setNextRange)]; 77 | 78 | XCTAssertEqual(chunkedUploadTask.currentRange.location, DefaultChunkSize); 79 | XCTAssertEqual(chunkedUploadTask.currentRange.length, DefaultChunkSize); 80 | } 81 | 82 | - (void)testUploadWithCompletion { 83 | MSLargeFileUploadTask *partialUploadTask = OCMPartialMock(chunkedUploadTask); 84 | 85 | OCMStub([partialUploadTask uploadNextSegmentWithCompletion:[OCMArg any]]).andDo(^(NSInvocation *invocation){ 86 | HTTPRequestCompletionHandler completionHandler; 87 | [invocation getArgument:&completionHandler atIndex:2]; 88 | completionHandler([NSData new], self.OKResponse, nil); 89 | }); 90 | 91 | [partialUploadTask uploadWithCompletion:^(NSData *data, NSURLResponse *response, NSError *error) { 92 | [self completionBlockCodeInvoked]; 93 | XCTAssertNil(error); 94 | XCTAssertNotNil(response); 95 | XCTAssertEqual(((NSHTTPURLResponse *)response).statusCode, MSExpectedResponseCodesOK); 96 | XCTAssertNotNil(data); 97 | }]; 98 | [self checkCompletionBlockCodeInvoked]; 99 | } 100 | 101 | - (void)testUploadSingleSegment { 102 | 103 | MSAuthenticationHandler *partialHandler = OCMPartialMock(self.mockClient.middleware); 104 | 105 | OCMStub([partialHandler execute:[OCMArg any] withCompletionHandler:[OCMArg any]]).andDo(^(NSInvocation *invocation){ 106 | HTTPRequestCompletionHandler completionHandler; 107 | [invocation getArgument:&completionHandler atIndex:3]; 108 | completionHandler(self->successData, self.OKResponse, nil); 109 | }); 110 | [chunkedUploadTask uploadWithCompletion:^(NSData *data, NSURLResponse *response, NSError *error) { 111 | [self completionBlockCodeInvoked]; 112 | XCTAssertNil(error); 113 | XCTAssertNotNil(response); 114 | XCTAssertEqual(((NSHTTPURLResponse *)response).statusCode, MSExpectedResponseCodesOK); 115 | XCTAssertNotNil(data); 116 | }]; 117 | [self checkCompletionBlockCodeInvoked]; 118 | } 119 | 120 | - (void)testFullIteration { 121 | 122 | MSAuthenticationHandler *partialHandler = OCMPartialMock(self.mockClient.middleware); 123 | 124 | __block int i=0; 125 | OCMStub([partialHandler execute:[OCMArg any] withCompletionHandler:[OCMArg any]]).andDo(^(NSInvocation *invocation){ 126 | i++; 127 | NSLog(@"%d - i ki value",i); 128 | 129 | __unsafe_unretained HTTPRequestCompletionHandler completionHandler; 130 | [invocation getArgument:&completionHandler atIndex:3]; 131 | 132 | __unsafe_unretained MSURLSessionDataTask *dataTask; 133 | [invocation getArgument:&dataTask atIndex:2]; 134 | 135 | if(i==1) { 136 | completionHandler([NSData new], self->_acceptedResponse, nil); 137 | }else if( i==2){ 138 | 139 | completionHandler ([NSData new], self->_OKResponse, nil); 140 | }else { 141 | completionHandler(self->successData, self.OKResponse, nil); 142 | } 143 | }); 144 | 145 | [chunkedUploadTask uploadWithCompletion:^(NSData *data, NSURLResponse *response, NSError *error) { 146 | [self completionBlockCodeInvoked]; 147 | XCTAssertNil(error); 148 | XCTAssertNotNil(response); 149 | XCTAssertEqual(((NSHTTPURLResponse *)response).statusCode, MSExpectedResponseCodesOK); 150 | XCTAssertNotNil(data); 151 | }]; 152 | [self checkCompletionBlockCodeInvoked]; 153 | } 154 | 155 | - (void)testCreateUploadSession { 156 | MSAuthenticationHandler *partialHandler = OCMPartialMock(self.mockClient.middleware); 157 | 158 | OCMStub([partialHandler execute:[OCMArg any] withCompletionHandler:[OCMArg any]]).andDo(^(NSInvocation *invocation){ 159 | HTTPRequestCompletionHandler completionHandler; 160 | [invocation getArgument:&completionHandler atIndex:3]; 161 | completionHandler(self->successData, self.OKResponse, nil); 162 | }); 163 | 164 | [MSLargeFileUploadTask createUploadSessionFromRequest:self.requestForMock andHTTPClient:self.mockClient completionBlock:^(id data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 165 | XCTAssertNil(error); 166 | XCTAssertNotNil(response); 167 | XCTAssertEqual(((NSHTTPURLResponse *)response).statusCode, MSExpectedResponseCodesOK); 168 | XCTAssertNotNil(data); 169 | }]; 170 | } 171 | 172 | @end 173 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/GraphTasks/MSPageIteratorTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSGraphClientSDKTests.h" 7 | #import "MSPageIterator.h" 8 | 9 | @interface MSPageIterator() 10 | 11 | @property (nonatomic, strong) NSDictionary *dataDictionary; 12 | @property (nonatomic, strong) MSURLSessionDataTask *dataTask; 13 | 14 | - (void)fetchNextPage; 15 | 16 | @end 17 | 18 | @interface MSURLSessionTask() 19 | 20 | - (void)taskCompletedWithData:(id)data response:(NSURLResponse *)response andError:(NSError *)error; 21 | 22 | @end 23 | 24 | 25 | @interface MSPageIteratorTests : MSGraphClientSDKTests 26 | 27 | @end 28 | 29 | @implementation MSPageIteratorTests { 30 | NSData *demoBatchResponseData; 31 | NSDictionary *demoResponseDictionary; 32 | } 33 | 34 | - (void)setUp { 35 | [super setUp]; 36 | NSString *jsonPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"PagedResponse" ofType:@".json"]; 37 | XCTAssertNotNil(jsonPath); 38 | demoBatchResponseData = [NSData dataWithContentsOfFile:jsonPath]; 39 | demoResponseDictionary = [NSJSONSerialization JSONObjectWithData:demoBatchResponseData options:kNilOptions error:nil]; 40 | // Put setup code here. This method is called before the invocation of each test method in the class. 41 | } 42 | 43 | - (void)tearDown { 44 | // Put teardown code here. This method is called after the invocation of each test method in the class. 45 | [super tearDown]; 46 | } 47 | 48 | - (void)testInit { 49 | XCTAssertThrows([[MSPageIterator alloc] initWithData:nil client:self.mockClient andIteratorBlock:^(NSDictionary *itemDictionary, BOOL *stop) { 50 | }]); 51 | 52 | XCTAssertThrows([[MSPageIterator alloc] initWithData:[NSData new] client:nil andIteratorBlock:^(NSDictionary *itemDictionary, BOOL *stop) { 53 | }]); 54 | 55 | XCTAssertThrows([[MSPageIterator alloc] initWithData:[NSData new] client:self.mockClient andIteratorBlock:nil]); 56 | 57 | XCTAssertNotNil([[MSPageIterator alloc] initWithData:[NSData new] client:self.mockClient andIteratorBlock:^(NSDictionary *itemDictionary, BOOL *stop) { 58 | }]); 59 | } 60 | 61 | - (void)testIntraPageIterateAndStop { 62 | __block int i=0; 63 | __block NSArray *valueArray = [demoResponseDictionary objectForKey:@"value"]; 64 | 65 | XCTestExpectation *iterationWaitExpectation = [[XCTestExpectation alloc] initWithDescription:@"Waiting for iteration to complete"]; 66 | 67 | MSPageIterator *pageIterator = [[MSPageIterator alloc] initWithData:demoBatchResponseData client:self.mockClient andIteratorBlock:^(NSDictionary *itemDictionary, BOOL *stop) { 68 | XCTAssertEqualObjects(itemDictionary, [valueArray objectAtIndex:i]); 69 | i++; 70 | if(i==10){ 71 | *stop = true; 72 | [iterationWaitExpectation fulfill]; 73 | } 74 | }]; 75 | [pageIterator iterate]; 76 | [self waitForExpectations:@[iterationWaitExpectation] timeout:2.0]; 77 | 78 | XCTAssertFalse(pageIterator.isComplete); 79 | } 80 | 81 | - (void)testInterPageIterateAndIsComplete { 82 | XCTestExpectation *iterationWaitExpectation = [[XCTestExpectation alloc] initWithDescription:@"Waiting for iteration to complete"]; 83 | 84 | __block MSPageIterator *pageIterator = [[MSPageIterator alloc] initWithData:demoBatchResponseData client:self.mockClient andIteratorBlock:^(NSDictionary *itemDictionary, BOOL *stop) { 85 | if([pageIterator isComplete]){ 86 | [iterationWaitExpectation fulfill]; 87 | } 88 | }]; 89 | 90 | MSPageIterator *partialMock = OCMPartialMock(pageIterator); 91 | OCMStub([partialMock fetchNextPage]).andDo(^(NSInvocation *invocation){ 92 | MSURLSessionDataTask *partialTask = OCMPartialMock(pageIterator.dataTask); 93 | OCMStub([partialTask execute]).andDo(^(NSInvocation *invocation){ 94 | NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:MSGraphBaseURL] statusCode:MSExpectedResponseCodesOK HTTPVersion:@"foo" headerFields:nil]; 95 | NSMutableDictionary *nextPageDictionary = [self->demoResponseDictionary mutableCopy]; 96 | [nextPageDictionary setObject:@"" forKey:@"@odata.nextLink"]; 97 | NSData *nextPageData = [NSJSONSerialization dataWithJSONObject:nextPageDictionary options:kNilOptions error:nil]; 98 | [pageIterator.dataTask taskCompletedWithData:nextPageData response:response andError:nil]; 99 | }); 100 | [partialTask execute]; 101 | 102 | }); 103 | [pageIterator iterate]; 104 | [self waitForExpectations:@[iterationWaitExpectation] timeout:12.0]; 105 | 106 | XCTAssertTrue(pageIterator.isComplete); 107 | } 108 | @end 109 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/HTTPClient/MSClientFactoryTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSGraphClientSDKTests.h" 7 | 8 | @interface MSClientFactoryTests : MSGraphClientSDKTests 9 | 10 | @end 11 | 12 | @implementation MSClientFactoryTests 13 | 14 | - (void)setUp { 15 | [super setUp]; 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | - (void)tearDown { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | [super tearDown]; 22 | } 23 | 24 | - (void)testCreationOfHTTPClientWithNilValue { 25 | XCTAssertThrows([MSClientFactory createHTTPClientWithAuthenticationProvider:nil]); 26 | XCTAssertThrows([MSClientFactory createHTTPClientWithMiddleware:nil]); 27 | XCTAssertThrows([MSClientFactory createHTTPClientWithAuthenticationProvider:self.mockAuthProvider andSessionConfiguration:nil]); 28 | } 29 | 30 | - (void)testCreationOfHTTPClientWithAuthProvider { 31 | MSHTTPClient *defaulClient = [MSClientFactory createHTTPClientWithAuthenticationProvider:self.mockAuthProvider]; 32 | XCTAssertNotNil(defaulClient); 33 | } 34 | 35 | - (void)testCreationOfHTTPClientWithMiddleware { 36 | MSHTTPClient *customClient = [MSClientFactory createHTTPClientWithMiddleware:OCMProtocolMock(@protocol(MSGraphMiddleware))]; 37 | XCTAssertNotNil(customClient); 38 | } 39 | 40 | - (void)testCreationOfHTTPClientWithAuthProviderAndSessionConfiguration { 41 | MSHTTPClient *defaulClient = [MSClientFactory createHTTPClientWithAuthenticationProvider:self.mockAuthProvider andSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; 42 | XCTAssertNotNil(defaulClient); 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/HTTPClient/MSHTTPClientTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSGraphClientSDKTests.h" 7 | 8 | @interface MSURLSessionTask() 9 | 10 | - (void)taskCompletedWithData:(id)data response:(NSURLResponse *)response andError:(NSError *)error; 11 | 12 | @end 13 | 14 | 15 | @interface MSHTTPClientTests : MSGraphClientSDKTests 16 | @property NSData * demoData; 17 | @property NSURL *demoFileLocation; 18 | @end 19 | 20 | @implementation MSHTTPClientTests 21 | 22 | - (void)setUp { 23 | [super setUp]; 24 | self.demoData = [NSJSONSerialization dataWithJSONObject:@{@"initKey":@"initData"} options:0 error:nil]; 25 | self.demoFileLocation = [NSURL URLWithString:@"foo/bar/baz"]; 26 | 27 | } 28 | 29 | - (void)tearDown { 30 | // Put teardown code here. This method is called after the invocation of each test method in the class. 31 | [super tearDown]; 32 | } 33 | 34 | 35 | - (void)testDataTaskCreationAndExecution{ 36 | 37 | MSDataCompletionHandler dataCompletion = ^(NSData *data, NSURLResponse *response, NSError *error){ 38 | 39 | [self completionBlockCodeInvoked]; 40 | XCTAssertNil(error); 41 | XCTAssertNotNil(response); 42 | XCTAssertEqual(((NSHTTPURLResponse *)response).statusCode, MSExpectedResponseCodesOK); 43 | XCTAssertNotNil(data); 44 | 45 | }; 46 | 47 | XCTAssertThrows([self.mockClient dataTaskWithRequest:nil completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 48 | 49 | }]); 50 | MSURLSessionDataTask *dataTask = [self.mockClient dataTaskWithRequest:self.requestForMock completionHandler:dataCompletion]; 51 | XCTAssertNotNil(dataTask); 52 | 53 | 54 | MSURLSessionDataTask *partialTask = OCMPartialMock(dataTask); 55 | OCMStub([partialTask execute]).andDo(^(NSInvocation *invocation){ 56 | NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:MSGraphBaseURL] statusCode:MSExpectedResponseCodesOK HTTPVersion:@"foo" headerFields:nil]; 57 | [dataTask taskCompletedWithData:self->_demoData response:response andError:nil]; 58 | }); 59 | [dataTask execute]; 60 | [self checkCompletionBlockCodeInvoked]; 61 | } 62 | 63 | - (void)testDownloadTaskCreationAndExecution{ 64 | 65 | MSRawDownloadCompletionHandler downloadCompletion = ^(NSURL *fileUrl, NSURLResponse *response, NSError *error){ 66 | 67 | [self completionBlockCodeInvoked]; 68 | XCTAssertNil(error); 69 | XCTAssertNotNil(response); 70 | XCTAssertEqual(((NSHTTPURLResponse *)response).statusCode, MSExpectedResponseCodesOK); 71 | XCTAssertNotNil(fileUrl); 72 | 73 | }; 74 | 75 | XCTAssertThrows([self.mockClient downloadTaskWithRequest:nil completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) { 76 | 77 | }]); 78 | MSURLSessionDownloadTask *downloadTask = [self.mockClient downloadTaskWithRequest:self.requestForMock completionHandler:downloadCompletion]; 79 | XCTAssertNotNil(downloadTask); 80 | 81 | MSURLSessionDownloadTask *partialTask = OCMPartialMock(downloadTask); 82 | OCMStub([partialTask execute]).andDo(^(NSInvocation *invocation){ 83 | NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:MSGraphBaseURL] statusCode:MSExpectedResponseCodesOK HTTPVersion:@"foo" headerFields:nil]; 84 | [downloadTask taskCompletedWithData:self->_demoFileLocation response:response andError:nil]; 85 | }); 86 | [downloadTask execute]; 87 | [self checkCompletionBlockCodeInvoked]; 88 | } 89 | 90 | - (void)testUploadTaskCreationFromDataAndExecution{ 91 | MSRawUploadCompletionHandler uploadCompletion = ^(NSData *data, NSURLResponse *response, NSError *error){ 92 | 93 | [self completionBlockCodeInvoked]; 94 | XCTAssertNil(error); 95 | XCTAssertNotNil(response); 96 | XCTAssertEqual(((NSHTTPURLResponse *)response).statusCode, MSExpectedResponseCodesOK); 97 | XCTAssertNotNil(data); 98 | 99 | }; 100 | 101 | XCTAssertThrows([self.mockClient uploadTaskWithRequest:nil fromData:_demoData completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 102 | 103 | }]); 104 | XCTAssertThrows([self.mockClient uploadTaskWithRequest:self.requestForMock fromData:nil completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 105 | 106 | }]); 107 | 108 | MSURLSessionUploadTask *uploadTaskFromData = [self.mockClient uploadTaskWithRequest:self.requestForMock fromData:_demoData completionHandler:uploadCompletion]; 109 | 110 | XCTAssertNotNil(uploadTaskFromData); 111 | 112 | MSURLSessionUploadTask *partialTask = OCMPartialMock(uploadTaskFromData); 113 | OCMStub([partialTask execute]).andDo(^(NSInvocation *invocation){ 114 | NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:MSGraphBaseURL] statusCode:MSExpectedResponseCodesOK HTTPVersion:@"foo" headerFields:nil]; 115 | [uploadTaskFromData taskCompletedWithData:self->_demoData response:response andError:nil]; 116 | }); 117 | [uploadTaskFromData execute]; 118 | [self checkCompletionBlockCodeInvoked]; 119 | } 120 | 121 | - (void)testUploadTaskCreationFromFileAndExecution{ 122 | MSRawUploadCompletionHandler uploadCompletion = ^(NSData *data, NSURLResponse *response, NSError *error){ 123 | 124 | [self completionBlockCodeInvoked]; 125 | XCTAssertNil(error); 126 | XCTAssertNotNil(response); 127 | XCTAssertEqual(((NSHTTPURLResponse *)response).statusCode, MSExpectedResponseCodesOK); 128 | XCTAssertNotNil(data); 129 | 130 | }; 131 | 132 | 133 | XCTAssertThrows([self.mockClient uploadTaskWithRequest:nil fromFile:_demoFileLocation completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 134 | 135 | }]); 136 | XCTAssertThrows([self.mockClient uploadTaskWithRequest:self.requestForMock fromFile:nil completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 137 | 138 | }]); 139 | 140 | MSURLSessionUploadTask *uploadTaskFromFile = [self.mockClient uploadTaskWithRequest:self.requestForMock fromFile:_demoFileLocation completionHandler:uploadCompletion]; 141 | XCTAssertNotNil(uploadTaskFromFile); 142 | 143 | MSURLSessionUploadTask *partialTask = OCMPartialMock(uploadTaskFromFile); 144 | OCMStub([partialTask execute]).andDo(^(NSInvocation *invocation){ 145 | NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:MSGraphBaseURL] statusCode:MSExpectedResponseCodesOK HTTPVersion:@"foo" headerFields:nil]; 146 | [uploadTaskFromFile taskCompletedWithData:self->_demoData response:response andError:nil]; 147 | }); 148 | [uploadTaskFromFile execute]; 149 | [self checkCompletionBlockCodeInvoked]; 150 | } 151 | @end 152 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/HTTPClient/MSMiddlewareFactoryTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSGraphClientSDKTests.h" 7 | #import "MSMiddlewareFactory.h" 8 | 9 | @interface MSMiddlewareFactoryTests : MSGraphClientSDKTests 10 | 11 | @end 12 | 13 | @implementation MSMiddlewareFactoryTests 14 | 15 | - (void)setUp { 16 | [super setUp]; 17 | // Put setup code here. This method is called before the invocation of each test method in the class. 18 | } 19 | 20 | - (void)tearDown { 21 | // Put teardown code here. This method is called after the invocation of each test method in the class. 22 | [super tearDown]; 23 | } 24 | 25 | - (void)testCreateMiddlewareMethod { 26 | idauthHandler = [MSMiddlewareFactory createMiddleware:MSMiddlewareTypeAuthentication]; 27 | idhttpMiddleware = [MSMiddlewareFactory createMiddleware:MSMiddlewareTypeHTTP]; 28 | idrandomMiddleware = [MSMiddlewareFactory createMiddleware:4]; 29 | XCTAssertTrue([authHandler isKindOfClass:[MSAuthenticationHandler class]]); 30 | XCTAssertTrue([httpMiddleware isKindOfClass:[MSURLSessionManager class]]); 31 | XCTAssertNil(randomMiddleware); 32 | } 33 | 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/MSGraphClientSDKTests.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSGraphClientSDK.h" 7 | #import "OCMock.h" 8 | 9 | @interface MSGraphClientSDKTests : XCTestCase 10 | 11 | @property (nonatomic,retain) NSMutableURLRequest *requestForMock; 12 | @property (nonatomic,retain) NSURL *testBaseURL; 13 | @property (nonatomic,retain) id mockAuthProvider; 14 | @property (nonatomic,retain) id mockHttpProvider; 15 | @property (nonatomic,retain) MSHTTPClient *mockClient; 16 | @property (nonatomic) __block BOOL bCompletionBlockInvoked; 17 | 18 | -(void)completionBlockCodeInvoked; 19 | -(void)checkCompletionBlockCodeInvoked; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/MSGraphClientSDKTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import "MSGraphClientSDKTests.h" 6 | 7 | @implementation MSGraphClientSDKTests 8 | 9 | - (void)setUp { 10 | [super setUp]; 11 | // Put setup code here. This method is called before the invocation of each test method in the class. 12 | 13 | self.testBaseURL = [NSURL URLWithString:@"https://foo.com/bar/baz"]; 14 | self.requestForMock = [[NSMutableURLRequest alloc] initWithURL:self.testBaseURL]; 15 | self.mockAuthProvider = OCMProtocolMock(@protocol(MSAuthenticationProvider)); 16 | self.mockHttpProvider = OCMProtocolMock(@protocol(MSHttpProvider)); 17 | self.mockClient = OCMPartialMock([MSClientFactory createHTTPClientWithAuthenticationProvider:self.mockAuthProvider]); 18 | } 19 | 20 | - (void)tearDown { 21 | // Put teardown code here. This method is called after the invocation of each test method in the class. 22 | self.mockAuthProvider = nil; 23 | self.mockClient = nil; 24 | [super tearDown]; 25 | } 26 | 27 | -(void)completionBlockCodeInvoked{ 28 | _bCompletionBlockInvoked = YES; 29 | } 30 | -(void)checkCompletionBlockCodeInvoked{ 31 | XCTAssertTrue(_bCompletionBlockInvoked); 32 | } 33 | 34 | 35 | 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/Middleware/Implementations/MSAuthenticationHandlerTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | 6 | #import 7 | #import "MSGraphClientSDKTests.h" 8 | 9 | @interface MSAuthenticationHandler() 10 | @property (nonatomic, strong) id nextMiddleware; 11 | @end 12 | 13 | #define TestToken @"a1b2c3d4" 14 | 15 | @interface MSAuthenticationHandlerTests : MSGraphClientSDKTests 16 | 17 | @property (nonatomic, strong) MSAuthenticationHandler *authenticationHandler; 18 | @property (nonatomic, strong) MSURLSessionDataTask *mockDataTask; 19 | 20 | @end 21 | 22 | @implementation MSAuthenticationHandlerTests 23 | 24 | - (void)setUp { 25 | [super setUp]; 26 | self.authenticationHandler = [[MSAuthenticationHandler alloc] initWithAuthenticationProvider:self.mockAuthProvider]; 27 | 28 | [self.authenticationHandler setNextMiddleware:self.mockHttpProvider]; 29 | 30 | _mockDataTask = [[MSURLSessionDataTask alloc] initWithRequest:self.requestForMock client:self.mockClient]; 31 | // Put setup code here. This method is called before the invocation of each test method in the class. 32 | } 33 | 34 | - (void)tearDown { 35 | // Put teardown code here. This method is called after the invocation of each test method in the class. 36 | [super tearDown]; 37 | } 38 | 39 | - (void)testInit { 40 | MSAuthenticationHandler *handler = [[MSAuthenticationHandler alloc] initWithAuthenticationProvider:self.mockAuthProvider]; 41 | XCTAssertNotNil(handler); 42 | XCTAssertEqual(handler.authenticationProvider, self.mockAuthProvider); 43 | } 44 | 45 | - (void)testSetAuthenticationProvider { 46 | MSAuthenticationHandler *handler = [[MSAuthenticationHandler alloc] init]; 47 | [handler setAuthenticationProvider:self.mockAuthProvider]; 48 | XCTAssertEqual(handler.authenticationProvider, self.mockAuthProvider); 49 | } 50 | 51 | - (void)testExecuteWithSuccessInGettingToken { 52 | HTTPRequestCompletionHandler requestCompletion = ^(id data, NSURLResponse * _Nullable response, NSError * _Nullable error){ 53 | [self completionBlockCodeInvoked]; 54 | XCTAssertNil(error); 55 | XCTAssertNotNil(response); 56 | XCTAssertEqual(((NSHTTPURLResponse *)response).statusCode, MSExpectedResponseCodesOK); 57 | XCTAssertNotNil(data); 58 | }; 59 | //Mocking auth to provide a test token 60 | OCMStub([self.mockAuthProvider getAccessTokenForProviderOptions:[OCMArg any] andCompletion:[OCMArg any]]) 61 | .andDo(^(NSInvocation *invocation){ 62 | void (^completionHandler)(NSString *accessToken, NSError *error); 63 | [invocation getArgument:&completionHandler atIndex:3]; 64 | completionHandler(TestToken,nil); 65 | }); 66 | 67 | OCMStub([self.mockHttpProvider execute:[OCMArg any] withCompletionHandler:[OCMArg any]]).andDo((^(NSInvocation *invocation){ 68 | MSURLSessionDataTask *dataTask; 69 | [invocation getArgument:&dataTask atIndex:2]; 70 | NSString *authrizationValue = [NSString stringWithFormat:@"Bearer %@",TestToken]; 71 | XCTAssertEqualObjects([dataTask.request valueForHTTPHeaderField:@"Authorization"], authrizationValue); 72 | 73 | HTTPRequestCompletionHandler completionHandler; 74 | [invocation getArgument:&completionHandler atIndex:3]; 75 | NSHTTPURLResponse *OKResponse = [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:MSGraphBaseURL] statusCode:MSExpectedResponseCodesOK HTTPVersion:@"foo" headerFields:nil]; 76 | completionHandler([NSData new],OKResponse,nil); 77 | })); 78 | [self.authenticationHandler execute:_mockDataTask withCompletionHandler:requestCompletion]; 79 | [self checkCompletionBlockCodeInvoked]; 80 | } 81 | 82 | - (void)testExecuteWithErrorInGettingToken { 83 | HTTPRequestCompletionHandler requestCompletion = ^(id data, NSURLResponse * _Nullable response, NSError * _Nullable error){ 84 | [self completionBlockCodeInvoked]; 85 | XCTAssertNotNil(error); 86 | XCTAssertNil(response); 87 | XCTAssertEqual(error.code, 0); 88 | XCTAssertEqualObjects(error.domain, @"TestDomain"); 89 | XCTAssertNil(data); 90 | }; 91 | //Mocking auth to provide an error 92 | OCMStub([self.mockAuthProvider getAccessTokenForProviderOptions:[OCMArg any] andCompletion:[OCMArg any]]) 93 | .andDo(^(NSInvocation *invocation){ 94 | void (^completionHandler)(NSString *accessToken, NSError *error); 95 | [invocation getArgument:&completionHandler atIndex:3]; 96 | completionHandler(nil,[NSError errorWithDomain:@"TestDomain" code:0 userInfo:nil]); 97 | }); 98 | 99 | [self.authenticationHandler execute:_mockDataTask withCompletionHandler:requestCompletion]; 100 | [self checkCompletionBlockCodeInvoked]; 101 | } 102 | 103 | 104 | - (void)testSetNext { 105 | id tempMiddleware = OCMProtocolMock(@protocol(MSGraphMiddleware)); 106 | [self.authenticationHandler setNext:tempMiddleware]; 107 | XCTAssertEqualObjects(tempMiddleware, self.authenticationHandler.nextMiddleware); 108 | id tempMiddleware1 = OCMProtocolMock(@protocol(MSGraphMiddleware)); 109 | [self.authenticationHandler setNext:tempMiddleware1]; 110 | XCTAssertEqualObjects(self.authenticationHandler.nextMiddleware, tempMiddleware1); 111 | } 112 | 113 | @end 114 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/Middleware/Implementations/MSURLSessionTaskDelegateTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | 6 | #import 7 | #import "MSGraphClientSDKTests.h" 8 | 9 | @interface MSURLSessionTaskDelegate() 10 | 11 | @property (strong, nonatomic) NSProgress *progress; 12 | 13 | @property (strong, nonatomic) NSMutableData *mutableData; 14 | 15 | @property (strong, nonatomic) NSURL *downloadPath; 16 | 17 | @property (strong, nonatomic) MSURLSessionTaskCompletion completion; 18 | 19 | @end 20 | 21 | @interface MSURLSessionTaskDelegateTests : MSGraphClientSDKTests 22 | 23 | @property MSURLSessionTaskDelegate *taskDelegate; 24 | 25 | 26 | @end 27 | 28 | @implementation MSURLSessionTaskDelegateTests 29 | 30 | - (void)setUp { 31 | [super setUp]; 32 | MSURLSessionTaskCompletion taskCompletion = ^(id responseObject, NSURLResponse *response, NSError *error){ 33 | 34 | }; 35 | NSProgress *progress = [[NSProgress alloc] init]; 36 | self.taskDelegate = [[MSURLSessionTaskDelegate alloc] initWithProgressRef:&progress completion:taskCompletion]; 37 | } 38 | 39 | - (void)tearDown { 40 | self.taskDelegate = nil; 41 | [super tearDown]; 42 | } 43 | 44 | - (void)testInitWithNilProgressAndCompletion{ 45 | MSURLSessionTaskDelegate *taskDelegate = [[MSURLSessionTaskDelegate alloc] initWithProgressRef:nil completion:nil]; 46 | XCTAssertNil(taskDelegate.completion); 47 | XCTAssertNil(taskDelegate.progress); 48 | 49 | } 50 | 51 | - (void)testInitWithProgress{ 52 | MSURLSessionTaskCompletion taskCompletion = ^(id responseObject, NSURLResponse *response, NSError *error){ 53 | 54 | }; 55 | NSProgress *progress = [[NSProgress alloc] init]; 56 | MSURLSessionTaskDelegate *taskDelegate = [[MSURLSessionTaskDelegate alloc] initWithProgressRef:&progress completion:taskCompletion]; 57 | XCTAssertEqual(taskCompletion, taskDelegate.completion); 58 | XCTAssertEqual(progress, taskDelegate.progress); 59 | } 60 | 61 | - (void)testInitWithProgressPointingToNilProgress{ 62 | MSURLSessionTaskCompletion taskCompletion = ^(id responseObject, NSURLResponse *response, NSError *error){ 63 | 64 | }; 65 | NSProgress *progress = [[NSProgress alloc] init]; 66 | NSProgress *nilProgress = nil; 67 | progress = nilProgress; 68 | MSURLSessionTaskDelegate *taskDelegate = [[MSURLSessionTaskDelegate alloc] initWithProgressRef:&progress completion:taskCompletion]; 69 | XCTAssertEqual(taskCompletion, taskDelegate.completion); 70 | XCTAssertEqual(progress, taskDelegate.progress); 71 | } 72 | 73 | - (void)testUpdateProgress{ 74 | [self.taskDelegate updateProgressWithBytesSent:2300 expectedBytes:9200]; 75 | XCTAssertEqual(2300, self.taskDelegate.progress.completedUnitCount); 76 | XCTAssertEqual(9200, self.taskDelegate.progress.totalUnitCount); 77 | } 78 | 79 | - (void)testDidReceiveData{ 80 | [self.taskDelegate didReceiveData:[NSJSONSerialization dataWithJSONObject:@{@"initKey":@"initData"} options:0 error:nil]]; 81 | NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:self.taskDelegate.mutableData options:0 error:nil]; 82 | XCTAssertTrue([dictionary isEqualToDictionary:@{@"initKey":@"initData"}]); 83 | } 84 | 85 | - (void)testTaskDidCompleteWithError{ 86 | MSURLSessionTaskCompletion taskCompletion = ^(id responseObject, NSURLResponse *response, NSError *error){ 87 | [self completionBlockCodeInvoked]; 88 | XCTAssertNotNil(responseObject); 89 | XCTAssertTrue([responseObject isKindOfClass:[NSData class]]); 90 | XCTAssertNil(response); 91 | XCTAssertNil(error); 92 | 93 | }; 94 | 95 | MSURLSessionTaskDelegate *taskDelegate = [[MSURLSessionTaskDelegate alloc] initWithProgressRef:nil completion:taskCompletion]; 96 | 97 | NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; 98 | NSURLSessionTask *sessionTask = [session dataTaskWithRequest:self.requestForMock]; 99 | 100 | [taskDelegate didReceiveData:[NSJSONSerialization dataWithJSONObject:@{@"initKey":@"initData"} options:0 error:nil]]; 101 | 102 | [taskDelegate task:sessionTask didCompleteWithError:nil]; 103 | 104 | [self checkCompletionBlockCodeInvoked]; 105 | } 106 | 107 | - (void)testTaskDidCompleteWithErrorForFileDownload{ 108 | MSURLSessionTaskCompletion taskCompletion = ^(id responseObject, NSURLResponse *response, NSError *error){ 109 | [self completionBlockCodeInvoked]; 110 | XCTAssertNotNil(responseObject); 111 | XCTAssertTrue([responseObject isKindOfClass:[NSURL class]]); 112 | XCTAssertNil(response); 113 | XCTAssertNil(error); 114 | 115 | }; 116 | 117 | MSURLSessionTaskDelegate *taskDelegate = [[MSURLSessionTaskDelegate alloc] initWithProgressRef:nil completion:taskCompletion]; 118 | 119 | NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; 120 | NSURLSessionTask *sessionTask = [session dataTaskWithRequest:self.requestForMock]; 121 | 122 | [taskDelegate task:sessionTask didCompleteDownload:[NSURL URLWithString:@"file://var/dld.tmp"]]; 123 | 124 | [taskDelegate task:sessionTask didCompleteWithError:nil]; 125 | 126 | [self checkCompletionBlockCodeInvoked]; 127 | } 128 | 129 | - (void)testTaskDidCompleteDownload{ 130 | NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; 131 | NSURLSessionTask *sessionTask = [session dataTaskWithRequest:self.requestForMock]; 132 | [self.taskDelegate task:sessionTask didCompleteDownload:[NSURL URLWithString:@"file://var/dld.tmp"]]; 133 | XCTAssertTrue([self.taskDelegate.downloadPath.absoluteString isEqualToString:@"file://var/dld.tmp"]); 134 | } 135 | 136 | - (void)testTaskDidRedirect { 137 | MSURLSessionTaskCompletion taskCompletion = ^(id responseObject, NSURLResponse *response, NSError *error){ 138 | [self completionBlockCodeInvoked]; 139 | XCTAssertNil(responseObject); 140 | XCTAssertNotNil(response); 141 | XCTAssertEqual(((NSHTTPURLResponse *)response).statusCode, MSExpectedResponseCodesSeeOther); 142 | XCTAssertNil(error); 143 | 144 | }; 145 | 146 | MSURLSessionTaskDelegate *taskDelegate = [[MSURLSessionTaskDelegate alloc] initWithProgressRef:nil completion:taskCompletion]; 147 | 148 | NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; 149 | NSURLSessionTask *sessionTask = [session dataTaskWithRequest:self.requestForMock]; 150 | 151 | NSHTTPURLResponse *redirectResponse = [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:MSGraphBaseURL] statusCode:MSExpectedResponseCodesSeeOther HTTPVersion:@"foo" headerFields:nil]; 152 | [taskDelegate task:sessionTask didRedirectWithResponse:redirectResponse]; 153 | 154 | [self checkCompletionBlockCodeInvoked]; 155 | } 156 | 157 | @end 158 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/Middleware/Options/MSAuthenticationHandlerOptionsTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // MSAuthenticationHandlerOptionsTests.m 3 | // MSGraphClientSDKTests 4 | // 5 | // Created by Vikas Dadheech on 26/04/19. 6 | // Copyright © 2019 Vikas Dadheech. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MSGraphClientSDKTests.h" 11 | @interface MSAuthenticationHandlerOptionsTests : MSGraphClientSDKTests 12 | 13 | @end 14 | 15 | @implementation MSAuthenticationHandlerOptionsTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testSuccfullInit { 28 | id providerOptions = OCMProtocolMock(@protocol(MSAuthenticationProviderOptions)); 29 | MSAuthenticationHandlerOptions *authHandlerOptions = [[MSAuthenticationHandlerOptions alloc] initWithAuthenticationProvider:self.mockAuthProvider andAuthProviderOptions:providerOptions]; 30 | 31 | XCTAssertEqual(authHandlerOptions.authenticationProvider, self.mockAuthProvider); 32 | XCTAssertEqual(authHandlerOptions.middlewareOptionsType, MSMiddlewareOptionsTypeAuth); 33 | XCTAssertEqual(authHandlerOptions.authenticationProviderOptions, providerOptions); 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/Middleware/Options/MSRedirectHandlerOptionsTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSGraphClientSDKTests.h" 7 | 8 | @interface MSRedirectHandlerOptionsTests : MSGraphClientSDKTests 9 | 10 | @end 11 | 12 | @implementation MSRedirectHandlerOptionsTests 13 | 14 | - (void)setUp { 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | [super setUp]; 17 | } 18 | 19 | - (void)tearDown { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | [super tearDown]; 22 | } 23 | 24 | - (void)testInit { 25 | MSRedirectHandlerOptions *redirectOptions = [[MSRedirectHandlerOptions alloc] init]; 26 | 27 | XCTAssertNotNil(redirectOptions); 28 | XCTAssertEqual(redirectOptions.maxRedirects, 5); 29 | XCTAssertEqual(redirectOptions.middlewareOptionsType, MSMiddlewareTypeRedirect); 30 | } 31 | 32 | - (void)testInitWithRedirects { 33 | NSError *error; 34 | MSRedirectHandlerOptions *redirectOptions = [[MSRedirectHandlerOptions alloc] initWithMaxRedirects:10 andError:&error]; 35 | 36 | XCTAssertNil(error); 37 | XCTAssertNotNil(redirectOptions); 38 | XCTAssertEqual(redirectOptions.maxRedirects, 10); 39 | XCTAssertEqual(redirectOptions.middlewareOptionsType, MSMiddlewareTypeRedirect); 40 | } 41 | 42 | - (void)testInitWithRedirectsLimitCrossed { 43 | NSError *error; 44 | MSRedirectHandlerOptions *redirectOptions = [[MSRedirectHandlerOptions alloc] initWithMaxRedirects:21 andError:&error]; 45 | 46 | XCTAssertNotNil(error); 47 | XCTAssertNil(redirectOptions); 48 | XCTAssertEqual(error.domain, MSErrorDomain); 49 | XCTAssertEqual(error.code, MSCLientErrorCodeSDKUpperLimitReached); 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/Middleware/Options/MSRetryHandlerOptionsTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | /// 4 | 5 | #import 6 | #import "MSGraphClientSDKTests.h" 7 | 8 | @interface MSRetryHandlerOptionsTests : MSGraphClientSDKTests 9 | 10 | @end 11 | 12 | @implementation MSRetryHandlerOptionsTests 13 | 14 | - (void)setUp { 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | [super setUp]; 17 | } 18 | 19 | - (void)tearDown { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | [super tearDown]; 22 | } 23 | 24 | - (void)testInit { 25 | MSRetryHandlerOptions *retryOptions = [[MSRetryHandlerOptions alloc] init]; 26 | 27 | XCTAssertNotNil(retryOptions); 28 | XCTAssertEqual(retryOptions.delay, 3); 29 | XCTAssertEqual(retryOptions.maxRetries, 3); 30 | XCTAssertEqual(retryOptions.middlewareOptionsType, MSMiddlewareTypeRetry); 31 | } 32 | 33 | - (void)testInitWithDelayAndRetries { 34 | NSError *error; 35 | MSRetryHandlerOptions *retryOptions = [[MSRetryHandlerOptions alloc] initWithDelay:5 maxRetries:5 andError:&error]; 36 | 37 | XCTAssertNil(error); 38 | XCTAssertNotNil(retryOptions); 39 | XCTAssertEqual(retryOptions.delay, 5); 40 | XCTAssertEqual(retryOptions.maxRetries, 5); 41 | XCTAssertEqual(retryOptions.middlewareOptionsType, MSMiddlewareTypeRetry); 42 | } 43 | 44 | - (void)testInitWithDelayLimitCrossed { 45 | NSError *error; 46 | MSRetryHandlerOptions *retryOptions = [[MSRetryHandlerOptions alloc] initWithDelay:200 maxRetries:5 andError:&error]; 47 | 48 | XCTAssertNotNil(error); 49 | XCTAssertNil(retryOptions); 50 | XCTAssertEqual(error.domain, MSErrorDomain); 51 | XCTAssertEqual(error.code, MSCLientErrorCodeSDKUpperLimitReached); 52 | } 53 | 54 | - (void)testInitWithRetryLimitCrossed { 55 | NSError *error; 56 | MSRetryHandlerOptions *retryOptions = [[MSRetryHandlerOptions alloc] initWithDelay:5 maxRetries:12 andError:&error]; 57 | 58 | XCTAssertNotNil(error); 59 | XCTAssertNil(retryOptions); 60 | XCTAssertEqual(error.domain, MSErrorDomain); 61 | XCTAssertEqual(error.code, MSCLientErrorCodeSDKUpperLimitReached); 62 | } 63 | 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/Resources/BatchResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "responses": [ 3 | { 4 | "id": "1", 5 | "status": 302, 6 | "headers": { 7 | "location": "https://b0mpua-by3301.files.1drv.com/y23vmagahszhxzlcvhasdhasghasodfi" 8 | } 9 | }, 10 | { 11 | "id": "3", 12 | "status": 401, 13 | "body": { 14 | "error": { 15 | "code": "Forbidden", 16 | "message": "..." 17 | } 18 | } 19 | }, 20 | { 21 | "id": "2", 22 | "status": 200, 23 | "body": { 24 | "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(microsoft.graph.plannerTask)", 25 | "value": [] 26 | } 27 | }, 28 | { 29 | "id": "4", 30 | "status": 204, 31 | "body": null 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/Resources/LargeFileUploadResource.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-sdk-objc/1733c3cdd7afe9a0aeffc35c2635eb0cec59b264/MSGraphClientSDK/MSGraphClientSDKTests/Resources/LargeFileUploadResource.bmp -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/Resources/UserPhoto.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoftgraph/msgraph-sdk-objc/1733c3cdd7afe9a0aeffc35c2635eb0cec59b264/MSGraphClientSDK/MSGraphClientSDKTests/Resources/UserPhoto.jpg -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/SessionTask/MSURLSessionDataTaskTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | 6 | 7 | #import 8 | #import "MSGraphClientSDKTests.h" 9 | 10 | @interface MSURLSessionTask() 11 | 12 | - (void)taskCompletedWithData:(id)data response:(NSURLResponse *)response andError:(NSError *)error; 13 | 14 | @end 15 | 16 | @interface MSURLSessionDataTaskTests : MSGraphClientSDKTests 17 | 18 | @end 19 | 20 | @implementation MSURLSessionDataTaskTests 21 | 22 | - (void)setUp { 23 | [super setUp]; 24 | } 25 | 26 | - (void)tearDown { 27 | [super tearDown]; 28 | } 29 | - (void)testMSURLSessionDataTaskInit{ 30 | XCTAssertThrows([[MSURLSessionDataTask alloc] initWithRequest:nil client:self.mockClient completion:^(NSData *data, NSURLResponse *response, NSError *error) { 31 | }]); 32 | XCTAssertThrows([[MSURLSessionDataTask alloc] initWithRequest:self.requestForMock client:nil completion:^(NSData *data, NSURLResponse *response, NSError *error) { 33 | }]); 34 | MSURLSessionDataTask *dataTask = [[MSURLSessionDataTask alloc] initWithRequest:self.requestForMock client:self.mockClient completion: nil]; 35 | XCTAssertNotNil(dataTask); 36 | } 37 | 38 | - (void)testDataTaskCompletion{ 39 | MSDataCompletionHandler requestCompletion = ^(NSData *data, NSURLResponse * _Nullable response, NSError * _Nullable error){ 40 | 41 | [self completionBlockCodeInvoked]; 42 | XCTAssertNil(error); 43 | XCTAssertNotNil(response); 44 | XCTAssertNotNil(data); 45 | }; 46 | 47 | MSURLSessionDataTask *dataTask = [[MSURLSessionDataTask alloc] initWithRequest:self.requestForMock client:self.mockClient completion:requestCompletion]; 48 | id middleware = OCMPartialMock(dataTask.client.middleware); 49 | OCMStub([middleware execute:[OCMArg any] withCompletionHandler:[OCMArg any]]).andDo(^(NSInvocation *invocation){ 50 | 51 | NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:MSGraphBaseURL] statusCode:MSExpectedResponseCodesOK HTTPVersion:@"foo" headerFields:nil]; 52 | [dataTask taskCompletedWithData:[NSData new] response:response andError:nil]; 53 | }); 54 | 55 | [dataTask execute]; 56 | [self checkCompletionBlockCodeInvoked]; 57 | 58 | } 59 | 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/SessionTask/MSURLSessionDownloadTaskTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | 6 | #import 7 | #import "MSGraphClientSDKTests.h" 8 | 9 | @interface MSURLSessionDownloadTask() 10 | 11 | - (NSProgress *)createProgress; 12 | - (void)taskCompletedWithData:(id)data response:(NSURLResponse *)response andError:(NSError *)error; 13 | 14 | @end 15 | 16 | @interface MSURLSessionDownloadTaskTests : MSGraphClientSDKTests 17 | 18 | @property (nonatomic,retain) NSURL *fileLocation; 19 | @end 20 | 21 | @implementation MSURLSessionDownloadTaskTests 22 | 23 | - (void)setUp { 24 | [super setUp]; 25 | self.fileLocation = [NSURL URLWithString:@"foo/bar/baz"]; 26 | } 27 | 28 | - (void)tearDown { 29 | // Put teardown code here. This method is called after the invocation of each test method in the class. 30 | [super tearDown]; 31 | } 32 | - (void)testMSURLSessionDownloadTaskInit{ 33 | XCTAssertThrows([[MSURLSessionDownloadTask alloc] initWithRequest:nil client:self.mockClient completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) { 34 | }]); 35 | XCTAssertThrows([[MSURLSessionDownloadTask alloc] initWithRequest:self.requestForMock client:nil completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) { 36 | }]); 37 | 38 | MSURLSessionDownloadTask *downloadTask = [[MSURLSessionDownloadTask alloc] initWithRequest:self.requestForMock client:self.mockClient completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) { 39 | }]; 40 | XCTAssertNotNil(downloadTask); 41 | } 42 | 43 | - (void)testCreateProgress{ 44 | MSURLSessionDownloadTask *downloadTask = [[MSURLSessionDownloadTask alloc] initWithRequest:self.requestForMock client:self.mockClient completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) { 45 | }]; 46 | NSProgress *progress = [downloadTask createProgress]; 47 | 48 | XCTAssertEqual(progress, downloadTask.progress); 49 | 50 | } 51 | 52 | - (void)testDownloadTaskCompletion{ 53 | MSDownloadCompletionHandler requestCompletion = ^(NSURL *fileURL, NSURLResponse * _Nullable response, NSError * _Nullable error){ 54 | [self completionBlockCodeInvoked]; 55 | XCTAssertNil(error); 56 | XCTAssertNotNil(response); 57 | XCTAssertNotNil(fileURL); 58 | }; 59 | 60 | MSURLSessionDownloadTask *downloadTask = [[MSURLSessionDownloadTask alloc] initWithRequest:self.requestForMock client:self.mockClient completionHandler:requestCompletion]; 61 | id middleware = OCMPartialMock(downloadTask.client.middleware); 62 | OCMStub([middleware execute:[OCMArg any] withCompletionHandler:[OCMArg any]]).andDo(^(NSInvocation *invocation){ 63 | 64 | NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:MSGraphBaseURL] statusCode:MSExpectedResponseCodesOK HTTPVersion:@"foo" headerFields:nil]; 65 | [downloadTask taskCompletedWithData:[NSURL URLWithString:@"/foo.tmp"] response:response andError:nil]; 66 | }); 67 | 68 | [downloadTask execute]; 69 | [self checkCompletionBlockCodeInvoked]; 70 | 71 | } 72 | @end 73 | -------------------------------------------------------------------------------- /MSGraphClientSDK/MSGraphClientSDKTests/SessionTask/MSURLSessionUploadTaskTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. 3 | // 4 | 5 | #import 6 | #import "MSGraphClientSDKTests.h" 7 | 8 | @interface MSURLSessionUploadTask() 9 | 10 | - (NSProgress *)createProgress; 11 | - (void)taskCompletedWithData:(id)data response:(NSURLResponse *)response andError:(NSError *)error; 12 | 13 | @end 14 | 15 | @interface MSURLSessionUploadTaskTests : MSGraphClientSDKTests 16 | @property NSData * demoData; 17 | @property NSURL *demoFileLocation; 18 | 19 | 20 | @end 21 | 22 | @implementation MSURLSessionUploadTaskTests 23 | 24 | - (void)setUp { 25 | [super setUp]; 26 | self.demoData = [NSJSONSerialization dataWithJSONObject:@{@"initKey":@"initData"} options:0 error:nil]; 27 | self.demoFileLocation = [NSURL URLWithString:@"foo/bar/baz"]; 28 | } 29 | 30 | - (void)tearDown { 31 | [super tearDown]; 32 | } 33 | /** 34 | ** Test [MSURLSessionUploadTask init] 35 | ** 36 | */ 37 | - (void)testMSURLSessionUploadTaskInit{ 38 | 39 | XCTAssertThrows([[MSURLSessionUploadTask alloc] initWithRequest:nil data:_demoData client:self.mockClient completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 40 | }]); 41 | XCTAssertThrows([[MSURLSessionUploadTask alloc] initWithRequest:self.requestForMock data:nil client:self.mockClient completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 42 | }]); 43 | XCTAssertThrows([[MSURLSessionUploadTask alloc] initWithRequest:self.requestForMock data:_demoData client:nil completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 44 | }]); 45 | 46 | 47 | XCTAssertThrows([[MSURLSessionUploadTask alloc] initWithRequest:nil fromFile:_demoFileLocation client:self.mockClient completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 48 | }]); 49 | XCTAssertThrows([[MSURLSessionUploadTask alloc] initWithRequest:self.requestForMock fromFile:nil client:self.mockClient completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 50 | }]); 51 | XCTAssertThrows([[MSURLSessionUploadTask alloc] initWithRequest:self.requestForMock fromFile:_demoFileLocation client:nil completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 52 | }]); 53 | 54 | 55 | MSURLSessionUploadTask *uploadTaskFromData = [[MSURLSessionUploadTask alloc] initWithRequest:self.requestForMock data:_demoData client:self.mockClient completionHandler:nil]; 56 | MSURLSessionUploadTask *uploadTaskFromFile = [[MSURLSessionUploadTask alloc] initWithRequest:self.requestForMock fromFile:_demoFileLocation client:self.mockClient completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 57 | }]; 58 | XCTAssertNotNil(uploadTaskFromData); 59 | XCTAssertNotNil(uploadTaskFromFile); 60 | } 61 | 62 | - (void)testCreateProgress{ 63 | MSURLSessionUploadTask *uploadTask = [[MSURLSessionUploadTask alloc] initWithRequest:self.requestForMock data:_demoData client:self.mockClient completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 64 | } ]; 65 | NSProgress *progress = [uploadTask createProgress]; 66 | 67 | XCTAssertEqual(progress, uploadTask.progress); 68 | 69 | } 70 | 71 | - (void)testUploadTaskCompletion{ 72 | MSUploadCompletionHandler requestCompletion = ^(NSData *data, NSURLResponse * _Nullable response, NSError * _Nullable error){ 73 | 74 | [self completionBlockCodeInvoked]; 75 | XCTAssertNil(error); 76 | XCTAssertNotNil(response); 77 | XCTAssertNotNil(data); 78 | }; 79 | 80 | MSURLSessionUploadTask *uploadTask = [[MSURLSessionUploadTask alloc] initWithRequest:self.requestForMock data:_demoData client:self.mockClient completionHandler:requestCompletion]; 81 | id middleware = OCMPartialMock(uploadTask.client.middleware); 82 | OCMStub([middleware execute:[OCMArg any] withCompletionHandler:[OCMArg any]]).andDo(^(NSInvocation *invocation){ 83 | 84 | NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:MSGraphBaseURL] statusCode:MSExpectedResponseCodesOK HTTPVersion:@"foo" headerFields:nil]; 85 | [uploadTask taskCompletedWithData:[NSData new] response:response andError:nil]; 86 | }); 87 | 88 | [uploadTask execute]; 89 | [self checkCompletionBlockCodeInvoked]; 90 | 91 | } 92 | 93 | 94 | @end 95 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Microsoft Graph SDK for ObjC 3 | 4 | 5 | Get started with the Microsoft Graph SDK for ObjectiveC by integrating it into your iOS and MacOS applications! 6 | 7 | ## Installation 8 | 9 | 10 | ### Using CocoaPods 11 | 12 | You can use [CocoaPods](https://cocoapods.org/) to remain up to date with our latest version. Include the following line in your podfile: 13 | ``` 14 | pod 'MSGraphClientSDK' 15 | ``` 16 | 17 | 18 | ### Using Carthage 19 | 20 | 21 | 22 | You can also chose to use [Carthage](https://github.com/Carthage/Carthage) for package management. 23 | 24 | 25 | 26 | 1. Install Carthage on your Mac using a download from their website or if using Homebrew `brew install carthage`. 27 | 28 | 2. You must create a `Cartfile` that lists the MSGraphClientSDK library for this project on Github. 29 | 30 | 31 | 32 | ``` 33 | 34 | github "microsoftgraph/msgraph-sdk-objc" "tags/" 35 | 36 | ``` 37 | 38 | 39 | 40 | 3. Run `carthage update`. This will fetch dependencies into a `Carthage/Checkouts` folder, then build the MSGraphClientSDK library. 41 | 42 | 4. On your application target's “General” settings tab, in the “Linked Frameworks and Libraries” section, drag and drop the `MSGraphClientSDK.framework` from the `Carthage/Build` folder on disk. 43 | 44 | 5. On your application target's “Build Phases” settings tab, click the “+” icon and choose “New Run Script Phase”. Create a Run Script in which you specify your shell (ex: `/bin/sh`), add the following contents to the script area below the shell: 45 | 46 | 47 | 48 | ```sh 49 | 50 | /usr/local/bin/carthage copy-frameworks 51 | 52 | ``` 53 | 54 | 55 | 56 | and add the paths to the frameworks you want to use under “Input Files”, e.g.: 57 | 58 | 59 | 60 | ``` 61 | 62 | $(SRCROOT)/Carthage/Build/iOS/MSGraphClientSDK.framework 63 | 64 | ``` 65 | 66 | This script works around an [App Store submission bug](http://www.openradar.me/radar?id=6409498411401216) triggered by universal binaries and ensures that necessary bitcode-related files and dSYMs are copied when archiving. 67 | 68 | 69 | 70 | With the debug information copied into the built products directory, Xcode will be able to symbolicate the stack trace whenever you stop at a breakpoint. This will also enable you to step through third-party code in the debugger. 71 | 72 | 73 | 74 | When archiving your application for submission to the App Store or TestFlight, Xcode will also copy these files into the dSYMs subdirectory of your application’s `.xcarchive` bundle. 75 | 76 | 77 | 78 | ## Prerequisites 79 | 80 | Each network call to Microsoft Graph needs to be authenticated. For that purpose, creation of an instance of MSHTTPClient takes an MSAuthenticationProvider protocol's instance as parameter. 81 | 82 | You can create the MSAuthenticationProvider instance via two ways: 83 | 84 | ### Using [MSGraphMSALAuthProvider](https://github.com/microsoftgraph/msgraph-sdk-objc-auth) 85 | 86 | This repo handles the authentication scenarios via [MSAL](https://github.com/AzureAD/microsoft-authentication-library-for-objc) 87 | 88 | ### By writing your own implmentation of MSAuthenticationProvider 89 | 90 | You can also chose to handle authentication via any means that suits your needs. You need to follow below steps so that this SDK can interact with your authentication mechanism. 91 | 92 | 1. After integrating the SDK, you will have to provide implmentation for MSAuthenticationProvider by creating a new file. 93 | 94 | 2. In this file, write an implmentation for below method of MSAuthenticationProvider 95 | 96 | ``` 97 | 98 | - (void) getAccessTokenWithCompletion:(void (^)(NSString *accessToken, NSError *error))completion; 99 | 100 | ``` 101 | 102 | This implmentation should be able to talk to your authentication mechanism in order to get the access token or any error which occurred during the process and return it in completion block. 103 | 104 | ## How to use SDK 105 | 106 | 107 | 108 | Assuming you have gone thorugh the above steps, you will now have : 109 | 110 | 111 | 112 | 1. A .xcworkspace file integrated with MSGraphClientSDK pod or MSGraphClientSDK.framework integrated in your project. 113 | 114 | 115 | 116 | 2. Instance of a class implementing MSAuthenticationProvider protocol. 117 | 118 | 119 | 120 | After above steps, you need to follow below steps: 121 | 122 | 123 | 124 | 1. Create an instance of MSHTTPClient from MSClientFactory in below fashion: 125 | 126 | ``` 127 | 128 | MSHTTPClient *httpClient = [MSClientFactory createHTTPClientWithAuthenticationProvider:authenticationProvider]; 129 | 130 | ``` 131 | 132 | 2. Configure a native request object which might look like something below: 133 | 134 | ``` 135 | 136 | NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[MSGraphBaseURL stringByAppendingString:@"/me"]]]; 137 | 138 | ``` 139 | 140 | 3. Create an MSURLSessionTask (in case of our example a DataTask) object with the help of MSHTTPClient in below fashion and call execute on it: 141 | 142 | ``` 143 | 144 | MSURLSessionDataTask *meDataTask = [httpClient dataTaskWithRequest:urlRequest 145 | 146 | completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 147 | 148 | //Do something 149 | 150 | }]; 151 | 152 | [meDataTask execute]; 153 | 154 | ``` 155 | 156 | 157 | 158 | And that's it. You have now successfully made call to graph server asking information about the user. 159 | 160 | ## Usage Resources 161 | 162 | * [Batching](/Docs/Content/Batching.md) 163 | * [Page Iterator](/Docs/Tasks/PageIterator.md) 164 | * [Large File Upload Task](/Docs/Tasks/LargeFileUpload.md) 165 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | --------------------------------------------------------------------------------