├── Podfile
├── Microsoft Tasks
├── en.lproj
│ └── InfoPlist.strings
├── Images.xcassets
│ ├── AppIcon.appiconset
│ │ ├── iPhone-1.png
│ │ ├── iPhone-4.png
│ │ ├── iPhone-5.png
│ │ ├── iPhone-6.png
│ │ ├── iPhone-2-1.png
│ │ ├── iPhone-5-5.png
│ │ └── Contents.json
│ └── LaunchImage.launchimage
│ │ └── Contents.json
├── SamplesSelectUserViewController.h
├── samplesTaskItem.m
├── SamplesAppSettingsController.h
├── Microsoft_Tasks.xcdatamodeld
│ ├── .xccurrentversion
│ └── Microsoft_Tasks.xcdatamodel
│ │ └── contents
├── NSDictionary+UrlEncoding.h
├── samplesLoginViewController.h
├── samplesTaskListTableViewController.h
├── main.m
├── Microsoft Tasks.entitlements
├── samplesTaskItem.h
├── Microsoft Tasks-Prefix.pch
├── sampleAddTaskItemViewController.h
├── samplesPolicyData.h
├── SamplesApplicationData.h
├── samplesShowClaimsViewController.h
├── samplesAppDelegate.h
├── settings.plist
├── samplesPolicyData.m
├── NSDictionary+UrlEncoding.m
├── SamplesApplicationData.m
├── samplesWebAPIConnector.h
├── samplesShowClaimsViewController.m
├── Microsoft Tasks-Info.plist
├── sampleAddTaskItemViewController.m
├── samplesLoginViewController.m
├── SamplesAppSettingsController.m
├── samplesAppDelegate.m
├── samplesTaskListTableViewController.m
├── SamplesSelectUserViewController.m
├── samplesWebAPIConnector.m
└── Main_iPhone.storyboard
├── Microsoft TasksTests
├── en.lproj
│ └── InfoPlist.strings
├── Microsoft_TasksTests.m
└── Microsoft TasksTests-Info.plist
├── HockeySDK-iOS
└── BuildAgent
├── Microsoft Tasks.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── project.pbxproj
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
└── README.md
/Podfile:
--------------------------------------------------------------------------------
1 | target 'Microsoft Tasks' do
2 |
3 | pod 'ADALiOS'
4 |
5 | end
6 |
--------------------------------------------------------------------------------
/Microsoft Tasks/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/Microsoft TasksTests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/HockeySDK-iOS/BuildAgent:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tikyau/active-directory-ios/master/HockeySDK-iOS/BuildAgent
--------------------------------------------------------------------------------
/Microsoft Tasks/Images.xcassets/AppIcon.appiconset/iPhone-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tikyau/active-directory-ios/master/Microsoft Tasks/Images.xcassets/AppIcon.appiconset/iPhone-1.png
--------------------------------------------------------------------------------
/Microsoft Tasks/Images.xcassets/AppIcon.appiconset/iPhone-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tikyau/active-directory-ios/master/Microsoft Tasks/Images.xcassets/AppIcon.appiconset/iPhone-4.png
--------------------------------------------------------------------------------
/Microsoft Tasks/Images.xcassets/AppIcon.appiconset/iPhone-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tikyau/active-directory-ios/master/Microsoft Tasks/Images.xcassets/AppIcon.appiconset/iPhone-5.png
--------------------------------------------------------------------------------
/Microsoft Tasks/Images.xcassets/AppIcon.appiconset/iPhone-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tikyau/active-directory-ios/master/Microsoft Tasks/Images.xcassets/AppIcon.appiconset/iPhone-6.png
--------------------------------------------------------------------------------
/Microsoft Tasks/Images.xcassets/AppIcon.appiconset/iPhone-2-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tikyau/active-directory-ios/master/Microsoft Tasks/Images.xcassets/AppIcon.appiconset/iPhone-2-1.png
--------------------------------------------------------------------------------
/Microsoft Tasks/Images.xcassets/AppIcon.appiconset/iPhone-5-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tikyau/active-directory-ios/master/Microsoft Tasks/Images.xcassets/AppIcon.appiconset/iPhone-5-5.png
--------------------------------------------------------------------------------
/Microsoft Tasks.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Microsoft Tasks/SamplesSelectUserViewController.h:
--------------------------------------------------------------------------------
1 |
2 | #import
3 |
4 | @interface SamplesSelectUserViewController : UITableViewController
5 |
6 | - (IBAction)addPressed:(id)sender;
7 |
8 | - (IBAction)cancelPressed:(id)sender;
9 | @end
10 |
--------------------------------------------------------------------------------
/Microsoft Tasks/samplesTaskItem.m:
--------------------------------------------------------------------------------
1 | //
2 | // samplesTaskItem.m
3 | // Microsoft Tasks
4 | //
5 | // Created by Brandon Werner on 3/5/14.
6 | // Copyright (c) 2014 Microsoft. All rights reserved.
7 | //
8 |
9 | #import "samplesTaskItem.h"
10 |
11 | @implementation samplesTaskItem
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Microsoft Tasks/SamplesAppSettingsController.h:
--------------------------------------------------------------------------------
1 |
2 | #import
3 |
4 | @interface SamplesAppSettingsController : UIViewController
5 |
6 | - (IBAction)savePressed:(id)sender;
7 |
8 | - (IBAction)clearKeychainPressed:(id)sender;
9 |
10 | - (IBAction)cancelPressed:(id)sender;
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | .DS_Store
3 | */build/*
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | profile
14 | *.moved-aside
15 | DerivedData
16 | .idea/
17 | *.hmap
18 | *.xccheckout
19 |
20 | #CocoaPods
21 | Pods
22 |
--------------------------------------------------------------------------------
/Microsoft Tasks/Microsoft_Tasks.xcdatamodeld/.xccurrentversion:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | _XCCurrentVersionName
6 | Microsoft_Tasks.xcdatamodel
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Microsoft Tasks/NSDictionary+UrlEncoding.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSDictionary+UrlEncoding.h
3 | // Microsoft Tasks
4 | //
5 | // Created by Brandon Werner on 4/21/15.
6 | // Copyright (c) 2015 Microsoft. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSDictionary (UrlEncoding)
12 |
13 | -(NSString*) urlEncodedString;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Microsoft Tasks/samplesLoginViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // samplesLoginViewController.h
3 | // Microsoft Tasks
4 | //
5 | // Created by Brandon Werner on 4/21/15.
6 | // Copyright (c) 2015 Microsoft. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface samplesLoginViewController : UIViewController
12 | - (IBAction)signInPressed:(id)sender;
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/Microsoft Tasks/samplesTaskListTableViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // samplesTaskListTableViewController.h
3 | // Microsoft Tasks
4 | //
5 | // Created by Brandon Werner on 3/4/14.
6 | // Copyright (c) 2014 Microsoft. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface samplesTaskListTableViewController : UITableViewController
12 |
13 |
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Microsoft Tasks/Microsoft_Tasks.xcdatamodeld/Microsoft_Tasks.xcdatamodel/contents:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Microsoft Tasks/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // Microsoft Tasks
4 | //
5 | // Created by Brandon Werner on 3/4/14.
6 | // Copyright (c) 2014 Microsoft. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "samplesAppDelegate.h"
12 |
13 | int main(int argc, char * argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([samplesAppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Microsoft Tasks/Microsoft Tasks.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | keychain-access-groups
6 |
7 | $(AppIdentifierPrefix)com.microsoft.adalcache
8 | $(AppIdentifierPrefix)com.microsoft.workplacejoin
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Microsoft Tasks/samplesTaskItem.h:
--------------------------------------------------------------------------------
1 | //
2 | // samplesTaskItem.h
3 | // Microsoft Tasks
4 | //
5 | // Created by Brandon Werner on 3/5/14.
6 | // Copyright (c) 2014 Microsoft. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface samplesTaskItem : NSObject
12 |
13 | @property NSString *itemName;
14 | @property NSString *ownerName;
15 | @property BOOL completed;
16 | @property (readonly) NSDate *creationDate;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/Microsoft Tasks/Microsoft Tasks-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #import
8 |
9 | #ifndef __IPHONE_3_0
10 | #warning "This project uses features only available in iOS SDK 3.0 and later."
11 | #endif
12 |
13 | #ifdef __OBJC__
14 | #import
15 | #import
16 | #import
17 | #endif
18 |
--------------------------------------------------------------------------------
/Microsoft Tasks/sampleAddTaskItemViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // sampleAddTaskItemViewController.h
3 | // Microsoft Tasks
4 | //
5 | // Created by Brandon Werner on 3/4/14.
6 | // Copyright (c) 2014 Microsoft. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface sampleAddTaskItemViewController : UIViewController
12 |
13 | - (IBAction)save:(id)sender;
14 | @property (weak, nonatomic) IBOutlet UITextField *textField;
15 |
16 | - (IBAction)cancelPressed:(id)sender;
17 | @end
18 |
--------------------------------------------------------------------------------
/Microsoft Tasks/samplesPolicyData.h:
--------------------------------------------------------------------------------
1 | //
2 | // samplesPolicyData.h
3 | // Microsoft Tasks
4 | //
5 | // Created by Brandon Werner on 4/21/15.
6 | // Copyright (c) 2015 Microsoft. All rights reserved.
7 | //
8 |
9 | #ifndef Microsoft_Tasks_samplesPolicyData_h
10 | #define Microsoft_Tasks_samplesPolicyData_h
11 |
12 |
13 | #endif
14 |
15 | #import
16 |
17 | @interface samplesPolicyData : NSObject
18 |
19 | @property (strong) NSString* policyName;
20 | @property (strong) NSString* policyID;
21 |
22 | +(id) getInstance;
23 |
24 | @end
--------------------------------------------------------------------------------
/Microsoft Tasks/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "iphone",
6 | "extent" : "full-screen",
7 | "minimum-system-version" : "7.0",
8 | "scale" : "2x"
9 | },
10 | {
11 | "orientation" : "portrait",
12 | "idiom" : "iphone",
13 | "subtype" : "retina4",
14 | "extent" : "full-screen",
15 | "minimum-system-version" : "7.0",
16 | "scale" : "2x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Microsoft Tasks/SamplesApplicationData.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface SamplesApplicationData : NSObject
5 |
6 | @property (strong) ADTokenCacheStoreItem *userItem;
7 | @property (strong) NSString* taskWebApiUrlString;
8 | @property (strong) NSString* authority;
9 | @property (strong) NSString* clientId;
10 | @property (strong) NSString* resourceId;
11 | @property (strong) NSString* redirectUriString;
12 | @property (strong) NSString* correlationId;
13 | @property BOOL fullScreen;
14 | @property BOOL showClaims;
15 |
16 | +(id) getInstance;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/Microsoft Tasks/samplesShowClaimsViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // samplesShowClaimsViewController.h
3 | // Microsoft Tasks
4 | //
5 | // Created by Brandon Werner on 4/21/15.
6 | // Copyright (c) 2015 Microsoft. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface samplesShowClaimsViewController : UIViewController
12 |
13 | @property (weak, nonatomic) IBOutlet UILabel *useLabel;
14 | @property (weak, nonatomic) IBOutlet UIScrollView *tokenView;
15 | @property (weak, nonatomic) IBOutlet UITextView *tokenText;
16 | @property (nonatomic, strong) NSString *claims;
17 | - (IBAction)homePressed:(id)sender;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/Microsoft Tasks/samplesAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // samplesAppDelegate.h
3 | // Microsoft Tasks
4 | //
5 | // Created by Brandon Werner on 3/4/14.
6 | // Copyright (c) 2014 Microsoft. All rights reserved.
7 | //
8 |
9 | #import
10 | @interface samplesAppDelegate : UIResponder
11 |
12 | @property (strong, nonatomic) UIWindow *window;
13 |
14 | @property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
15 | @property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
16 | @property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/Microsoft Tasks/settings.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | authority
6 | https://login.microsoftonline.com/common
7 | clientId
8 | e6d65cc4-f9e8-444a-9ba6-c3c82ce8086b
9 | resourceString
10 | http://localhost:3000/tasks
11 | redirectUri
12 | urn:ietf:wg:oauth:2.0:oob
13 | userId
14 |
15 | taskWebAPI
16 | http://localhost:3000/tasks
17 | fullScreen
18 |
19 | showClaims
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Microsoft TasksTests/Microsoft_TasksTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // Microsoft_TasksTests.m
3 | // Microsoft TasksTests
4 | //
5 | // Created by Brandon Werner on 3/4/14.
6 | // Copyright (c) 2014 Microsoft. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface Microsoft_TasksTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation Microsoft_TasksTests
16 |
17 | - (void)setUp
18 | {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown
24 | {
25 | // Put teardown code here. This method is called after the invocation of each test method in the class.
26 | [super tearDown];
27 | }
28 |
29 | - (void)testExample
30 | {
31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
32 | }
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/Microsoft TasksTests/Microsoft TasksTests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | com.microsoft.windowsazure.activedirectory.samples.${PRODUCT_NAME:rfc1034identifier}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to Azure samples
2 |
3 | Thank you for your interest in contributing to Azure samples!
4 |
5 | ## Ways to contribute
6 |
7 | You can contribute to [Azure samples](https://azure.microsoft.com/documentation/samples/) in a few different ways:
8 |
9 | - Submit feedback on [this sample page](https://azure.microsoft.com/documentation/samples/active-directory-ios/) whether it was helpful or not.
10 | - Submit issues through [issue tracker](https://github.com/Azure-Samples/active-directory-ios/issues) on GitHub. We are actively monitoring the issues and improving our samples.
11 | - If you wish to make code changes to samples, or contribute something new, please follow the [GitHub Forks / Pull requests model](https://help.github.com/articles/fork-a-repo/): Fork the sample repo, make the change and propose it back by submitting a pull request.
--------------------------------------------------------------------------------
/Microsoft Tasks/samplesPolicyData.m:
--------------------------------------------------------------------------------
1 | //
2 | // samplesPolicyData.m
3 | // Microsoft Tasks
4 | //
5 | // Created by Brandon Werner on 4/21/15.
6 | // Copyright (c) 2015 Microsoft. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "samplesPolicyData.h"
11 |
12 | @implementation samplesPolicyData
13 |
14 | +(id) getInstance
15 | {
16 | static samplesPolicyData *instance = nil;
17 | static dispatch_once_t onceToken;
18 |
19 | dispatch_once(&onceToken, ^{
20 | instance = [[self alloc] init];
21 | NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"settings" ofType:@"plist"]];
22 | instance.policyName = [dictionary objectForKey:@"policyName"];
23 | instance.policyID = [dictionary objectForKey:@"policyID"];
24 |
25 |
26 | });
27 |
28 | return instance;
29 | }
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/Microsoft Tasks/NSDictionary+UrlEncoding.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSDictionary+UrlEncoding.m
3 | // Microsoft Tasks
4 | //
5 | // Created by Brandon Werner on 4/21/15.
6 | // Copyright (c) 2015 Microsoft. All rights reserved.
7 | //
8 |
9 | #import "NSDictionary+UrlEncoding.h"
10 |
11 | // helper function: get the string form of any object
12 | static NSString *toString(id object) {
13 | return [NSString stringWithFormat: @"%@", object];
14 | }
15 |
16 | // helper function: get the url encoded string form of any object
17 | static NSString *urlEncode(id object) {
18 | NSString *string = toString(object);
19 | return [string stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
20 | }
21 |
22 | @implementation NSDictionary (UrlEncoding)
23 |
24 | -(NSString*) urlEncodedString {
25 | NSMutableArray *parts = [NSMutableArray array];
26 | for (id key in self) {
27 | id value = [self objectForKey: key];
28 | NSString *part = [NSString stringWithFormat: @"%@=%@", urlEncode(key), urlEncode(value)];
29 | [parts addObject: part];
30 | }
31 | return [parts componentsJoinedByString: @"&"];
32 | }
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Microsoft Corporation
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.
--------------------------------------------------------------------------------
/Microsoft Tasks/SamplesApplicationData.m:
--------------------------------------------------------------------------------
1 | #import "SamplesApplicationData.h"
2 |
3 | @implementation SamplesApplicationData
4 |
5 | +(id) getInstance
6 | {
7 | static SamplesApplicationData *instance = nil;
8 | static dispatch_once_t onceToken;
9 |
10 | dispatch_once(&onceToken, ^{
11 | instance = [[self alloc] init];
12 | NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"settings" ofType:@"plist"]];
13 | NSString* va = [dictionary objectForKey:@"fullScreen"];
14 | NSString* sc = [dictionary objectForKey:@"showClaims"];
15 | instance.fullScreen = [va boolValue];
16 | instance.showClaims = [sc boolValue];
17 | instance.clientId = [dictionary objectForKey:@"clientId"];
18 | instance.authority = [dictionary objectForKey:@"authority"];
19 | instance.resourceId = [dictionary objectForKey:@"resourceString"];
20 | instance.redirectUriString = [dictionary objectForKey:@"redirectUri"];
21 | instance.taskWebApiUrlString = [dictionary objectForKey:@"taskWebAPI"];
22 | instance.correlationId = [dictionary objectForKey:@"correlationId"];
23 |
24 | });
25 |
26 | return instance;
27 | }
28 |
29 | @end
--------------------------------------------------------------------------------
/Microsoft Tasks/samplesWebAPIConnector.h:
--------------------------------------------------------------------------------
1 | //
2 | // samplesWebAPIConnector.h
3 | // Microsoft Tasks
4 | //
5 | // Created by Brandon Werner on 3/11/14.
6 | // Copyright (c) 2014 Microsoft. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "samplesTaskItem.h"
11 | #import "samplesPolicyData.h"
12 | #import "ADALiOS/ADAuthenticationContext.h"
13 |
14 | @interface samplesWebAPIConnector : NSObject
15 |
16 | +(void) getTaskList:(void (^) (NSArray*, NSError* error))completionBlock
17 | parent:(UIViewController*) parent;
18 |
19 | +(void) addTask:(samplesTaskItem*)task
20 | parent:(UIViewController*) parent
21 | completionBlock:(void (^) (bool, NSError* error)) completionBlock;
22 |
23 | +(void) deleteTask:(samplesTaskItem*)task
24 | parent:(UIViewController*) parent
25 | completionBlock:(void (^) (bool, NSError* error)) completionBlock;
26 |
27 | +(void) doPolicy:(samplesPolicyData*)policy
28 | parent:(UIViewController*) parent
29 | completionBlock:(void (^) (ADUserInformation* userInfo, NSError* error)) completionBlock;
30 |
31 | +(void) doLogin:(BOOL)prompt
32 | parent:(UIViewController*) parent
33 | completionBlock:(void (^) (ADUserInformation* userInfo, NSError* error)) completionBlock;
34 |
35 | +(void) signOut;
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/Microsoft Tasks/samplesShowClaimsViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // samplesShowClaimsViewController.m
3 | // Microsoft Tasks
4 | //
5 | // Created by Brandon Werner on 4/21/15.
6 | // Copyright (c) 2015 Microsoft. All rights reserved.
7 | //
8 |
9 |
10 | #import "samplesShowClaimsViewController.h"
11 | #import "samplesTaskListTableViewController.h"
12 |
13 | @interface samplesShowClaimsViewController ()
14 |
15 | @end
16 |
17 | @implementation samplesShowClaimsViewController
18 |
19 | @synthesize tokenText;
20 | @synthesize claims;
21 |
22 | - (void)viewDidLoad {
23 | [super viewDidLoad];
24 | // Do any additional setup after loading the view.
25 | tokenText.text = claims;
26 | // Do any additional setup after loading the view.
27 | }
28 |
29 | - (void)didReceiveMemoryWarning {
30 | [super didReceiveMemoryWarning];
31 | // Dispose of any resources that can be recreated.
32 | }
33 |
34 | /*
35 | #pragma mark - Navigation
36 |
37 | // In a storyboard-based application, you will often want to do a little preparation before navigation
38 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
39 | // Get the new view controller using [segue destinationViewController].
40 | // Pass the selected object to the new view controller.
41 | }
42 | */
43 |
44 | - (IBAction)homePressed:(id)sender {
45 |
46 | [self.navigationController popToRootViewControllerAnimated:TRUE];
47 |
48 | }
49 | @end
50 |
--------------------------------------------------------------------------------
/Microsoft Tasks/Microsoft Tasks-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | Microsoft Tasks
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | com.microsoft.windowsazure.activedirectory.samples.microsofttasks
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | Microsoft Tasks
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.3
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.3
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | Main_iPhone
29 | UIMainStoryboardFile
30 | Main_iPhone
31 | UIRequiredDeviceCapabilities
32 |
33 | armv7
34 |
35 | NSAppTransportSecurity
36 |
37 | NSAllowsArbitraryLoads
38 |
39 |
40 | UISupportedInterfaceOrientations
41 |
42 | UIInterfaceOrientationPortrait
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 | UIInterfaceOrientationPortraitUpsideDown
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/Microsoft Tasks/sampleAddTaskItemViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // sampleAddTaskItemViewController.m
3 | // Microsoft Tasks
4 | //
5 | // Created by Brandon Werner on 3/4/14.
6 | // Copyright (c) 2014 Microsoft. All rights reserved.
7 | //
8 |
9 | #import "sampleAddTaskItemViewController.h"
10 | #import "samplesWebAPIConnector.h"
11 | #import "samplesTaskItem.h"
12 |
13 | @implementation sampleAddTaskItemViewController
14 |
15 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
16 | {
17 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
18 | if (self) {
19 | // Custom initialization
20 | }
21 | return self;
22 | }
23 |
24 | - (void)viewDidLoad
25 | {
26 | [super viewDidLoad];
27 | // Do any additional setup after loading the view.
28 | }
29 |
30 | - (void)didReceiveMemoryWarning
31 | {
32 | [super didReceiveMemoryWarning];
33 | // Dispose of any resources that can be recreated.
34 | }
35 |
36 | - (IBAction)save:(id)sender {
37 |
38 | if (self.textField.text.length > 0) {
39 |
40 | samplesTaskItem* taskItem = [[samplesTaskItem alloc]init];
41 | taskItem.itemName = self.textField.text;
42 | taskItem.completed = NO;
43 |
44 | [samplesWebAPIConnector addTask:taskItem parent:self completionBlock:^(bool success, NSError* error) {
45 | if (success)
46 |
47 | {dispatch_async(dispatch_get_main_queue(),^ {
48 |
49 | [self.navigationController popViewControllerAnimated:TRUE];
50 | });
51 | }
52 | else
53 | {
54 | UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:nil message:[[NSString alloc]initWithFormat:@"Error : %@", error.localizedDescription] delegate:nil cancelButtonTitle:@"Retry" otherButtonTitles:@"Cancel", nil];
55 |
56 | [alertView setDelegate:self];
57 |
58 | dispatch_async(dispatch_get_main_queue(),^ {
59 | [alertView show];
60 | });
61 | }
62 |
63 | }];
64 | }
65 | }
66 |
67 |
68 | - (IBAction)cancelPressed:(id)sender
69 | {
70 | [self dismissViewControllerAnimated:YES completion:nil];
71 | }
72 |
73 |
74 | - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
75 | {
76 | if (buttonIndex == 0)
77 | {
78 | [alertView dismissWithClickedButtonIndex:0 animated:NO];
79 | [self save:nil];
80 | }
81 | }
82 |
83 | @end
84 |
--------------------------------------------------------------------------------
/Microsoft Tasks/samplesLoginViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // samplesLoginViewController.m
3 | // Microsoft Tasks
4 | //
5 | // Created by Brandon Werner on 4/21/15.
6 | // Copyright (c) 2015 Microsoft. All rights reserved.
7 | //
8 |
9 | #import "samplesLoginViewController.h"
10 | #import "samplesWebAPIConnector.h"
11 | #import "samplesShowClaimsViewController.h"
12 | #import "samplesPolicyData.h"
13 | #import "samplesApplicationData.h"
14 |
15 | @interface samplesLoginViewController ()
16 |
17 | @end
18 |
19 | @implementation samplesLoginViewController
20 |
21 | - (void)viewDidLoad {
22 | [super viewDidLoad];
23 | // Do any additional setup after loading the view.
24 | }
25 |
26 | - (void)didReceiveMemoryWarning {
27 | [super didReceiveMemoryWarning];
28 | // Dispose of any resources that can be recreated.
29 | }
30 |
31 | /*
32 | #pragma mark - Navigation
33 |
34 | // In a storyboard-based application, you will often want to do a little preparation before navigation
35 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
36 | // Get the new view controller using [segue destinationViewController].
37 | // Pass the selected object to the new view controller.
38 | }
39 | */
40 |
41 | - (IBAction)signInPressed:(id)sender {
42 |
43 | SamplesApplicationData* appData = [SamplesApplicationData getInstance];
44 |
45 | [samplesWebAPIConnector doLogin:YES parent:self completionBlock:^(ADUserInformation* userInfo, NSError* error) {
46 | if (userInfo && appData.showClaims)
47 | {
48 | dispatch_sync(dispatch_get_main_queue(), ^{
49 | samplesShowClaimsViewController* claimsController = [self.storyboard instantiateViewControllerWithIdentifier:@"ClaimsView"];
50 | claimsController.claims = [NSString stringWithFormat:@" Claims : %@", userInfo.allClaims];
51 | [self.navigationController pushViewController:claimsController animated:YES];
52 | });
53 | }
54 | else if (userInfo)
55 | {
56 | [self dismissViewControllerAnimated:YES completion:nil];
57 | }
58 | else
59 | {
60 | UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:nil message:[[NSString alloc]initWithFormat:@"Error : %@", error.localizedDescription] delegate:nil cancelButtonTitle:@"Retry" otherButtonTitles:@"Cancel", nil];
61 |
62 | [alertView setDelegate:self];
63 |
64 | dispatch_async(dispatch_get_main_queue(),^ {
65 | [alertView show];
66 | });
67 | }
68 |
69 | }];
70 |
71 | }
72 |
73 | @end
74 |
--------------------------------------------------------------------------------
/Microsoft Tasks/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "3x"
17 | },
18 | {
19 | "size" : "40x40",
20 | "idiom" : "iphone",
21 | "filename" : "iPhone-2-1.png",
22 | "scale" : "2x"
23 | },
24 | {
25 | "size" : "40x40",
26 | "idiom" : "iphone",
27 | "filename" : "iPhone-5.png",
28 | "scale" : "3x"
29 | },
30 | {
31 | "size" : "57x57",
32 | "idiom" : "iphone",
33 | "filename" : "iPhone-1.png",
34 | "scale" : "1x"
35 | },
36 | {
37 | "size" : "57x57",
38 | "idiom" : "iphone",
39 | "filename" : "iPhone-4.png",
40 | "scale" : "2x"
41 | },
42 | {
43 | "size" : "60x60",
44 | "idiom" : "iphone",
45 | "filename" : "iPhone-5-5.png",
46 | "scale" : "2x"
47 | },
48 | {
49 | "size" : "60x60",
50 | "idiom" : "iphone",
51 | "filename" : "iPhone-6.png",
52 | "scale" : "3x"
53 | },
54 | {
55 | "size" : "24x24",
56 | "idiom" : "watch",
57 | "scale" : "2x",
58 | "role" : "notificationCenter",
59 | "subtype" : "38mm"
60 | },
61 | {
62 | "size" : "27.5x27.5",
63 | "idiom" : "watch",
64 | "scale" : "2x",
65 | "role" : "notificationCenter",
66 | "subtype" : "42mm"
67 | },
68 | {
69 | "size" : "29x29",
70 | "idiom" : "watch",
71 | "role" : "companionSettings",
72 | "scale" : "2x"
73 | },
74 | {
75 | "size" : "29x29",
76 | "idiom" : "watch",
77 | "role" : "companionSettings",
78 | "scale" : "3x"
79 | },
80 | {
81 | "size" : "40x40",
82 | "idiom" : "watch",
83 | "scale" : "2x",
84 | "role" : "appLauncher",
85 | "subtype" : "38mm"
86 | },
87 | {
88 | "size" : "44x44",
89 | "idiom" : "watch",
90 | "scale" : "2x",
91 | "role" : "longLook",
92 | "subtype" : "42mm"
93 | },
94 | {
95 | "size" : "86x86",
96 | "idiom" : "watch",
97 | "scale" : "2x",
98 | "role" : "quickLook",
99 | "subtype" : "38mm"
100 | },
101 | {
102 | "size" : "98x98",
103 | "idiom" : "watch",
104 | "scale" : "2x",
105 | "role" : "quickLook",
106 | "subtype" : "42mm"
107 | }
108 | ],
109 | "info" : {
110 | "version" : 1,
111 | "author" : "xcode"
112 | }
113 | }
--------------------------------------------------------------------------------
/Microsoft Tasks/SamplesAppSettingsController.m:
--------------------------------------------------------------------------------
1 | #import "SamplesAppSettingsController.h"
2 | #import "SamplesApplicationData.h"
3 | #import
4 |
5 | @interface SamplesAppSettingsController ()
6 |
7 | @property (weak, nonatomic) IBOutlet UITextField *authorityLabel;
8 | @property (weak, nonatomic) IBOutlet UITextField *clientIdLabel;
9 | @property (weak, nonatomic) IBOutlet UITextField *resourceLabel;
10 | @property (weak, nonatomic) IBOutlet UITextField *redirectUriLabel;
11 | @property (weak, nonatomic) IBOutlet UISegmentedControl *fullScreenSwitch;
12 | @property (weak, nonatomic) IBOutlet UITextField *correlationIdLabel;
13 | @property (weak, nonatomic) IBOutlet UISegmentedControl *showClaimsSwitch;
14 | @end
15 |
16 | @implementation SamplesAppSettingsController
17 |
18 | - (void)viewDidLoad
19 | {
20 | [super viewDidLoad];
21 | // Do any additional setup after loading the view.
22 | SamplesApplicationData* data = [SamplesApplicationData getInstance];
23 | self->_authorityLabel.text = data.authority;
24 | self->_clientIdLabel.text = data.clientId;
25 | self->_resourceLabel.text = data.resourceId;
26 | self->_redirectUriLabel.text = data.redirectUriString;
27 | self->_correlationIdLabel.text = data.correlationId;
28 | [self configureControl:self->_fullScreenSwitch forValue:data.fullScreen];
29 | [self configureControl:self->_showClaimsSwitch forValue:data.showClaims];
30 | }
31 |
32 |
33 | - (IBAction)savePressed:(id)sender
34 | {
35 | SamplesApplicationData* data = [SamplesApplicationData getInstance];
36 | data.authority = self->_authorityLabel.text;
37 | data.clientId = self->_clientIdLabel.text;
38 | data.resourceId = self->_resourceLabel.text;
39 | data.redirectUriString = self->_redirectUriLabel.text;
40 | data.fullScreen = [self isEnabled:self->_fullScreenSwitch];
41 | data.correlationId = self->_correlationIdLabel.text;
42 | data.showClaims = [self isEnabled:self->_showClaimsSwitch];
43 | [self cancelPressed:sender];
44 |
45 | }
46 |
47 |
48 | - (void) configureControl:(UISegmentedControl *)control forValue:(BOOL) enabled
49 | {
50 | if(enabled){
51 | [control setSelectedSegmentIndex:1];
52 | }else
53 | {
54 | [control setSelectedSegmentIndex:0];
55 | }
56 | }
57 |
58 | - (IBAction)cancelPressed:(id)sender
59 | {
60 | [self dismissViewControllerAnimated:YES completion:nil];
61 | }
62 |
63 |
64 | - (IBAction)clearKeychainPressed:(id)sender
65 | {
66 | id cache = [ADAuthenticationSettings sharedInstance].defaultTokenCacheStore;
67 | [cache removeAllWithError:nil];
68 | SamplesApplicationData* data = [SamplesApplicationData getInstance];
69 | data.userItem = nil;
70 |
71 | // This clears cookies for new sign-in flow. We shouldn't need to do this. Server should accept PROMPT_ALWAYS
72 |
73 | NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
74 | for (NSHTTPCookie *cookie in [storage cookies]) {
75 | [storage deleteCookie:cookie];
76 | }
77 |
78 | [[NSUserDefaults standardUserDefaults] synchronize];
79 | }
80 |
81 | - (BOOL) isEnabled:(UISegmentedControl *)control
82 | {
83 | return [control selectedSegmentIndex] != 0;
84 | }
85 |
86 | @end
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | services: active-directory
3 | platforms: ios
4 | author: brandwe
5 | ---
6 |
7 | # Integrate Azure AD into an iOS application
8 |
9 | **NOTE regarding iOS 9:**
10 |
11 | Apple has released iOS 9 which includes support for App Transport Security (ATS). ATS restricts apps from accessing the internet unless they meet several security requirements incuding TLS 1.2 and SHA-256. While Microsoft's APIs support these standards some third party APIs and content delivery networks we use have yet to be upgraded. This means that any app that relies on Azure Active Directory or Microsoft Accounts will fail when compiled with iOS 9. For now our recommendation is to disable ATS, which reverts to iOS 8 functionality. Please refer to this [technote from Apple](https://developer.apple.com/library/prerelease/ios/technotes/App-Transport-Security-Technote/) for more informtaion.
12 |
13 | ----
14 |
15 |
16 | This sample shows how to build an iOS application that calls a web API that requires a Work Account for authentication. This sample uses the Active Directory authentication library for iOS to do the interactive OAuth 2.0 authorization code flow with public client.
17 |
18 |
19 | ## Quick Start
20 |
21 | Getting started with the sample is easy. It is configured to run out of the box with minimal setup. If you'd like a more detailed walkthrough including how to setup the REST API and register an Azure AD Directory follow the walk-through here.
22 |
23 | ### Step 1: Download the iOS Native Client Sample code
24 |
25 | * `$ git clone git@github.com:Azure-Samples/active-directory-ios.git`
26 |
27 | ### Step 2: Download Cocoapods (if you don't already have it)
28 |
29 | CocoaPods is the dependency manager for Swift and Objective-C Cocoa projects. It has thousands of libraries and can help you scale your projects elegantly. To install on OS X 10.9 and greater simply run the following command in your terminal:
30 |
31 | `$ sudo gem install cocoapods`
32 |
33 | ### Step 3: Build the sample and pull down ADAL for iOS automatically
34 |
35 | Run the following command in your terminal:
36 |
37 | `$ pod install`
38 |
39 | This will download and build ADAL for iOS for you and configure your Microsoft Tasks.xcodeproj to use the correct dependencies.
40 |
41 | ### Step 4: Run the application in Xcode
42 |
43 | Launch XCode and load the `Microsoft Tasks.xcworkspace` file. The application will run in an emulator as soon as it is loaded.
44 |
45 |
46 | #### Step 5. Determine what your Redirect URI will be for iOS
47 |
48 | In order to securely launch your applications in certain SSO scenarios we require that you create a **Redirect URI** in a particular format. A Redirect URI is used to ensure that the tokens return to the correct application that asked for them.
49 |
50 | The iOS format for a Redirect URI is:
51 |
52 | ```
53 | ://
54 | ```
55 |
56 | - **app-scheme** - This is registered in your XCode project. It is how other applications can call you. You can find this under Info.plist -> URL types -> URL Identifier. You should create one if you don't already have one or more configured.
57 | - **bundle-id** - This is the Bundle Identifier found under "identity" un your project settings in XCode.
58 |
59 | An example would be: ***mstodo://com.microsoft.windowsazure.activedirectory.samples.microsofttasks***
60 |
61 | ### Step 6: Configure the settings.plist file with your Web API information
62 |
63 | You will need to configure your application to work with the Azure AD tenant you've created. Under "Supporting Files"you will find a settings.plist file. It contains the following information:
64 |
65 | ```XML
66 |
67 |
68 |
69 |
70 | authority
71 | https://login.microsoftonline.com/common
72 | clientId
73 | xxxxxxx-xxxxxx-xxxxxxx-xxxxxxx
74 | resourceString
75 | https://localhost/todolistservice
76 | redirectUri
77 | mstodo://com.microsoft.windowsazure.activedirectory.samples.microsofttasks
78 | userId
79 | user@domain.com
80 | taskWebAPI
81 | https://localhost/api/todolist/
82 |
83 |
84 | ```
85 |
86 | Replace the information in the plist file with your Web API settings.
87 |
88 | ##### NOTE
89 |
90 | The current defaults are set up to work with our [Azure Active Directory Sample REST API Service for Node.js](https://github.com/Azure-Samples/WebAPI-Nodejs). You will need to specify the clientID of your Web API, however. If you are running your own API, you will need to update the endpoints as required.
91 |
--------------------------------------------------------------------------------
/Microsoft Tasks/samplesAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // samplesAppDelegate.m
3 | // Microsoft Tasks
4 | //
5 | // Created by Brandon Werner on 3/4/14.
6 | // Copyright (c) 2014 Microsoft. All rights reserved.
7 | //
8 |
9 | #import "samplesAppDelegate.h"
10 | #import "SamplesApplicationData.h"
11 |
12 |
13 | @implementation samplesAppDelegate
14 |
15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
16 | {
17 | // Override point for customization after application launch.
18 |
19 |
20 | [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
21 |
22 | UIPageControl *pageControl = [UIPageControl appearance];
23 | pageControl.pageIndicatorTintColor = [UIColor lightGrayColor];
24 | pageControl.currentPageIndicatorTintColor = [UIColor whiteColor];
25 | pageControl.backgroundColor = [UIColor colorWithRed:0.106 green:0.286 blue:0.627 alpha:1];
26 |
27 |
28 | SamplesApplicationData* data = [SamplesApplicationData getInstance];
29 | NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"settings" ofType:@"plist"]];
30 |
31 | data.clientId = [dictionary objectForKey:@"clientId"];
32 | data.authority = [dictionary objectForKey:@"authority"];
33 | data.resourceId = [dictionary objectForKey:@"resourceString"];
34 | data.redirectUriString = [dictionary objectForKey:@"redirectUri"];
35 | data.taskWebApiUrlString = [dictionary objectForKey:@"taskWebAPI"];
36 |
37 | return YES;
38 | }
39 |
40 | - (void)applicationWillResignActive:(UIApplication *)application
41 | {
42 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
43 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
44 | }
45 |
46 | - (void)applicationDidEnterBackground:(UIApplication *)application
47 | {
48 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
49 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
50 | }
51 |
52 | - (void)applicationWillEnterForeground:(UIApplication *)application
53 | {
54 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
55 | }
56 |
57 | - (void)applicationDidBecomeActive:(UIApplication *)application
58 | {
59 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
60 | }
61 |
62 | - (void)applicationWillTerminate:(UIApplication *)application
63 | {
64 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
65 | }
66 |
67 | #pragma mark - Core Data stack
68 |
69 | @synthesize managedObjectContext = _managedObjectContext;
70 | @synthesize managedObjectModel = _managedObjectModel;
71 | @synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
72 |
73 | - (NSURL *)applicationDocumentsDirectory {
74 | // The directory the application uses to store the Core Data store file. This code uses a directory named "com.microsoft.windowsazure.activedirectory.samples" in the application's documents directory.
75 | return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
76 | }
77 |
78 | - (NSManagedObjectModel *)managedObjectModel {
79 | // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
80 | if (_managedObjectModel != nil) {
81 | return _managedObjectModel;
82 | }
83 | NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Policy" withExtension:@"momd"];
84 | _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
85 | return _managedObjectModel;
86 | }
87 |
88 | - (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
89 | // The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it.
90 | if (_persistentStoreCoordinator != nil) {
91 | return _persistentStoreCoordinator;
92 | }
93 |
94 | // Create the coordinator and store
95 |
96 | _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
97 | NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Microsoft_Tasks.sqlite"];
98 | NSError *error = nil;
99 | NSString *failureReason = @"There was an error creating or loading the application's saved data.";
100 | if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
101 | // Report any error we got.
102 | NSMutableDictionary *dict = [NSMutableDictionary dictionary];
103 | dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data";
104 | dict[NSLocalizedFailureReasonErrorKey] = failureReason;
105 | dict[NSUnderlyingErrorKey] = error;
106 | error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
107 | // Replace this with code to handle the error appropriately.
108 | // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
109 | NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
110 | abort();
111 | }
112 |
113 | return _persistentStoreCoordinator;
114 | }
115 |
116 |
117 | - (NSManagedObjectContext *)managedObjectContext {
118 | // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
119 | if (_managedObjectContext != nil) {
120 | return _managedObjectContext;
121 | }
122 |
123 | NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
124 | if (!coordinator) {
125 | return nil;
126 | }
127 | _managedObjectContext = [[NSManagedObjectContext alloc] init];
128 | [_managedObjectContext setPersistentStoreCoordinator:coordinator];
129 | return _managedObjectContext;
130 | }
131 |
132 | #pragma mark - Core Data Saving support
133 |
134 | - (void)saveContext {
135 | NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
136 | if (managedObjectContext != nil) {
137 | NSError *error = nil;
138 | if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
139 | // Replace this implementation with code to handle the error appropriately.
140 | // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
141 | NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
142 | abort();
143 | }
144 | }
145 | }
146 |
147 | @end
148 |
--------------------------------------------------------------------------------
/Microsoft Tasks/samplesTaskListTableViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // samplesTaskListTableViewController.m
3 | // Microsoft Tasks
4 | //
5 | // Created by Brandon Werner on 3/4/14.
6 | // Copyright (c) 2014 Microsoft. All rights reserved.
7 | //
8 |
9 | #import "samplesTaskListTableViewController.h"
10 | #import "SamplesApplicationData.h"
11 | #import "samplesTaskItem.h"
12 | #import "sampleAddTaskItemViewController.h"
13 | #import "samplesWebAPIConnector.h"
14 | #import "ADALiOS/ADAuthenticationContext.h"
15 | #import "SamplesSelectUserViewController.h"
16 |
17 | @interface samplesTaskListTableViewController ()
18 |
19 | @property NSMutableArray *taskItems;
20 | @property ADAuthenticationContext *authContext;
21 | @property (weak, nonatomic) IBOutlet UILabel* userLabel;
22 |
23 | @end
24 |
25 | @implementation samplesTaskListTableViewController
26 |
27 | -(void)loadData {
28 |
29 | SamplesApplicationData* appData = [SamplesApplicationData getInstance];
30 |
31 | if (!appData.userItem.userInformation.userId) {
32 |
33 | dispatch_async(dispatch_get_main_queue(),^ {
34 |
35 | SamplesSelectUserViewController* userSelectController = [self.storyboard instantiateViewControllerWithIdentifier:@"SelectUserView"];
36 | [self.navigationController pushViewController:userSelectController animated:YES];
37 | });
38 | }
39 |
40 |
41 | // Load data from the webservice
42 | if (appData.userItem) {
43 |
44 | [samplesWebAPIConnector getTaskList:^(NSArray *tasks, NSError* error) {
45 |
46 | if (error != nil && appData.userItem)
47 | {
48 | UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:nil message:[[NSString alloc]initWithFormat:@"%@", error.localizedDescription] delegate:nil cancelButtonTitle:@"Retry" otherButtonTitles:@"Cancel", nil];
49 |
50 | [alertView setDelegate:self];
51 |
52 | dispatch_async(dispatch_get_main_queue(),^ {
53 | [alertView show];
54 | });
55 | }
56 | else
57 | {
58 | self.taskItems = (NSMutableArray*)tasks;
59 |
60 | // Refresh main thread since we are async
61 | dispatch_async(dispatch_get_main_queue(), ^{
62 | [self.tableView reloadData];
63 | SamplesApplicationData* appData = [SamplesApplicationData getInstance];
64 | if(appData.userItem && appData.userItem.userInformation)
65 | {
66 | [self.userLabel setText:appData.userItem.userInformation.userId];
67 | }
68 | else
69 | {
70 | [self.userLabel setText:@"N/A" ];
71 | }
72 | });
73 | }
74 | } parent:self];
75 | } }
76 |
77 | - (void)viewDidLoad
78 | {
79 | [super viewDidLoad];
80 | self.refreshControl = [[UIRefreshControl alloc] init];
81 |
82 | [self.refreshControl addTarget:self action:@selector(refreshInvoked:forState:) forControlEvents:UIControlEventValueChanged];
83 |
84 | [self setRefreshControl:self.refreshControl];
85 | self.taskItems = [[NSMutableArray alloc] init];
86 | [self loadData];
87 | }
88 |
89 | -(void)viewDidAppear:(BOOL)animated
90 | {
91 |
92 | SamplesApplicationData* appData = [SamplesApplicationData getInstance];
93 |
94 | if(appData.userItem)
95 | {
96 | [self loadData];
97 | }
98 |
99 | if(appData.userItem && appData.userItem.userInformation)
100 | {
101 | [self.userLabel setText:appData.userItem.userInformation.userId]; }
102 | else
103 | {
104 | [self.userLabel setText:@"N/A" ];
105 | }
106 | }
107 |
108 |
109 | -(void) refreshInvoked:(id)sender forState:(UIControlState)state {
110 | // Refresh table here...
111 | [self.taskItems removeAllObjects];
112 | [self.tableView reloadData];
113 | [self loadData];
114 | [self.refreshControl endRefreshing];
115 | }
116 |
117 | - (void)didReceiveMemoryWarning
118 | {
119 | [super didReceiveMemoryWarning];
120 | // Dispose of any resources that can be recreated.
121 | }
122 |
123 |
124 | #pragma mark - Table view data source
125 |
126 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
127 | {
128 | // Return the number of sections.
129 | return 1;
130 | }
131 |
132 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
133 | {
134 | // Return the number of rows in the section.
135 | return [self.taskItems count];
136 | }
137 |
138 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
139 | {
140 |
141 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TaskPrototypeCell" forIndexPath:indexPath];
142 |
143 | samplesTaskItem *taskItem = [self.taskItems objectAtIndex:indexPath.row];
144 | cell.textLabel.text = taskItem.itemName;
145 |
146 | if (taskItem.completed) {
147 | cell.accessoryType = UITableViewCellAccessoryCheckmark;
148 | } else {
149 | cell.accessoryType = UITableViewCellAccessoryNone;
150 | }
151 |
152 | return cell;
153 | }
154 |
155 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
156 |
157 | [tableView deselectRowAtIndexPath:indexPath animated:NO];
158 | samplesTaskItem *tappedItem = [self.taskItems objectAtIndex:indexPath.row];
159 | tappedItem.completed = !tappedItem.completed;
160 | [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
161 | }
162 |
163 |
164 | // Override to support conditional editing of the table view.
165 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
166 | // Return NO if you do not want the specified item to be editable.
167 | return YES;
168 | }
169 |
170 |
171 |
172 | // Override to support editing the table view.
173 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
174 | if (editingStyle == UITableViewCellEditingStyleDelete) {
175 |
176 |
177 | samplesTaskItem *selectedItem = [self.taskItems objectAtIndex:indexPath.row];
178 | [samplesWebAPIConnector deleteTask:selectedItem parent:self completionBlock:^(bool success, NSError* error) {
179 |
180 | if (error != nil) {
181 |
182 | UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:nil message:[[NSString alloc]initWithFormat:@"Error : %@", error.localizedDescription] delegate:nil cancelButtonTitle:@"Retry" otherButtonTitles:@"Cancel", nil];
183 |
184 | [alertView setDelegate:self];
185 |
186 | dispatch_async(dispatch_get_main_queue(),^ {
187 | [alertView show];
188 | });
189 | }
190 |
191 | }];
192 |
193 | [self.taskItems removeObjectAtIndex:indexPath.row];
194 | [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
195 |
196 | }
197 |
198 | [self.taskItems removeAllObjects];
199 | [self.tableView reloadData];
200 | [self loadData];
201 |
202 |
203 | }
204 |
205 |
206 |
207 |
208 | - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
209 | {
210 | if (buttonIndex == 0)
211 | {
212 | [alertView dismissWithClickedButtonIndex:0 animated:NO];
213 | }
214 | }
215 |
216 | - (IBAction)unwindToList:(UIStoryboardSegue *)segue {
217 |
218 | }
219 |
220 | @end
221 |
--------------------------------------------------------------------------------
/Microsoft Tasks/SamplesSelectUserViewController.m:
--------------------------------------------------------------------------------
1 | #import "SamplesSelectUserViewController.h"
2 | #import
3 | #import "ADALiOS/ADAuthenticationContext.h"
4 | #import "SamplesApplicationData.h"
5 | #import "samplesTaskListTableViewController.h"
6 |
7 | @interface SamplesSelectUserViewController ()
8 |
9 | @property NSMutableArray *userList;
10 |
11 | @end
12 |
13 | @implementation SamplesSelectUserViewController
14 |
15 |
16 | - (void)viewDidLoad
17 | {
18 | [super viewDidLoad];
19 | self.refreshControl = [[UIRefreshControl alloc] init];
20 |
21 | [self.refreshControl addTarget:self action:@selector(refreshInvoked:forState:) forControlEvents:UIControlEventValueChanged];
22 |
23 | [self setRefreshControl:self.refreshControl];
24 | self.userList = [[NSMutableArray alloc] init];
25 |
26 | [self loadData];
27 | }
28 |
29 | -(void)viewDidAppear:(BOOL)animated
30 | {
31 |
32 | [self loadData];
33 |
34 | }
35 |
36 | -(void) loadData
37 | {
38 | ADAuthenticationError* error;
39 | id cache = [ADAuthenticationSettings sharedInstance].defaultTokenCacheStore;
40 | NSArray* array = [cache allItemsWithError:&error];
41 |
42 | if (error)
43 | {
44 | UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:nil message:[[NSString alloc]initWithFormat:@"%@", error.errorDetails] delegate:nil cancelButtonTitle:@"Retry" otherButtonTitles:@"Cancel", nil];
45 |
46 | [alertView setDelegate:self];
47 |
48 | dispatch_async(dispatch_get_main_queue(),^ {
49 | [alertView show];
50 | });
51 | } else
52 | {
53 | NSMutableSet* users = [NSMutableSet new];
54 | self.userList = [NSMutableArray new];
55 | for(ADTokenCacheStoreItem* item in array)
56 | {
57 | ADUserInformation *user = item.userInformation;
58 | if (!item.userInformation)
59 | {
60 | user = [ADUserInformation userInformationWithUserId:@"Unknown user" error:nil];
61 | }
62 | if (![users containsObject:user.userId])
63 | {
64 | //New user, add and print:
65 | [self.userList addObject:item];
66 | [users addObject:user.userId];
67 | }
68 | }
69 |
70 | // Refresh main thread since we are async
71 | dispatch_async(dispatch_get_main_queue(), ^{
72 | [self.tableView reloadData];
73 | });
74 | }
75 | }
76 |
77 | - (IBAction)cancelPressed:(id)sender
78 | {
79 | [self dismissViewControllerAnimated:YES completion:nil];
80 | }
81 |
82 | -(void) refreshInvoked:(id)sender forState:(UIControlState)state {
83 | // Refresh table here...
84 | [self.userList removeAllObjects];
85 | [self.tableView reloadData];
86 | [self loadData];
87 | [self.refreshControl endRefreshing];
88 | }
89 |
90 |
91 |
92 | #pragma mark - Table view data source
93 |
94 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
95 | {
96 | // Return the number of sections.
97 | return 1;
98 | }
99 |
100 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
101 | {
102 | // Return the number of rows in the section.
103 | return [self.userList count];
104 | }
105 |
106 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
107 | {
108 |
109 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UserPrototypeCell" forIndexPath:indexPath];
110 |
111 | ADTokenCacheStoreItem *userItem = [self.userList objectAtIndex:indexPath.row];
112 | if(userItem)
113 | {
114 | if(userItem.userInformation){
115 |
116 | cell.textLabel.text = userItem.userInformation.userId;
117 | }
118 | else
119 | {
120 | cell.textLabel.text = @"ADFS User";
121 | }
122 | }
123 | // if (taskItem.completed) {
124 | // cell.accessoryType = UITableViewCellAccessoryCheckmark;
125 | // } else {
126 | // cell.accessoryType = UITableViewCellAccessoryNone;
127 | // }
128 |
129 | return cell;
130 | }
131 |
132 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
133 |
134 | [tableView deselectRowAtIndexPath:indexPath animated:NO];
135 | ADTokenCacheStoreItem *userItem = [self.userList objectAtIndex:indexPath.row];
136 | [self getToken:userItem];
137 |
138 | //tappedItem.completed = !tappedItem.completed;
139 | [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
140 |
141 | [self.navigationController popToRootViewControllerAnimated:TRUE];
142 |
143 | }
144 |
145 | - (void) getToken:(ADTokenCacheStoreItem*) userItem
146 | {
147 | SamplesApplicationData* appData = [SamplesApplicationData getInstance];
148 | ADAuthenticationError *error;
149 | ADAuthenticationContext* authContext = [ADAuthenticationContext authenticationContextWithAuthority:appData.authority validateAuthority:NO error:&error];
150 | NSString* userId = nil;
151 |
152 | if(userItem && userItem.userInformation){
153 | if(userItem.userInformation.userIdDisplayable){
154 | userId = userItem.userInformation.userId;
155 | }
156 | }
157 |
158 | authContext.parentController = self;
159 | [ADAuthenticationSettings sharedInstance].enableFullScreen = appData.fullScreen;
160 |
161 | if(!appData.correlationId ||
162 | [[appData.correlationId stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0)
163 | {
164 | authContext.correlationId = [[NSUUID alloc] initWithUUIDString:appData.correlationId];
165 | }
166 |
167 | ADPromptBehavior promptBehavior = AD_PROMPT_AUTO;
168 | if(!userItem){
169 | promptBehavior = AD_PROMPT_ALWAYS;
170 | }
171 |
172 | NSURL *redirectUri = [[NSURL alloc]initWithString:appData.redirectUriString];
173 | [authContext acquireTokenWithResource:appData.resourceId
174 | clientId:appData.clientId
175 | redirectUri:redirectUri
176 | promptBehavior:promptBehavior
177 | userId:userId
178 | extraQueryParameters:@"nux=1"
179 | completionBlock:^(ADAuthenticationResult *result) {
180 |
181 | if (result.status != AD_SUCCEEDED)
182 | {
183 | UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:nil message:[[NSString alloc]initWithFormat:@"Error : %@", error.localizedDescription] delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
184 |
185 | [alertView setDelegate:self];
186 |
187 | dispatch_async(dispatch_get_main_queue(),^ {
188 | [alertView show];
189 | });
190 | }
191 | else
192 | {
193 | SamplesApplicationData* data = [SamplesApplicationData getInstance];
194 | data.userItem = result.tokenCacheStoreItem;
195 | [self cancelPressed:self];
196 | }
197 | }];
198 |
199 | }
200 |
201 |
202 | - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
203 | {
204 | if (buttonIndex == 0)
205 | {
206 | [alertView dismissWithClickedButtonIndex:0 animated:NO];
207 | [self loadData];
208 | }
209 | }
210 |
211 |
212 |
213 | @end
214 |
215 |
--------------------------------------------------------------------------------
/Microsoft Tasks/samplesWebAPIConnector.m:
--------------------------------------------------------------------------------
1 | //
2 | // samplesWebAPIConnector.m
3 | // Microsoft Tasks
4 | //
5 | // Created by Brandon Werner on 3/11/14.
6 | // Copyright (c) 2014 Microsoft. All rights reserved.
7 | //
8 |
9 |
10 | #import "SamplesApplicationData.h"
11 | #import "samplesWebAPIConnector.h"
12 | #import "ADALiOS/ADAuthenticationContext.h"
13 | #import "samplesTaskItem.h"
14 | #import "samplesPolicyData.h"
15 | #import "ADALiOS/ADAuthenticationSettings.h"
16 | #import "NSDictionary+UrlEncoding.h"
17 |
18 | @implementation samplesWebAPIConnector
19 |
20 | ADAuthenticationContext* authContext;
21 | bool loadedApplicationSettings;
22 |
23 | + (void) readApplicationSettings {
24 | loadedApplicationSettings = YES;
25 | }
26 |
27 | +(NSString*) trimString: (NSString*) toTrim
28 | {
29 | //The white characters set is cached by the system:
30 | NSCharacterSet* set = [NSCharacterSet whitespaceAndNewlineCharacterSet];
31 | return [toTrim stringByTrimmingCharactersInSet:set];
32 | }
33 |
34 | //getToken for generic Web API flows. Returns a token with no additional parameters provided.
35 | //
36 | //
37 |
38 | +(void) getToken : (BOOL) clearCache
39 | parent:(UIViewController*) parent
40 | completionHandler:(void (^) (NSString*, NSError*))completionBlock;
41 | {
42 | SamplesApplicationData* data = [SamplesApplicationData getInstance];
43 | if(data.userItem){
44 | completionBlock(data.userItem.accessToken, nil);
45 | return;
46 | }
47 |
48 | ADAuthenticationError *error;
49 | authContext = [ADAuthenticationContext authenticationContextWithAuthority:data.authority error:&error];
50 | authContext.parentController = parent;
51 | NSURL *redirectUri = [[NSURL alloc]initWithString:data.redirectUriString];
52 |
53 | if(!data.correlationId ||
54 | [[data.correlationId stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0)
55 | {
56 | authContext.correlationId = [[NSUUID alloc] initWithUUIDString:data.correlationId];
57 | }
58 |
59 | [ADAuthenticationSettings sharedInstance].enableFullScreen = data.fullScreen;
60 | [authContext acquireTokenWithResource:data.resourceId
61 | clientId:data.clientId
62 | redirectUri:redirectUri
63 | promptBehavior:AD_PROMPT_AUTO
64 | userId:data.userItem.userInformation.userId
65 | extraQueryParameters: @"nux=1" // if this strikes you as strange it was legacy to display the correct mobile UX. You most likely won't need it in your code.
66 | completionBlock:^(ADAuthenticationResult *result) {
67 |
68 | if (result.status != AD_SUCCEEDED)
69 | {
70 | completionBlock(nil, result.error);
71 | }
72 | else
73 | {
74 | data.userItem = result.tokenCacheStoreItem;
75 | completionBlock(result.tokenCacheStoreItem.accessToken, nil);
76 | }
77 | }];
78 | }
79 |
80 | //getToken for support of sending extra (and unknown) params to the authorization and token endpoints
81 | //
82 | //
83 |
84 | +(void) getTokenWithExtraParams : (BOOL) clearCache
85 | params:(NSDictionary*) params
86 | parent:(UIViewController*) parent
87 | completionHandler:(void (^) (NSString*, NSError*))completionBlock;
88 | {
89 | SamplesApplicationData* data = [SamplesApplicationData getInstance];
90 |
91 |
92 | ADAuthenticationError *error;
93 | authContext = [ADAuthenticationContext authenticationContextWithAuthority:data.authority error:&error];
94 | authContext.parentController = parent;
95 | NSURL *redirectUri = [[NSURL alloc]initWithString:data.redirectUriString];
96 |
97 | if(!data.correlationId ||
98 | [[data.correlationId stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0)
99 | {
100 | authContext.correlationId = [[NSUUID alloc] initWithUUIDString:data.correlationId];
101 | }
102 |
103 | [ADAuthenticationSettings sharedInstance].enableFullScreen = data.fullScreen;
104 | [authContext acquireTokenWithResource:data.resourceId
105 | clientId:data.clientId
106 | redirectUri:redirectUri
107 | promptBehavior:AD_PROMPT_AUTO
108 | userId:data.userItem.userInformation.userId
109 | extraQueryParameters: params.urlEncodedString
110 | completionBlock:^(ADAuthenticationResult *result) {
111 |
112 | if (result.status != AD_SUCCEEDED)
113 | {
114 | completionBlock(nil, result.error);
115 | }
116 | else
117 | {
118 | data.userItem = result.tokenCacheStoreItem;
119 | completionBlock(result.tokenCacheStoreItem.accessToken, nil);
120 | }
121 | }];
122 | }
123 |
124 | // getToken for support of sending extra (and unknown) params to the authorization and token endpoints.
125 | // This method returns the entire claimset as stored in the userInformation collection instead of a token.
126 | // Use this only for display purposes, it is not necessary
127 |
128 | +(void) getClaimsWithExtraParams : (BOOL) clearCache
129 | params:(NSDictionary*) params
130 | parent:(UIViewController*) parent
131 | completionHandler:(void (^) (ADUserInformation*, NSError*))completionBlock;
132 | {
133 | SamplesApplicationData* data = [SamplesApplicationData getInstance];
134 |
135 |
136 | ADAuthenticationError *error;
137 | authContext = [ADAuthenticationContext authenticationContextWithAuthority:data.authority error:&error];
138 | authContext.parentController = parent;
139 | NSURL *redirectUri = [[NSURL alloc]initWithString:data.redirectUriString];
140 |
141 | if(!data.correlationId ||
142 | [[data.correlationId stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0)
143 | {
144 | authContext.correlationId = [[NSUUID alloc] initWithUUIDString:data.correlationId];
145 | }
146 |
147 | [ADAuthenticationSettings sharedInstance].enableFullScreen = data.fullScreen;
148 | [authContext acquireTokenWithResource:data.resourceId
149 | clientId:data.clientId
150 | redirectUri:redirectUri
151 | promptBehavior:AD_PROMPT_ALWAYS
152 | userId:data.userItem.userInformation.userId
153 | extraQueryParameters: params.urlEncodedString
154 | completionBlock:^(ADAuthenticationResult *result) {
155 |
156 | if (result.status != AD_SUCCEEDED)
157 | {
158 | completionBlock(nil, result.error);
159 | }
160 | else
161 | {
162 | data.userItem = result.tokenCacheStoreItem;
163 | completionBlock(result.tokenCacheStoreItem.userInformation, nil);
164 | }
165 | }];
166 | }
167 |
168 |
169 | // This method returns the entire claimset as stored in the userInformation collection instead of a token.
170 | // This is meant to show that Claims can be retreived without extra query params. You could easily pass getClaimsWithExtraParams with params = nil.
171 |
172 | +(void) getClaims : (BOOL) clearCache
173 | parent:(UIViewController*) parent
174 | completionHandler:(void (^) (ADUserInformation*, NSError*))completionBlock;
175 | {
176 | SamplesApplicationData* data = [SamplesApplicationData getInstance];
177 |
178 | ADAuthenticationError *error;
179 | authContext = [ADAuthenticationContext authenticationContextWithAuthority:data.authority error:&error];
180 | authContext.parentController = parent;
181 | NSURL *redirectUri = [[NSURL alloc]initWithString:data.redirectUriString];
182 |
183 | if(!data.correlationId ||
184 | [[data.correlationId stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0)
185 | {
186 | authContext.correlationId = [[NSUUID alloc] initWithUUIDString:data.correlationId];
187 | }
188 |
189 | [ADAuthenticationSettings sharedInstance].enableFullScreen = data.fullScreen;
190 | [authContext acquireTokenWithResource:data.resourceId
191 | clientId:data.clientId
192 | redirectUri:redirectUri
193 | promptBehavior:AD_PROMPT_ALWAYS
194 | userId:nil
195 | extraQueryParameters: @"nux=1" // if this strikes you as strange it was legacy to display the correct mobile UX. You most likely won't need it in your code.
196 |
197 | completionBlock:^(ADAuthenticationResult *result) {
198 |
199 | if (result.status != AD_SUCCEEDED)
200 | {
201 | completionBlock(nil, result.error);
202 | }
203 | else
204 | {
205 | data.userItem = result.tokenCacheStoreItem;
206 | completionBlock(result.tokenCacheStoreItem.userInformation, nil);
207 | }
208 | }];
209 | }
210 |
211 | +(void) getTaskList:(void (^) (NSArray*, NSError*))completionBlock
212 | parent:(UIViewController*) parent;
213 | {
214 | if (!loadedApplicationSettings)
215 | {
216 | [self readApplicationSettings];
217 | }
218 |
219 | SamplesApplicationData* data = [SamplesApplicationData getInstance];
220 |
221 | [self craftRequest:[self.class trimString:data.taskWebApiUrlString]
222 | parent:parent
223 | completionHandler:^(NSMutableURLRequest *request, NSError *error) {
224 |
225 | if (error != nil)
226 | {
227 | completionBlock(nil, error);
228 | }
229 | else
230 | {
231 |
232 | NSOperationQueue *queue = [[NSOperationQueue alloc]init];
233 |
234 | [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
235 |
236 | if (error == nil && data != nil){
237 |
238 | NSArray *tasks = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
239 |
240 | //each object is a key value pair
241 | NSDictionary *keyValuePairs;
242 | NSMutableArray* sampleTaskItems = [[NSMutableArray alloc]init];
243 |
244 | for(int i =0; i < tasks.count; i++)
245 | {
246 | keyValuePairs = [tasks objectAtIndex:i];
247 |
248 | samplesTaskItem *s = [[samplesTaskItem alloc]init];
249 | s.itemName = [keyValuePairs valueForKey:@"Text"];
250 |
251 | [sampleTaskItems addObject:s];
252 | }
253 |
254 | completionBlock(sampleTaskItems, nil);
255 | }
256 | else
257 | {
258 | completionBlock(nil, error);
259 | }
260 |
261 | }];
262 | }
263 | }];
264 |
265 | }
266 |
267 | +(void) addTask:(samplesTaskItem*)task
268 | parent:(UIViewController*) parent
269 | completionBlock:(void (^) (bool, NSError* error)) completionBlock
270 | {
271 | if (!loadedApplicationSettings)
272 | {
273 | [self readApplicationSettings];
274 | }
275 |
276 | SamplesApplicationData* data = [SamplesApplicationData getInstance];
277 | [self craftRequest:data.taskWebApiUrlString parent:parent completionHandler:^(NSMutableURLRequest* request, NSError* error){
278 |
279 | if (error != nil)
280 | {
281 | completionBlock(NO, error);
282 | }
283 | else
284 | {
285 | NSDictionary* taskInDictionaryFormat = [self convertTaskToDictionary:task];
286 |
287 | NSData* requestBody = [NSJSONSerialization dataWithJSONObject:taskInDictionaryFormat options:0 error:nil];
288 |
289 | [request setHTTPMethod:@"POST"];
290 | [request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
291 | [request setHTTPBody:requestBody];
292 |
293 | NSOperationQueue *queue = [[NSOperationQueue alloc]init];
294 |
295 | [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
296 |
297 | NSString* content = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
298 | NSLog(@"%@", content);
299 |
300 | if (error == nil){
301 |
302 | completionBlock(true, nil);
303 | }
304 | else
305 | {
306 | completionBlock(false, error);
307 | }
308 | }];
309 | }
310 | }];
311 | }
312 |
313 | +(void) deleteTask:(samplesTaskItem*)task
314 | parent:(UIViewController*) parent
315 | completionBlock:(void (^) (bool, NSError* error)) completionBlock
316 | {
317 | if (!loadedApplicationSettings)
318 | {
319 | [self readApplicationSettings];
320 | }
321 |
322 | SamplesApplicationData* data = [SamplesApplicationData getInstance];
323 | [self craftRequest:data.taskWebApiUrlString parent:parent completionHandler:^(NSMutableURLRequest* request, NSError* error){
324 |
325 | if (error != nil)
326 | {
327 | completionBlock(NO, error);
328 | }
329 | else
330 | {
331 | NSDictionary* taskInDictionaryFormat = [self convertTaskToDictionary:task];
332 |
333 | NSData* requestBody = [NSJSONSerialization dataWithJSONObject:taskInDictionaryFormat options:0 error:nil];
334 |
335 | [request setHTTPMethod:@"DELETE"];
336 | [request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
337 | [request setHTTPBody:requestBody];
338 |
339 | NSLog(@"%@", request);
340 |
341 | NSOperationQueue *queue = [[NSOperationQueue alloc]init];
342 |
343 | [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
344 |
345 | NSString* content = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
346 | NSLog(@"%@", content);
347 |
348 | if (error == nil){
349 |
350 | completionBlock(true, nil);
351 | }
352 | else
353 | {
354 | completionBlock(false, error);
355 | }
356 | }];
357 | }
358 | }];
359 | }
360 |
361 |
362 | // A simple callback that makes sense of all the getClaims* above.
363 |
364 | +(void) doLogin:(BOOL) prompt
365 | parent:(UIViewController*) parent
366 | completionBlock:(void (^) (ADUserInformation* userInfo, NSError* error)) completionBlock
367 | {
368 | if (!loadedApplicationSettings)
369 | {
370 | [self readApplicationSettings];
371 | }
372 |
373 | [self getClaims:NO parent:parent completionHandler:^(ADUserInformation* userInfo, NSError* error) {
374 |
375 | if (userInfo == nil)
376 | {
377 | completionBlock(nil, error);
378 | }
379 |
380 | else {
381 |
382 | completionBlock(userInfo, nil);
383 | }
384 | }];
385 |
386 | }
387 |
388 | // Although not yet used in this sample, this demonstrates how you could pass policies to the server.
389 | // See the Native-iOS-B2C sample for more information.
390 |
391 | +(void) doPolicy:(samplesPolicyData *)policy
392 | parent:(UIViewController*) parent
393 | completionBlock:(void (^) (ADUserInformation* userInfo, NSError* error)) completionBlock
394 | {
395 | if (!loadedApplicationSettings)
396 | {
397 | [self readApplicationSettings];
398 | }
399 |
400 | NSDictionary* params = [self convertPolicyToDictionary:policy];
401 |
402 | [self getClaimsWithExtraParams:NO params:params parent:parent completionHandler:^(ADUserInformation* userInfo, NSError* error) {
403 |
404 | if (userInfo == nil)
405 | {
406 | completionBlock(nil, error);
407 | }
408 |
409 | else {
410 |
411 | completionBlock(userInfo, nil);
412 | }
413 | }];
414 |
415 | }
416 |
417 | +(void) craftRequest : (NSString*)webApiUrlString
418 | parent:(UIViewController*) parent
419 | completionHandler:(void (^)(NSMutableURLRequest*, NSError* error))completionBlock
420 | {
421 | [self getToken:NO parent:parent completionHandler:^(NSString* accessToken, NSError* error){
422 |
423 | if (accessToken == nil)
424 | {
425 | completionBlock(nil,error);
426 | }
427 | else
428 | {
429 | NSURL *webApiURL = [[NSURL alloc]initWithString:webApiUrlString];
430 |
431 | NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:webApiURL];
432 |
433 | NSString *authHeader = [NSString stringWithFormat:@"Bearer %@", accessToken];
434 |
435 | [request addValue:authHeader forHTTPHeaderField:@"Authorization"];
436 |
437 | completionBlock(request, nil);
438 | }
439 | }];
440 | }
441 |
442 | // Here we have some converstion helpers that allow us to parse passed items in to dictionaries for URLEncoding later.
443 |
444 | +(NSDictionary*) convertTaskToDictionary:(samplesTaskItem*)task
445 | {
446 | NSMutableDictionary* dictionary = [[NSMutableDictionary alloc]init];
447 |
448 | if (task.itemName){
449 | [dictionary setValue:task.itemName forKey:@"Text"];
450 | }
451 |
452 | return dictionary;
453 | }
454 |
455 | +(NSDictionary*) convertPolicyToDictionary:(samplesPolicyData*)policy
456 | {
457 | NSMutableDictionary* dictionary = [[NSMutableDictionary alloc]init];
458 |
459 | // Using UUID for nonce. Not recommended.
460 |
461 | NSString *UUID = [[NSUUID UUID] UUIDString];
462 |
463 |
464 | if (policy.policyID){
465 | [dictionary setValue:policy.policyID forKey:@"p"];
466 | [dictionary setValue:@"openid" forKey:@"scope"];
467 | [dictionary setValue:UUID forKey:@"nonce"];
468 | [dictionary setValue:@"query" forKey:@"response_mode"];
469 | [dictionary setValue:@"1" forKey:@"nux"];
470 | }
471 |
472 | return dictionary;
473 | }
474 |
475 |
476 |
477 | +(void) signOut
478 | {
479 | [authContext.tokenCacheStore removeAllWithError:nil];
480 |
481 | NSHTTPCookie *cookie;
482 |
483 | NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
484 | for (cookie in [storage cookies])
485 | {
486 | [storage deleteCookie:cookie];
487 | }
488 | }
489 |
490 | @end
491 |
--------------------------------------------------------------------------------
/Microsoft Tasks/Main_iPhone.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
26 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
190 |
191 |
192 |
193 | Access Microsoft Tasks using your Microsoft Work Account. You can use any user in your tenant if you have granted permission to use the app in your Azure administrative console.
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
267 |
268 |
269 |
270 |
271 |
272 |
278 |
279 |
280 |
281 |
282 |
283 |
289 |
290 |
291 |
292 |
293 |
294 |
300 |
301 |
302 |
303 |
304 |
305 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
324 |
325 |
326 |
327 |
328 |
329 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
407 |
408 |
409 |
410 | Change the settings this application uses at runtime. Very convinient for changing your Task server or for changing user policies that are invoked at the server.
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
--------------------------------------------------------------------------------
/Microsoft Tasks.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 97C15AF41A27FDF0004A0419 /* SamplesSelectUserViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C15AF31A27FDF0004A0419 /* SamplesSelectUserViewController.m */; };
11 | 97C15AF71A280BEF004A0419 /* SamplesApplicationData.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C15AF61A280BEF004A0419 /* SamplesApplicationData.m */; };
12 | 97C15AFA1A29C9F3004A0419 /* SamplesAppSettingsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C15AF91A29C9F3004A0419 /* SamplesAppSettingsController.m */; };
13 | A7C8E8174A44140EEB0E7EF2 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 075B6E5720AC4E29872664F4 /* libPods.a */; };
14 | B82906B71AE6C98300E1977C /* NSDictionary+UrlEncoding.m in Sources */ = {isa = PBXBuildFile; fileRef = B82906B61AE6C98300E1977C /* NSDictionary+UrlEncoding.m */; };
15 | B82906B91AE6CA8100E1977C /* samplesPolicyData.m in Sources */ = {isa = PBXBuildFile; fileRef = B82906B81AE6CA8100E1977C /* samplesPolicyData.m */; };
16 | B82906BD1AE6CD1100E1977C /* samplesShowClaimsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B82906BC1AE6CD1100E1977C /* samplesShowClaimsViewController.m */; };
17 | B82906C01AE6DA2A00E1977C /* samplesLoginViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B82906BF1AE6DA2A00E1977C /* samplesLoginViewController.m */; };
18 | EC01CD8C7777703E90A7F804 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 075B6E5720AC4E29872664F4 /* libPods.a */; };
19 | FB33714918CA5B7E00234804 /* settings.plist in Resources */ = {isa = PBXBuildFile; fileRef = FB33714818CA5B7E00234804 /* settings.plist */; };
20 | FB3BF22018D0106C007E645E /* samplesWebAPIConnector.m in Sources */ = {isa = PBXBuildFile; fileRef = FB3BF21F18D0106C007E645E /* samplesWebAPIConnector.m */; };
21 | FB3BF22118D0106C007E645E /* samplesWebAPIConnector.m in Sources */ = {isa = PBXBuildFile; fileRef = FB3BF21F18D0106C007E645E /* samplesWebAPIConnector.m */; };
22 | FB3BF23518D03A88007E645E /* Main_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB3BF23218D03A88007E645E /* Main_iPhone.storyboard */; };
23 | FB3BF23618D03A88007E645E /* Main_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB3BF23218D03A88007E645E /* Main_iPhone.storyboard */; };
24 | FB3F00DA18C7016200173598 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB3F00D918C7016200173598 /* Foundation.framework */; };
25 | FB3F00DC18C7016200173598 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB3F00DB18C7016200173598 /* CoreGraphics.framework */; };
26 | FB3F00DE18C7016200173598 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB3F00DD18C7016200173598 /* UIKit.framework */; };
27 | FB3F00E018C7016200173598 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB3F00DF18C7016200173598 /* CoreData.framework */; };
28 | FB3F00E618C7016200173598 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = FB3F00E418C7016200173598 /* InfoPlist.strings */; };
29 | FB3F00E818C7016200173598 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = FB3F00E718C7016200173598 /* main.m */; };
30 | FB3F00EC18C7016200173598 /* samplesAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FB3F00EB18C7016200173598 /* samplesAppDelegate.m */; };
31 | FB3F00EF18C7016200173598 /* Microsoft_Tasks.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = FB3F00ED18C7016200173598 /* Microsoft_Tasks.xcdatamodeld */; };
32 | FB3F00F118C7016200173598 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FB3F00F018C7016200173598 /* Images.xcassets */; };
33 | FB3F00F818C7016200173598 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB3F00F718C7016200173598 /* XCTest.framework */; };
34 | FB3F00F918C7016200173598 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB3F00D918C7016200173598 /* Foundation.framework */; };
35 | FB3F00FA18C7016200173598 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB3F00DD18C7016200173598 /* UIKit.framework */; };
36 | FB3F00FB18C7016200173598 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB3F00DF18C7016200173598 /* CoreData.framework */; };
37 | FB3F010318C7016200173598 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = FB3F010118C7016200173598 /* InfoPlist.strings */; };
38 | FB3F010518C7016200173598 /* Microsoft_TasksTests.m in Sources */ = {isa = PBXBuildFile; fileRef = FB3F010418C7016200173598 /* Microsoft_TasksTests.m */; };
39 | FB3F011618C7092700173598 /* sampleAddTaskItemViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FB3F011518C7092700173598 /* sampleAddTaskItemViewController.m */; };
40 | FB3F011C18C709FE00173598 /* samplesTaskListTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FB3F011B18C709FE00173598 /* samplesTaskListTableViewController.m */; };
41 | FB3F011F18C713E600173598 /* samplesTaskItem.m in Sources */ = {isa = PBXBuildFile; fileRef = FB3F011E18C713E600173598 /* samplesTaskItem.m */; };
42 | /* End PBXBuildFile section */
43 |
44 | /* Begin PBXContainerItemProxy section */
45 | FB3F00FC18C7016200173598 /* PBXContainerItemProxy */ = {
46 | isa = PBXContainerItemProxy;
47 | containerPortal = FB3F00CE18C7016200173598 /* Project object */;
48 | proxyType = 1;
49 | remoteGlobalIDString = FB3F00D518C7016200173598;
50 | remoteInfo = "Microsoft Tasks";
51 | };
52 | /* End PBXContainerItemProxy section */
53 |
54 | /* Begin PBXFileReference section */
55 | 075B6E5720AC4E29872664F4 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
56 | 268C6853C490B04D8D505AD7 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; };
57 | 32C2DA3BB2D20EAD1E82DBA0 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; };
58 | 971963C41A6845950026BC5F /* Microsoft Tasks.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "Microsoft Tasks.entitlements"; sourceTree = ""; };
59 | 97C15AF01A27FAD6004A0419 /* SamplesSelectUserViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SamplesSelectUserViewController.h; sourceTree = ""; };
60 | 97C15AF31A27FDF0004A0419 /* SamplesSelectUserViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SamplesSelectUserViewController.m; sourceTree = ""; };
61 | 97C15AF51A280B69004A0419 /* SamplesApplicationData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SamplesApplicationData.h; sourceTree = ""; };
62 | 97C15AF61A280BEF004A0419 /* SamplesApplicationData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SamplesApplicationData.m; sourceTree = ""; };
63 | 97C15AF81A29C9E3004A0419 /* SamplesAppSettingsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SamplesAppSettingsController.h; sourceTree = ""; };
64 | 97C15AF91A29C9F3004A0419 /* SamplesAppSettingsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SamplesAppSettingsController.m; sourceTree = ""; };
65 | B82906B51AE6C98300E1977C /* NSDictionary+UrlEncoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+UrlEncoding.h"; sourceTree = ""; };
66 | B82906B61AE6C98300E1977C /* NSDictionary+UrlEncoding.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+UrlEncoding.m"; sourceTree = ""; };
67 | B82906B81AE6CA8100E1977C /* samplesPolicyData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = samplesPolicyData.m; sourceTree = ""; };
68 | B82906BA1AE6CA9400E1977C /* samplesPolicyData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = samplesPolicyData.h; sourceTree = ""; };
69 | B82906BB1AE6CD1100E1977C /* samplesShowClaimsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = samplesShowClaimsViewController.h; sourceTree = ""; };
70 | B82906BC1AE6CD1100E1977C /* samplesShowClaimsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = samplesShowClaimsViewController.m; sourceTree = ""; };
71 | B82906BE1AE6DA2A00E1977C /* samplesLoginViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = samplesLoginViewController.h; sourceTree = ""; };
72 | B82906BF1AE6DA2A00E1977C /* samplesLoginViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = samplesLoginViewController.m; sourceTree = ""; };
73 | FB33714818CA5B7E00234804 /* settings.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = settings.plist; sourceTree = ""; };
74 | FB3BF21E18D0106C007E645E /* samplesWebAPIConnector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = samplesWebAPIConnector.h; sourceTree = ""; };
75 | FB3BF21F18D0106C007E645E /* samplesWebAPIConnector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = samplesWebAPIConnector.m; sourceTree = ""; };
76 | FB3BF23218D03A88007E645E /* Main_iPhone.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main_iPhone.storyboard; sourceTree = ""; };
77 | FB3F00D618C7016200173598 /* Microsoft Tasks.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Microsoft Tasks.app"; sourceTree = BUILT_PRODUCTS_DIR; };
78 | FB3F00D918C7016200173598 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
79 | FB3F00DB18C7016200173598 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
80 | FB3F00DD18C7016200173598 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
81 | FB3F00DF18C7016200173598 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
82 | FB3F00E318C7016200173598 /* Microsoft Tasks-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Microsoft Tasks-Info.plist"; sourceTree = ""; };
83 | FB3F00E518C7016200173598 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
84 | FB3F00E718C7016200173598 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
85 | FB3F00E918C7016200173598 /* Microsoft Tasks-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Microsoft Tasks-Prefix.pch"; sourceTree = ""; };
86 | FB3F00EA18C7016200173598 /* samplesAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = samplesAppDelegate.h; sourceTree = ""; };
87 | FB3F00EB18C7016200173598 /* samplesAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = samplesAppDelegate.m; sourceTree = ""; };
88 | FB3F00EE18C7016200173598 /* Microsoft_Tasks.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Microsoft_Tasks.xcdatamodel; sourceTree = ""; };
89 | FB3F00F018C7016200173598 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
90 | FB3F00F618C7016200173598 /* Microsoft TasksTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Microsoft TasksTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
91 | FB3F00F718C7016200173598 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
92 | FB3F010018C7016200173598 /* Microsoft TasksTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Microsoft TasksTests-Info.plist"; sourceTree = ""; };
93 | FB3F010218C7016200173598 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
94 | FB3F010418C7016200173598 /* Microsoft_TasksTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Microsoft_TasksTests.m; sourceTree = ""; };
95 | FB3F011418C7092700173598 /* sampleAddTaskItemViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sampleAddTaskItemViewController.h; sourceTree = ""; };
96 | FB3F011518C7092700173598 /* sampleAddTaskItemViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = sampleAddTaskItemViewController.m; sourceTree = ""; };
97 | FB3F011A18C709FE00173598 /* samplesTaskListTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = samplesTaskListTableViewController.h; sourceTree = ""; };
98 | FB3F011B18C709FE00173598 /* samplesTaskListTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = samplesTaskListTableViewController.m; sourceTree = ""; };
99 | FB3F011D18C713E600173598 /* samplesTaskItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = samplesTaskItem.h; sourceTree = ""; };
100 | FB3F011E18C713E600173598 /* samplesTaskItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = samplesTaskItem.m; sourceTree = ""; };
101 | /* End PBXFileReference section */
102 |
103 | /* Begin PBXFrameworksBuildPhase section */
104 | FB3F00D318C7016200173598 /* Frameworks */ = {
105 | isa = PBXFrameworksBuildPhase;
106 | buildActionMask = 2147483647;
107 | files = (
108 | FB3F00DC18C7016200173598 /* CoreGraphics.framework in Frameworks */,
109 | FB3F00E018C7016200173598 /* CoreData.framework in Frameworks */,
110 | FB3F00DE18C7016200173598 /* UIKit.framework in Frameworks */,
111 | FB3F00DA18C7016200173598 /* Foundation.framework in Frameworks */,
112 | A7C8E8174A44140EEB0E7EF2 /* libPods.a in Frameworks */,
113 | );
114 | runOnlyForDeploymentPostprocessing = 0;
115 | };
116 | FB3F00F318C7016200173598 /* Frameworks */ = {
117 | isa = PBXFrameworksBuildPhase;
118 | buildActionMask = 2147483647;
119 | files = (
120 | FB3F00F818C7016200173598 /* XCTest.framework in Frameworks */,
121 | FB3F00FB18C7016200173598 /* CoreData.framework in Frameworks */,
122 | FB3F00FA18C7016200173598 /* UIKit.framework in Frameworks */,
123 | FB3F00F918C7016200173598 /* Foundation.framework in Frameworks */,
124 | EC01CD8C7777703E90A7F804 /* libPods.a in Frameworks */,
125 | );
126 | runOnlyForDeploymentPostprocessing = 0;
127 | };
128 | /* End PBXFrameworksBuildPhase section */
129 |
130 | /* Begin PBXGroup section */
131 | 3815BCDF3B86DDADB63BCC4F /* Pods */ = {
132 | isa = PBXGroup;
133 | children = (
134 | 268C6853C490B04D8D505AD7 /* Pods.debug.xcconfig */,
135 | 32C2DA3BB2D20EAD1E82DBA0 /* Pods.release.xcconfig */,
136 | );
137 | name = Pods;
138 | sourceTree = "";
139 | };
140 | FB3F00CD18C7016200173598 = {
141 | isa = PBXGroup;
142 | children = (
143 | FB3F00E118C7016200173598 /* Microsoft Tasks */,
144 | FB3F00FE18C7016200173598 /* Microsoft TasksTests */,
145 | FB3F00D818C7016200173598 /* Frameworks */,
146 | FB3F00D718C7016200173598 /* Products */,
147 | 3815BCDF3B86DDADB63BCC4F /* Pods */,
148 | );
149 | sourceTree = "";
150 | };
151 | FB3F00D718C7016200173598 /* Products */ = {
152 | isa = PBXGroup;
153 | children = (
154 | FB3F00D618C7016200173598 /* Microsoft Tasks.app */,
155 | FB3F00F618C7016200173598 /* Microsoft TasksTests.xctest */,
156 | );
157 | name = Products;
158 | sourceTree = "";
159 | };
160 | FB3F00D818C7016200173598 /* Frameworks */ = {
161 | isa = PBXGroup;
162 | children = (
163 | FB3F00D918C7016200173598 /* Foundation.framework */,
164 | FB3F00DB18C7016200173598 /* CoreGraphics.framework */,
165 | FB3F00DD18C7016200173598 /* UIKit.framework */,
166 | FB3F00DF18C7016200173598 /* CoreData.framework */,
167 | FB3F00F718C7016200173598 /* XCTest.framework */,
168 | 075B6E5720AC4E29872664F4 /* libPods.a */,
169 | );
170 | name = Frameworks;
171 | sourceTree = "";
172 | };
173 | FB3F00E118C7016200173598 /* Microsoft Tasks */ = {
174 | isa = PBXGroup;
175 | children = (
176 | 971963C41A6845950026BC5F /* Microsoft Tasks.entitlements */,
177 | FB3BF23218D03A88007E645E /* Main_iPhone.storyboard */,
178 | FB3F00E418C7016200173598 /* InfoPlist.strings */,
179 | FB3F00EA18C7016200173598 /* samplesAppDelegate.h */,
180 | FB3F00EB18C7016200173598 /* samplesAppDelegate.m */,
181 | FB3F00F018C7016200173598 /* Images.xcassets */,
182 | FB3F00ED18C7016200173598 /* Microsoft_Tasks.xcdatamodeld */,
183 | FB3F00E218C7016200173598 /* Supporting Files */,
184 | FB3F011418C7092700173598 /* sampleAddTaskItemViewController.h */,
185 | FB3F011518C7092700173598 /* sampleAddTaskItemViewController.m */,
186 | FB3F011A18C709FE00173598 /* samplesTaskListTableViewController.h */,
187 | FB3F011B18C709FE00173598 /* samplesTaskListTableViewController.m */,
188 | FB3F011D18C713E600173598 /* samplesTaskItem.h */,
189 | FB3F011E18C713E600173598 /* samplesTaskItem.m */,
190 | FB3BF21E18D0106C007E645E /* samplesWebAPIConnector.h */,
191 | FB3BF21F18D0106C007E645E /* samplesWebAPIConnector.m */,
192 | 97C15AF01A27FAD6004A0419 /* SamplesSelectUserViewController.h */,
193 | 97C15AF31A27FDF0004A0419 /* SamplesSelectUserViewController.m */,
194 | 97C15AF51A280B69004A0419 /* SamplesApplicationData.h */,
195 | 97C15AF61A280BEF004A0419 /* SamplesApplicationData.m */,
196 | 97C15AF81A29C9E3004A0419 /* SamplesAppSettingsController.h */,
197 | 97C15AF91A29C9F3004A0419 /* SamplesAppSettingsController.m */,
198 | B82906B51AE6C98300E1977C /* NSDictionary+UrlEncoding.h */,
199 | B82906B61AE6C98300E1977C /* NSDictionary+UrlEncoding.m */,
200 | B82906B81AE6CA8100E1977C /* samplesPolicyData.m */,
201 | B82906BA1AE6CA9400E1977C /* samplesPolicyData.h */,
202 | B82906BB1AE6CD1100E1977C /* samplesShowClaimsViewController.h */,
203 | B82906BC1AE6CD1100E1977C /* samplesShowClaimsViewController.m */,
204 | B82906BE1AE6DA2A00E1977C /* samplesLoginViewController.h */,
205 | B82906BF1AE6DA2A00E1977C /* samplesLoginViewController.m */,
206 | );
207 | path = "Microsoft Tasks";
208 | sourceTree = "";
209 | };
210 | FB3F00E218C7016200173598 /* Supporting Files */ = {
211 | isa = PBXGroup;
212 | children = (
213 | FB3F00E318C7016200173598 /* Microsoft Tasks-Info.plist */,
214 | FB3F00E718C7016200173598 /* main.m */,
215 | FB3F00E918C7016200173598 /* Microsoft Tasks-Prefix.pch */,
216 | FB33714818CA5B7E00234804 /* settings.plist */,
217 | );
218 | name = "Supporting Files";
219 | sourceTree = "";
220 | };
221 | FB3F00FE18C7016200173598 /* Microsoft TasksTests */ = {
222 | isa = PBXGroup;
223 | children = (
224 | FB3F010418C7016200173598 /* Microsoft_TasksTests.m */,
225 | FB3F00FF18C7016200173598 /* Supporting Files */,
226 | );
227 | path = "Microsoft TasksTests";
228 | sourceTree = "";
229 | };
230 | FB3F00FF18C7016200173598 /* Supporting Files */ = {
231 | isa = PBXGroup;
232 | children = (
233 | FB3F010018C7016200173598 /* Microsoft TasksTests-Info.plist */,
234 | FB3F010118C7016200173598 /* InfoPlist.strings */,
235 | );
236 | name = "Supporting Files";
237 | sourceTree = "";
238 | };
239 | /* End PBXGroup section */
240 |
241 | /* Begin PBXNativeTarget section */
242 | FB3F00D518C7016200173598 /* Microsoft Tasks */ = {
243 | isa = PBXNativeTarget;
244 | buildConfigurationList = FB3F010818C7016200173598 /* Build configuration list for PBXNativeTarget "Microsoft Tasks" */;
245 | buildPhases = (
246 | 242E920A0FC14065B8E09F12 /* Check Pods Manifest.lock */,
247 | FB3F00D218C7016200173598 /* Sources */,
248 | FB3F00D318C7016200173598 /* Frameworks */,
249 | FB3F00D418C7016200173598 /* Resources */,
250 | 2E16D7D83C534279873FC06F /* Copy Pods Resources */,
251 | B844A9A71AEF103A00224ED9 /* ShellScript */,
252 | );
253 | buildRules = (
254 | );
255 | dependencies = (
256 | );
257 | name = "Microsoft Tasks";
258 | productName = "Microsoft Tasks";
259 | productReference = FB3F00D618C7016200173598 /* Microsoft Tasks.app */;
260 | productType = "com.apple.product-type.application";
261 | };
262 | FB3F00F518C7016200173598 /* Microsoft TasksTests */ = {
263 | isa = PBXNativeTarget;
264 | buildConfigurationList = FB3F010B18C7016200173598 /* Build configuration list for PBXNativeTarget "Microsoft TasksTests" */;
265 | buildPhases = (
266 | 573F442CE68680C3300FD91C /* Check Pods Manifest.lock */,
267 | FB3F00F218C7016200173598 /* Sources */,
268 | FB3F00F318C7016200173598 /* Frameworks */,
269 | FB3F00F418C7016200173598 /* Resources */,
270 | AD96A739D75DFECDEA53C42D /* Copy Pods Resources */,
271 | );
272 | buildRules = (
273 | );
274 | dependencies = (
275 | FB3F00FD18C7016200173598 /* PBXTargetDependency */,
276 | );
277 | name = "Microsoft TasksTests";
278 | productName = "Microsoft TasksTests";
279 | productReference = FB3F00F618C7016200173598 /* Microsoft TasksTests.xctest */;
280 | productType = "com.apple.product-type.bundle.unit-test";
281 | };
282 | /* End PBXNativeTarget section */
283 |
284 | /* Begin PBXProject section */
285 | FB3F00CE18C7016200173598 /* Project object */ = {
286 | isa = PBXProject;
287 | attributes = {
288 | CLASSPREFIX = samples;
289 | LastUpgradeCheck = 0510;
290 | ORGANIZATIONNAME = Microsoft;
291 | TargetAttributes = {
292 | FB3F00D518C7016200173598 = {
293 | DevelopmentTeam = QPA5Y64RGS;
294 | SystemCapabilities = {
295 | com.apple.Keychain = {
296 | enabled = 1;
297 | };
298 | };
299 | };
300 | FB3F00F518C7016200173598 = {
301 | TestTargetID = FB3F00D518C7016200173598;
302 | };
303 | };
304 | };
305 | buildConfigurationList = FB3F00D118C7016200173598 /* Build configuration list for PBXProject "Microsoft Tasks" */;
306 | compatibilityVersion = "Xcode 3.2";
307 | developmentRegion = English;
308 | hasScannedForEncodings = 0;
309 | knownRegions = (
310 | en,
311 | );
312 | mainGroup = FB3F00CD18C7016200173598;
313 | productRefGroup = FB3F00D718C7016200173598 /* Products */;
314 | projectDirPath = "";
315 | projectRoot = "";
316 | targets = (
317 | FB3F00D518C7016200173598 /* Microsoft Tasks */,
318 | FB3F00F518C7016200173598 /* Microsoft TasksTests */,
319 | );
320 | };
321 | /* End PBXProject section */
322 |
323 | /* Begin PBXResourcesBuildPhase section */
324 | FB3F00D418C7016200173598 /* Resources */ = {
325 | isa = PBXResourcesBuildPhase;
326 | buildActionMask = 2147483647;
327 | files = (
328 | FB3BF23518D03A88007E645E /* Main_iPhone.storyboard in Resources */,
329 | FB3F00E618C7016200173598 /* InfoPlist.strings in Resources */,
330 | FB3F00F118C7016200173598 /* Images.xcassets in Resources */,
331 | FB33714918CA5B7E00234804 /* settings.plist in Resources */,
332 | );
333 | runOnlyForDeploymentPostprocessing = 0;
334 | };
335 | FB3F00F418C7016200173598 /* Resources */ = {
336 | isa = PBXResourcesBuildPhase;
337 | buildActionMask = 2147483647;
338 | files = (
339 | FB3F010318C7016200173598 /* InfoPlist.strings in Resources */,
340 | FB3BF23618D03A88007E645E /* Main_iPhone.storyboard in Resources */,
341 | );
342 | runOnlyForDeploymentPostprocessing = 0;
343 | };
344 | /* End PBXResourcesBuildPhase section */
345 |
346 | /* Begin PBXShellScriptBuildPhase section */
347 | 242E920A0FC14065B8E09F12 /* Check Pods Manifest.lock */ = {
348 | isa = PBXShellScriptBuildPhase;
349 | buildActionMask = 2147483647;
350 | files = (
351 | );
352 | inputPaths = (
353 | );
354 | name = "Check Pods Manifest.lock";
355 | outputPaths = (
356 | );
357 | runOnlyForDeploymentPostprocessing = 0;
358 | shellPath = /bin/sh;
359 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
360 | showEnvVarsInLog = 0;
361 | };
362 | 2E16D7D83C534279873FC06F /* Copy Pods Resources */ = {
363 | isa = PBXShellScriptBuildPhase;
364 | buildActionMask = 2147483647;
365 | files = (
366 | );
367 | inputPaths = (
368 | );
369 | name = "Copy Pods Resources";
370 | outputPaths = (
371 | );
372 | runOnlyForDeploymentPostprocessing = 0;
373 | shellPath = /bin/sh;
374 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
375 | showEnvVarsInLog = 0;
376 | };
377 | 573F442CE68680C3300FD91C /* Check Pods Manifest.lock */ = {
378 | isa = PBXShellScriptBuildPhase;
379 | buildActionMask = 2147483647;
380 | files = (
381 | );
382 | inputPaths = (
383 | );
384 | name = "Check Pods Manifest.lock";
385 | outputPaths = (
386 | );
387 | runOnlyForDeploymentPostprocessing = 0;
388 | shellPath = /bin/sh;
389 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
390 | showEnvVarsInLog = 0;
391 | };
392 | AD96A739D75DFECDEA53C42D /* Copy Pods Resources */ = {
393 | isa = PBXShellScriptBuildPhase;
394 | buildActionMask = 2147483647;
395 | files = (
396 | );
397 | inputPaths = (
398 | );
399 | name = "Copy Pods Resources";
400 | outputPaths = (
401 | );
402 | runOnlyForDeploymentPostprocessing = 0;
403 | shellPath = /bin/sh;
404 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
405 | showEnvVarsInLog = 0;
406 | };
407 | B844A9A71AEF103A00224ED9 /* ShellScript */ = {
408 | isa = PBXShellScriptBuildPhase;
409 | buildActionMask = 2147483647;
410 | files = (
411 | );
412 | inputPaths = (
413 | );
414 | outputPaths = (
415 | );
416 | runOnlyForDeploymentPostprocessing = 0;
417 | shellPath = /bin/sh;
418 | shellScript = "FILE=\"${SRCROOT}/HockeySDK-iOS/BuildAgent\"\nif [ -f \"$FILE\" ]; then\n\"$FILE\"\nfi";
419 | };
420 | /* End PBXShellScriptBuildPhase section */
421 |
422 | /* Begin PBXSourcesBuildPhase section */
423 | FB3F00D218C7016200173598 /* Sources */ = {
424 | isa = PBXSourcesBuildPhase;
425 | buildActionMask = 2147483647;
426 | files = (
427 | 97C15AFA1A29C9F3004A0419 /* SamplesAppSettingsController.m in Sources */,
428 | FB3F011618C7092700173598 /* sampleAddTaskItemViewController.m in Sources */,
429 | B82906B71AE6C98300E1977C /* NSDictionary+UrlEncoding.m in Sources */,
430 | FB3F011F18C713E600173598 /* samplesTaskItem.m in Sources */,
431 | FB3F00EF18C7016200173598 /* Microsoft_Tasks.xcdatamodeld in Sources */,
432 | B82906B91AE6CA8100E1977C /* samplesPolicyData.m in Sources */,
433 | B82906BD1AE6CD1100E1977C /* samplesShowClaimsViewController.m in Sources */,
434 | FB3F011C18C709FE00173598 /* samplesTaskListTableViewController.m in Sources */,
435 | FB3F00EC18C7016200173598 /* samplesAppDelegate.m in Sources */,
436 | 97C15AF71A280BEF004A0419 /* SamplesApplicationData.m in Sources */,
437 | B82906C01AE6DA2A00E1977C /* samplesLoginViewController.m in Sources */,
438 | FB3BF22018D0106C007E645E /* samplesWebAPIConnector.m in Sources */,
439 | 97C15AF41A27FDF0004A0419 /* SamplesSelectUserViewController.m in Sources */,
440 | FB3F00E818C7016200173598 /* main.m in Sources */,
441 | );
442 | runOnlyForDeploymentPostprocessing = 0;
443 | };
444 | FB3F00F218C7016200173598 /* Sources */ = {
445 | isa = PBXSourcesBuildPhase;
446 | buildActionMask = 2147483647;
447 | files = (
448 | FB3F010518C7016200173598 /* Microsoft_TasksTests.m in Sources */,
449 | FB3BF22118D0106C007E645E /* samplesWebAPIConnector.m in Sources */,
450 | );
451 | runOnlyForDeploymentPostprocessing = 0;
452 | };
453 | /* End PBXSourcesBuildPhase section */
454 |
455 | /* Begin PBXTargetDependency section */
456 | FB3F00FD18C7016200173598 /* PBXTargetDependency */ = {
457 | isa = PBXTargetDependency;
458 | target = FB3F00D518C7016200173598 /* Microsoft Tasks */;
459 | targetProxy = FB3F00FC18C7016200173598 /* PBXContainerItemProxy */;
460 | };
461 | /* End PBXTargetDependency section */
462 |
463 | /* Begin PBXVariantGroup section */
464 | FB3F00E418C7016200173598 /* InfoPlist.strings */ = {
465 | isa = PBXVariantGroup;
466 | children = (
467 | FB3F00E518C7016200173598 /* en */,
468 | );
469 | name = InfoPlist.strings;
470 | sourceTree = "";
471 | };
472 | FB3F010118C7016200173598 /* InfoPlist.strings */ = {
473 | isa = PBXVariantGroup;
474 | children = (
475 | FB3F010218C7016200173598 /* en */,
476 | );
477 | name = InfoPlist.strings;
478 | sourceTree = "";
479 | };
480 | /* End PBXVariantGroup section */
481 |
482 | /* Begin XCBuildConfiguration section */
483 | FB3F010618C7016200173598 /* Debug */ = {
484 | isa = XCBuildConfiguration;
485 | buildSettings = {
486 | ALWAYS_SEARCH_USER_PATHS = NO;
487 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
488 | CLANG_CXX_LIBRARY = "libc++";
489 | CLANG_ENABLE_MODULES = YES;
490 | CLANG_ENABLE_OBJC_ARC = YES;
491 | CLANG_WARN_BOOL_CONVERSION = YES;
492 | CLANG_WARN_CONSTANT_CONVERSION = YES;
493 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
494 | CLANG_WARN_EMPTY_BODY = YES;
495 | CLANG_WARN_ENUM_CONVERSION = YES;
496 | CLANG_WARN_INT_CONVERSION = YES;
497 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
498 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
499 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
500 | COPY_PHASE_STRIP = NO;
501 | GCC_C_LANGUAGE_STANDARD = gnu99;
502 | GCC_DYNAMIC_NO_PIC = NO;
503 | GCC_OPTIMIZATION_LEVEL = 0;
504 | GCC_PREPROCESSOR_DEFINITIONS = (
505 | "DEBUG=1",
506 | "$(inherited)",
507 | );
508 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
509 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
510 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
511 | GCC_WARN_UNDECLARED_SELECTOR = YES;
512 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
513 | GCC_WARN_UNUSED_FUNCTION = YES;
514 | GCC_WARN_UNUSED_VARIABLE = YES;
515 | IPHONEOS_DEPLOYMENT_TARGET = 7.1;
516 | ONLY_ACTIVE_ARCH = YES;
517 | SDKROOT = iphoneos;
518 | };
519 | name = Debug;
520 | };
521 | FB3F010718C7016200173598 /* Release */ = {
522 | isa = XCBuildConfiguration;
523 | buildSettings = {
524 | ALWAYS_SEARCH_USER_PATHS = NO;
525 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
526 | CLANG_CXX_LIBRARY = "libc++";
527 | CLANG_ENABLE_MODULES = YES;
528 | CLANG_ENABLE_OBJC_ARC = YES;
529 | CLANG_WARN_BOOL_CONVERSION = YES;
530 | CLANG_WARN_CONSTANT_CONVERSION = YES;
531 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
532 | CLANG_WARN_EMPTY_BODY = YES;
533 | CLANG_WARN_ENUM_CONVERSION = YES;
534 | CLANG_WARN_INT_CONVERSION = YES;
535 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
536 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
537 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
538 | COPY_PHASE_STRIP = YES;
539 | ENABLE_NS_ASSERTIONS = NO;
540 | GCC_C_LANGUAGE_STANDARD = gnu99;
541 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
542 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
543 | GCC_WARN_UNDECLARED_SELECTOR = YES;
544 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
545 | GCC_WARN_UNUSED_FUNCTION = YES;
546 | GCC_WARN_UNUSED_VARIABLE = YES;
547 | IPHONEOS_DEPLOYMENT_TARGET = 7.1;
548 | SDKROOT = iphoneos;
549 | VALIDATE_PRODUCT = YES;
550 | };
551 | name = Release;
552 | };
553 | FB3F010918C7016200173598 /* Debug */ = {
554 | isa = XCBuildConfiguration;
555 | baseConfigurationReference = 268C6853C490B04D8D505AD7 /* Pods.debug.xcconfig */;
556 | buildSettings = {
557 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
558 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
559 | CODE_SIGN_ENTITLEMENTS = "Microsoft Tasks/Microsoft Tasks.entitlements";
560 | CODE_SIGN_IDENTITY = "iPhone Developer";
561 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
562 | FRAMEWORK_SEARCH_PATHS = (
563 | "$(inherited)",
564 | "$(PROJECT_DIR)",
565 | );
566 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
567 | GCC_PREFIX_HEADER = "Microsoft Tasks/Microsoft Tasks-Prefix.pch";
568 | INFOPLIST_FILE = "Microsoft Tasks/Microsoft Tasks-Info.plist";
569 | IPHONEOS_DEPLOYMENT_TARGET = 7.1;
570 | LIBRARY_SEARCH_PATHS = "$(inherited)";
571 | OTHER_LDFLAGS = "$(inherited)";
572 | PRODUCT_NAME = "$(TARGET_NAME)";
573 | PROVISIONING_PROFILE = "";
574 | TARGETED_DEVICE_FAMILY = 1;
575 | WRAPPER_EXTENSION = app;
576 | };
577 | name = Debug;
578 | };
579 | FB3F010A18C7016200173598 /* Release */ = {
580 | isa = XCBuildConfiguration;
581 | baseConfigurationReference = 32C2DA3BB2D20EAD1E82DBA0 /* Pods.release.xcconfig */;
582 | buildSettings = {
583 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
584 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
585 | CODE_SIGN_ENTITLEMENTS = "Microsoft Tasks/Microsoft Tasks.entitlements";
586 | CODE_SIGN_IDENTITY = "iPhone Developer";
587 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
588 | FRAMEWORK_SEARCH_PATHS = (
589 | "$(inherited)",
590 | "$(PROJECT_DIR)",
591 | );
592 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
593 | GCC_PREFIX_HEADER = "Microsoft Tasks/Microsoft Tasks-Prefix.pch";
594 | INFOPLIST_FILE = "Microsoft Tasks/Microsoft Tasks-Info.plist";
595 | IPHONEOS_DEPLOYMENT_TARGET = 7.1;
596 | LIBRARY_SEARCH_PATHS = "$(inherited)";
597 | OTHER_LDFLAGS = "$(inherited)";
598 | PRODUCT_NAME = "$(TARGET_NAME)";
599 | PROVISIONING_PROFILE = "";
600 | TARGETED_DEVICE_FAMILY = 1;
601 | WRAPPER_EXTENSION = app;
602 | };
603 | name = Release;
604 | };
605 | FB3F010C18C7016200173598 /* Debug */ = {
606 | isa = XCBuildConfiguration;
607 | baseConfigurationReference = 268C6853C490B04D8D505AD7 /* Pods.debug.xcconfig */;
608 | buildSettings = {
609 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Microsoft Tasks.app/Microsoft Tasks";
610 | FRAMEWORK_SEARCH_PATHS = (
611 | "$(SDKROOT)/Developer/Library/Frameworks",
612 | "$(inherited)",
613 | "$(DEVELOPER_FRAMEWORKS_DIR)",
614 | );
615 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
616 | GCC_PREFIX_HEADER = "Microsoft Tasks/Microsoft Tasks-Prefix.pch";
617 | GCC_PREPROCESSOR_DEFINITIONS = (
618 | "DEBUG=1",
619 | "$(inherited)",
620 | );
621 | INFOPLIST_FILE = "Microsoft TasksTests/Microsoft TasksTests-Info.plist";
622 | PRODUCT_NAME = "$(TARGET_NAME)";
623 | TEST_HOST = "$(BUNDLE_LOADER)";
624 | WRAPPER_EXTENSION = xctest;
625 | };
626 | name = Debug;
627 | };
628 | FB3F010D18C7016200173598 /* Release */ = {
629 | isa = XCBuildConfiguration;
630 | baseConfigurationReference = 32C2DA3BB2D20EAD1E82DBA0 /* Pods.release.xcconfig */;
631 | buildSettings = {
632 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Microsoft Tasks.app/Microsoft Tasks";
633 | FRAMEWORK_SEARCH_PATHS = (
634 | "$(SDKROOT)/Developer/Library/Frameworks",
635 | "$(inherited)",
636 | "$(DEVELOPER_FRAMEWORKS_DIR)",
637 | );
638 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
639 | GCC_PREFIX_HEADER = "Microsoft Tasks/Microsoft Tasks-Prefix.pch";
640 | INFOPLIST_FILE = "Microsoft TasksTests/Microsoft TasksTests-Info.plist";
641 | PRODUCT_NAME = "$(TARGET_NAME)";
642 | TEST_HOST = "$(BUNDLE_LOADER)";
643 | WRAPPER_EXTENSION = xctest;
644 | };
645 | name = Release;
646 | };
647 | /* End XCBuildConfiguration section */
648 |
649 | /* Begin XCConfigurationList section */
650 | FB3F00D118C7016200173598 /* Build configuration list for PBXProject "Microsoft Tasks" */ = {
651 | isa = XCConfigurationList;
652 | buildConfigurations = (
653 | FB3F010618C7016200173598 /* Debug */,
654 | FB3F010718C7016200173598 /* Release */,
655 | );
656 | defaultConfigurationIsVisible = 0;
657 | defaultConfigurationName = Release;
658 | };
659 | FB3F010818C7016200173598 /* Build configuration list for PBXNativeTarget "Microsoft Tasks" */ = {
660 | isa = XCConfigurationList;
661 | buildConfigurations = (
662 | FB3F010918C7016200173598 /* Debug */,
663 | FB3F010A18C7016200173598 /* Release */,
664 | );
665 | defaultConfigurationIsVisible = 0;
666 | defaultConfigurationName = Release;
667 | };
668 | FB3F010B18C7016200173598 /* Build configuration list for PBXNativeTarget "Microsoft TasksTests" */ = {
669 | isa = XCConfigurationList;
670 | buildConfigurations = (
671 | FB3F010C18C7016200173598 /* Debug */,
672 | FB3F010D18C7016200173598 /* Release */,
673 | );
674 | defaultConfigurationIsVisible = 0;
675 | defaultConfigurationName = Release;
676 | };
677 | /* End XCConfigurationList section */
678 |
679 | /* Begin XCVersionGroup section */
680 | FB3F00ED18C7016200173598 /* Microsoft_Tasks.xcdatamodeld */ = {
681 | isa = XCVersionGroup;
682 | children = (
683 | FB3F00EE18C7016200173598 /* Microsoft_Tasks.xcdatamodel */,
684 | );
685 | currentVersion = FB3F00EE18C7016200173598 /* Microsoft_Tasks.xcdatamodel */;
686 | path = Microsoft_Tasks.xcdatamodeld;
687 | sourceTree = "";
688 | versionGroupType = wrapper.xcdatamodel;
689 | };
690 | /* End XCVersionGroup section */
691 | };
692 | rootObject = FB3F00CE18C7016200173598 /* Project object */;
693 | }
694 |
--------------------------------------------------------------------------------