├── .gitignore ├── README.md ├── loc └── README-ja.md ├── objective-c ├── O365-iOS-Connect.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── O365-iOS-Connect.xcworkspace │ └── contents.xcworkspacedata ├── O365-iOS-Connect │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── AuthenticationManager.h │ ├── AuthenticationManager.m │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── EmailBody.html │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ ├── Office365ClientFetcher.h │ ├── Office365ClientFetcher.m │ ├── SendMailViewController.h │ ├── SendMailViewController.m │ └── main.m └── Podfile ├── readme-images └── O365-iOS-Connect-video_play_icon.png └── swift ├── O365-iOS-Connect-Swift.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── O365-iOS-Connect-Swift.xcworkspace └── contents.xcworkspacedata ├── O365-iOS-Connect-Swift ├── AppDelegate.swift ├── AuthenticationManager.swift ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard ├── EmailBody.html ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Info.plist ├── O365-Connect-Bridging-Header.h ├── O365ClientFetcher.swift └── SendMailViewController.swift └── Podfile /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 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 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | 21 | # Cocoapods 22 | Pods/ 23 | *Podfile.lock 24 | 25 | # Apple/Mac 26 | .DS_Store 27 | 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Office 365 Connect app for iOS# 2 | 3 | [日本 (日本語)](/loc/README-ja.md) (Japanese) 4 | 5 | [![Office 365 Connect sample](/readme-images/O365-iOS-Connect-video_play_icon.png)](https://youtu.be/3v__BnV61Rs "Click to see the sample in action") 6 | 7 | Connecting to Office 365 is the first step every iOS app must take to start working with the rich data and services Office 365 offers. This sample shows how to connect to Office 365 and call the sendMail API to send an email from your Office 365 mail account. You can use this sample as a starting point to quickly connect your iOS apps to Office 365. It comes in both Objective-C and Swift versions. 8 | 9 | **Table of contents** 10 | 11 | * [Set up your environment](#set-up-your-environment) 12 | * [Use CocoaPods to import the O365 iOS SDK](#use-cocoapods-to-import-the-o365-ios-sdk) 13 | * [Register your app with Microsoft Azure](#register-your-app-with-microsoft-azure) 14 | * [Get the Client ID and Redirect Uri into the project](#get-the-client-id-and-redirect-uri-into-the-project) 15 | * [Code of Interest](#code-of-interest) 16 | * [Troubleshooting](#troubleshooting) 17 | * [Additional resources](#additional-resources) 18 | 19 | 20 | 21 | ## Set up your environment ## 22 | 23 | To run the Office 365 Connect app for iOS, you need the following: 24 | 25 | 26 | * [Xcode](https://developer.apple.com/) from Apple. 27 | * An Office 365 account. You can get an Office 365 account by signing up for an [Office 365 Developer site](http://msdn.microsoft.com/library/office/fp179924.aspx). This will give you access to the APIs that you can use to create apps that target Office 365 data. 28 | * A Microsoft Azure tenant to register your application. Azure Active Directory provides identity services that applications use for authentication and authorization. To create a trial subscription, and associate it with your O365 account, see [Set up your Office 365 development environment](https://msdn.microsoft.com/office/office365/howto/setup-development-environment) and the section **To create a new Azure subscription and associate it with your Office 365 accounts** for more information. 29 | 30 | **Important**: If you already have an Azure subscription, you'll need to bind that subscription to your Office 365 account. To do this see [Set up your Office 365 development environment](https://msdn.microsoft.com/office/office365/howto/setup-development-environment) and the section **Associate your Office 365 account with Azure AD to create and manage apps** for more information. 31 | 32 | 33 | * Installation of [CocoaPods](https://cocoapods.org/) as a dependency manager. CocoaPods will allow you to pull the Office 365 and Azure Active Directory Authentication Library (ADAL) dependencies into the project. 34 | 35 | Once you have an Office 365 account, an Azure AD account that is bound to your Office 365 Developer site, you'll need to perform the following steps: 36 | 37 | 1. Register your application with Microsoft Azure, and configure the appropriate Office 365 Exchange Online permissions. We'll show you how to do this later. 38 | 2. Install and use CocoaPods to get the Office 365 and ADAL authentication dependencies into your project. We'll show you how to do this later. 39 | 3. Enter the Azure app registration specifics (ClientID and RedirectUri) into the Office 365 Connect app. 40 | 41 | 42 | ## Use CocoaPods to import the O365 iOS SDK 43 | Note: If you've never used **CocoaPods** before as a dependency manager you'll have to install it prior to getting your Office 365 iOS SDK dependencies into your project. If you already have it installed you may skip this and move on to **Getting the Office 365 SDK for iOS dependencies in your project**. 44 | 45 | Enter both these lines of code from the **Terminal** app on your Mac. 46 | 47 | sudo gem install cocoapods 48 | pod setup 49 | 50 | If the install and setup were successful, you should see the message **Setup completed in Terminal**. For more information on CocoaPods, and its usage, see [CocoaPods](https://cocoapods.org/). 51 | 52 | 53 | **Getting the Office 365 SDK for iOS dependencies in your project.** 54 | The O365 iOS Connect app already contains a podfile that will get the Office 365 and ADAL components (pods) into your project. It's located in either the **objective-c** or **swift** folder based on sample preference ("Podfile"). The example shows the contents of the file. 55 | 56 | target ‘test’ do 57 | 58 | pod 'ADALiOS', '~> 1.2.1' 59 | pod 'Office365/Outlook', '= 0.9.1' 60 | pod 'Office365/Discovery', '= 0.9.1' 61 | 62 | end 63 | 64 | 65 | You'll simply need to navigate to the project directory in the **Terminal** (root of the project folder) and run the following command. 66 | 67 | 68 | pod install 69 | 70 | Note: You should receive confirmation that these dependencies have been added to the project. If there is a syntax error in the Podfile, you will encounter an error when you run the install command. 71 | 72 | 73 | ## Register your app with Microsoft Azure 74 | 1. Sign in to the [Azure Management Portal](https://manage.windowsazure.com), using your Azure AD credentials. 75 | 2. Click **Active Directory** on the left menu, then click the directory for your Office 365 developer site. 76 | 3. On the top menu, click **Applications**. 77 | 4. Click **Add** from the bottom menu. 78 | 5. On the **What do you want to do page**, click **Add an application my organization is developing**. 79 | 6. On the **Tell us about your application** page, specify **O365-iOS-Connect** for the application name and select **NATIVE CLIENT APPLICATION** for type. 80 | 7. Click the arrow icon on the lower-right corner of the page. 81 | 8. On the Application information page, specify a Redirect URI, for this example, you can specify http://localhost/connect, and then click the check box in the lower-right hand corner of the page. Remember this value for the section **Getting the ClientID and RedirectUri into the project**. 82 | 9. Once the application has been successfully added, you will be taken to the Quick Start page for the application. From here, click Configure in the top menu. 83 | 10. Under **permissions to other applications**, add the following permission: **Add the Office 365 Exchange Online** application. Next, click the check box in the bottom right corner to add the application. Finally, when you return to the **permissions to other applications** section, select **Send mail as a user** permission under **Delegated Permissions**. 84 | 13. Copy the value specified for **Client ID** on the **Configure** page. Remember this value for the section **Getting the ClientID and RedirectUri into the project**. 85 | 14. Click **Save** in the bottom menu. 86 | 87 | 88 | ## Get the Client ID and Redirect Uri into the project 89 | 90 | Finally you'll need to add the Client ID and Redirect Uri you recorded from the previous section **Register your app with Microsoft Azure**. 91 | 92 | Browse the **O365-iOS-Connect** project directory and open up the workspace (O365-iOS-Connect.xcworkspace). In the **AuthenticationManager** file you'll see that the **ClientID** and **RedirectUri** values can be added to the top of the file. Supply the necessary values here: 93 | 94 | // You will set your application's clientId and redirect URI. You get 95 | // these when you register your application in Azure AD. 96 | static NSString * const REDIRECT_URL_STRING = @"ENTER_REDIRECT_URI_HERE"; 97 | static NSString * const CLIENT_ID = @"ENTER_CLIENT_ID_HERE"; 98 | static NSString * const AUTHORITY = @"https://login.microsoftonline.com/common"; 99 | 100 | 101 | 102 | 103 | ## Code of Interest 104 | 105 | **Authentication with Azure AD** 106 | 107 | The code for authenticating with Azure AD, which includes retrieval and management of your access tokens is located in AuthenticationManager. 108 | 109 | 110 | **Outlook Services Client** 111 | 112 | The code for creating your Outlook Services client is located in Office365ClientFetcher. The code in this file creates the Outlook Services client object required for performing API calls against the Office 365 Exchange service. The client requests will leverage the authentication code to get the application an access and refresh token to act on behalf of the user. The access and refresh token will be cached. The next time a user attempts to access the service, the access token will be issued. If the access token has expired, the client will issue the refresh token to get a new access token. 113 | 114 | 115 | **Discovery Service** 116 | 117 | The code for using the O365 Discovery service to retrieve the Exchange service endpoints/URLs is located in the internal method connectToOffice365 is called from the viewDidLoad method in SendMailViewController. 118 | 119 | 120 | **Office 365 SendMail snippet** 121 | 122 | The code for the operation to send mail is located in the sendMailMessage method in the SendMailViewController. 123 | 124 | 125 | 126 | 127 | ## Troubleshooting 128 | 129 | With the Xcode 7.0 update, App Transport Security is enabled for simulators and devices running iOS 9. See [App Transport Security Technote](https://developer.apple.com/library/prerelease/ios/technotes/App-Transport-Security-Technote/). 130 | 131 | For this sample we have created a temporary exception for the following domain in the plist: 132 | 133 | - outlook.office365.com 134 | 135 | If these exceptions are not included, all calls into the Office 365 API will fail in this app when deployed to an iOS 9 simulator in Xcode. 136 | 137 | 138 | ## Additional resources 139 | 140 | * [Office 365 code snippets for iOS](https://github.com/OfficeDev/O365-iOS-Snippets) 141 | * [Office 365 Profile Sample for iOS](https://github.com/OfficeDev/O365-iOS-Profile) 142 | * [Email Peek - An iOS app built using Office 365](https://github.com/OfficeDev/O365-iOS-EmailPeek) 143 | * [Office 365 APIs documentation](http://msdn.microsoft.com/office/office365/howto/platform-development-overview) 144 | * [File REST operations reference](http://msdn.microsoft.com/office/office365/api/files-rest-operations) 145 | * [Calendar REST operations reference](http://msdn.microsoft.com/office/office365/api/calendar-rest-operations) 146 | * [Office Dev Center](http://dev.office.com/) 147 | * [Office 365 API code samples and videos](https://msdn.microsoft.com/office/office365/howto/starter-projects-and-code-samples) 148 | 149 | 150 | 151 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information, see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 152 | -------------------------------------------------------------------------------- /loc/README-ja.md: -------------------------------------------------------------------------------- 1 | #iOS# 版 Office 365 Connect アプリ 2 | 3 | [日本 (日本語)](/loc/README-ja.md) (日本語) 4 | 5 | [![Office 365 Connect のサンプル](/readme-images/O365-iOS-Connect-video_play_icon.png)](https://youtu.be/3v__BnV61Rs "活用できるサンプルを確認するにはこちらをクリックしてください") 6 | 7 | Office 365 への接続は、各 iOS アプリが Office 365 によって提供される豊富なデータとサービスの操作を開始するために必要な最初の手順です。このサンプルは、Office 365 に接続し、sendMail API を呼び出して、Office 365 の電子メール アカウントから電子メールを送信する方法を示します。このサンプルは、iOS アプリを Office 365 にすばやく接続する開始点として使用できます。Objective-C バージョンと Swift バージョンの両方でご利用いただけます。 8 | 9 | **目次** 10 | 11 | * [環境を設定する](#set-up-your-environment) 12 | * [CocoaPods を使用して Office 365 iOS SDK をインポートする](#use-cocoapods-to-import-the-o365-ios-sdk) 13 | * [Microsoft Azure にアプリを登録する](#register-your-app-with-microsoft-azure) 14 | * [プロジェクトにクライアント ID とリダイレクト URI を取り込む](#get-the-client-id-and-redirect-uri-into-the-project) 15 | * [目的のコード](#code-of-interest) 16 | * [質問とコメント](#questions-and-comments) 17 | * [トラブルシューティング](#troubleshooting) 18 | * [その他の技術情報](#additional-resources) 19 | 20 | 21 | 22 | ## 環境を設定する ## 23 | 24 | iOS 版 Office 365 Connect アプリを実行するには、以下が必要です。 25 | 26 | 27 | * 28 | Apple 社の [Xcode](https://developer.apple.com/)。 29 | * Office 365 アカウント。Office 365 アカウントは、[Office 365 開発者向けサイト](http://msdn.microsoft.com/ja-jp/library/office/fp179924.aspx)にサインアップすると取得できます。これにより、Office 365 のデータを対象とするアプリの作成に使用できる API にアクセスできるようになります。 30 | * アプリケーションを登録する Microsoft Azure テナント。Azure Active Directory は、アプリケーションが認証と承認に使用する ID サービスを提供します。試用版のサブスクリプションを作成し、O365 アカウントに関連付ける方法の詳細については、「[Office 365 の開発環境を設定](https://msdn.microsoft.com/office/office365/howto/setup-development-environment)」および 「**新しい Azure サブスクリプションを作成し、Office 365 アカウントに関連付ける**」のセクションを参照してください。 31 | 32 | **重要事項**:Azure サブスクリプションが既ある場合、Office 365 アカウントにそのサブスクリプションをバインドする必要があります。この工程の詳細については、「[Office 365 の開発環境を設定する](https://msdn.microsoft.com/office/office365/howto/setup-development-environment)」 および「 **Office 365 アカウントを Azure AD と関連付けてアプリを作成および管理する**」のセクションを参照してください。 33 | 34 | 35 | * 依存関係マネージャーとしての [CocoaPods](https://cocoapods.org/) のインストール。CocoaPods を使用すると、Office 365 と Azure Active Directory 認証ライブラリ (ADAL) の依存関係をプロジェクトに導入することができます。 36 | 37 | Office 365 アカウント、および Office 365 開発者サイトにバインドされた Azure AD アカウントを取得したら、次の手順を実行する必要があります。 38 | 39 | 1. Microsoft Azure でアプリケーションを登録し、Office 365 Exchange Online の適切なアクセス許可を構成します。この方法については後で説明します。 40 | 2. CocoaPods をインストールし、これを使用して、プロジェクトに Office 365 と ADAL 認証の依存関係を取り込みます。この方法については後で説明します。 41 | 3. Azure アプリの登録固有の情報 (ClientID と RedirectUri) を、Office 365 Connect アプリに入力します。 42 | 43 | 44 | ## CocoaPods を使用して Office 365 iOS SDK をインポートする 45 | 注:依存関係マネージャーとして **CocoaPods** を初めて使用する場合は、これをインストールしてからプロジェクトで Office 365 iOS SDK の依存関係を取り込む必要があります。インストール済みの場合は、この手順を省略して「**プロジェクトに iOS 版 Office 365 SDK の依存関係を取り込む**」に移動しても構いません。 46 | 47 | Mac の**ターミナル** アプリケーションから、次のコード行を入力します。 48 | 49 | sudo gem install cocoapods 50 | pod setup 51 | 52 | インストールとセットアップが成功すると、「**ターミナルのセットアップが完了しました**」というメッセージが表示されます。CocoaPods とその使用法の詳細については、「[CocoaPods](https://cocoapods.org/)」を参照してください。 53 | 54 | 55 | **プロジェクトに iOS 版 Office 365 SDK の依存関係を取り込む** 56 | Office 365 iOS Connect アプリには、プロジェクトに Office 365 と ADAL のコンポーネント (pods) を取り込む podfile がすでに含まれています。podfile の場所は、サンプルの設定 (「Podfile」) に基づき、**objective-c** または **swift** のいずれかのフォルダーにあります。次の例は、このファイルの内容を示しています。 57 | 58 | target ‘test’ do 59 | 60 | pod 'ADALiOS', '~> 1.2.1' 61 | pod 'Office365/Outlook', '= 0.9.1' 62 | pod 'Office365/Discovery', '= 0.9.1' 63 | 64 | end 65 | 66 | 67 | **Terminal** (プロジェクト フォルダーのルート) にあるプロジェクトのディレクトリに移動して、次のコマンドを実行する必要があります。 68 | 69 | 70 | pod install 71 | 72 | 注: これらの依存関係がプロジェクトに追加されたことを示す確認のメッセージを受信します。Podfile に構文エラーがあると、インストール コマンドを実行する際にエラーが発生します。 73 | 74 | 75 | ## Microsoft Azure にアプリを登録する 76 | 1. Azure AD 資格情報を使用して、[Azure 管理ポータル](https://manage.windowsazure.com)にサインインします。 77 | 2. 左側のメニューで **[Active Directory]** をクリックしてから、Office 365 開発者向けサイトのディレクトリをクリックします。 78 | 3. 上部のメニューで、**[アプリケーション]** をクリックします。 79 | 4. 下部のメニューから、**[追加]** をクリックします。 80 | 5. **[何を行いますか] ページ**で、**[所属組織が開発しているアプリケーションの追加]** をクリックします。 81 | 6. **[アプリケーションについてお聞かせください]** ページで、アプリケーション名には「**O365-iOS-Connect**」を指定し、種類は「**ネイティブ クライアント アプリケーション**」を選択します。 82 | 7. ページの右下隅にある矢印アイコンをクリックします。 83 | 8. [アプリケーション情報] ページで、リダイレクト URI を指定します。この例では http://localhost/connect を指定します。続いて、ページの右下隅にあるチェック ボックスをクリックします。この値は、「**プロジェクトに ClientID と RedirectUri を取り込む**」セクションで使用するため覚えておいてください。 84 | 9. アプリケーションが正常に追加されたら、アプリケーションの [クイック スタート] ページに移動します。ここで、上部のメニューにある [構成] をクリックします。 85 | 10. **[他のアプリケーションへのアクセス許可]** で、次のアクセス許可を追加します。**Office 365 Exchange Online** アプリケーションを追加します。次に、アプリケーションを追加するために、右下隅のチェック ボックスをクリックします。最後に、**[他のアプリケーションへのアクセス許可]** セクションに戻り、**[委任されたアクセス許可]** から **[ユーザーとしてメールを送信]** を選択してください。 86 | 13. **[構成]** ページで、**[クライアント ID]** に指定された値をコピーします。この値は、「**プロジェクトに ClientID と RedirectUri を取り込む**」セクションで使用するため覚えておいてください。 87 | 14. 下部のメニューで、**[保存]** をクリックします。 88 | 89 | 90 | ## クライアント ID を取得して、URI をプロジェクトにリダイレクトする 91 | 92 | 最後に、前のセクション「**Microsoft Azure にアプリを登録する**」で記録したクライアント ID とリダイレクト URI を追加する必要があります。 93 | 94 | **O365-iOS-Connect** プロジェクトのディレクトリを参照し、ワークスペース (O365-iOS-Connect.xcworkspace) を開きます。**AuthenticationManager** ファイルで、**ClientID** と **RedirectUri** の各値がファイルの一番上に追加されていることが分かります。ここで必要な値を指定します。 95 | 96 | // You will set your application's clientId and redirect URI. You get 97 | // these when you register your application in Azure AD. 98 | static NSString * const REDIRECT_URL_STRING = @"ENTER_REDIRECT_URI_HERE"; 99 | static NSString * const CLIENT_ID = @"ENTER_CLIENT_ID_HERE"; 100 | static NSString * const AUTHORITY = @"https://login.microsoftonline.com/common"; 101 | 102 | 103 | 104 | 105 | ## 目的のコード 106 | 107 | **Azure AD での認証** 108 | 109 | Azure AD での認証 (これにはアクセス トークンの取得と管理が含まれます) 用のコードは、AuthenticationManager にあります。 110 | 111 | 112 | **Outlook サービス クライアント** 113 | 114 | Outlook サービス クライアントを作成するコードは、Office365ClientFetcher にあります。このファイル内のコードは、Office 365 Exchange サービスに対する API の呼び出しを実行するために必要な Outlook サービス クライアント オブジェクトを作成します。クライアント要求は、認証コードを利用して、アプリケーションがユーザーの代理として操作するためのアクセスおよび更新トークンを取得できるようにします。アクセスおよび更新トークンはキャッシュされます。次回ユーザーがサービスへのアクセスを試みる際、アクセス トークンが発行されます。アクセス トークンの有効期限が切れている場合、クライアントは、新しいアクセス トークンを取得するために更新トークンを発行します。 115 | 116 | 117 | **探索サービス** 118 | 119 | Office 365 探索サービスを使用して Exchange サービスのエンドポイント/URL を取得するコードは、内部メソッド connectToOffice365 にあります。このメソッドは、SendMailViewController の viewDidLoad メソッドから呼び出されます。 120 | 121 | 122 | **Office 365 SendMail スニペット** 123 | 124 | メールを送信する操作のコードは、SendMailViewController の sendMailMessage メソッドにあります。 125 | 126 | 127 | 128 | ## 質問とコメント 129 | 130 | iOS 版 Office 365 のサンプルについて、Microsoft にフィードバックをお寄せください。フィードバックは、このリポジトリの「[問題](https://github.com/OfficeDev/O365-iOS-Connect)」セクションに送信できます。
Office 365 の開発全般については、 「[スタックオーバーフロー](http://stackoverflow.com/questions/tagged/Office365+API)」に送信してください。質問には、必ず [Office365] および [API] のタグを付けてください。 131 | 132 | 133 | ## トラブルシューティング 134 | 135 | Xcode 7.0 のアップデートにより、iOS 9 を実行するシミュレーターやデバイス用に App Transport Security を使用できるようになりました。「[App Transport Security のテクニカル ノート](https://developer.apple.com/library/prerelease/ios/technotes/App-Transport-Security-Technote/)」を参照してください。 136 | 137 | このサンプルでは、plist 内の次のドメインのために一時的な例外を作成しました: 138 | 139 | - outlook.office365.com 140 | 141 | これらの例外が含まれていないと、Xcode で iOS 9 シミュレーターにデプロイされたときに、このアプリで Office 365 API へのすべての呼び出しが失敗します。 142 | 143 | 144 | ## その他の技術情報 145 | 146 | * [iOS 用 Office 365 コード スニペット](https://github.com/OfficeDev/O365-iOS-Snippets) 147 | * [iOS 用 Office 365 プロファイル サンプル](https://github.com/OfficeDev/O365-iOS-Profile) 148 | * [Email Peek - Office 365 を使用して構築された iOS アプリ](https://github.com/OfficeDev/O365-iOS-EmailPeek) 149 | * [Office 365 API ドキュメント](http://msdn.microsoft.com/office/office365/howto/platform-development-overview) 150 | * [ファイルの REST 操作のリファレンス](http://msdn.microsoft.com/office/office365/api/files-rest-operations) 151 | * [予定表の REST 操作のリファレンス](http://msdn.microsoft.com/office/office365/api/calendar-rest-operations) 152 | * [Office デベロッパー センター](http://dev.office.com/) 153 | * [Office 365 API のサンプル コードとビデオ](https://msdn.microsoft.com/office/office365/howto/starter-projects-and-code-samples) 154 | 155 | 156 | -------------------------------------------------------------------------------- /objective-c/O365-iOS-Connect.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0A1B6E041A8D442F00C17B1C /* EmailBody.html in Resources */ = {isa = PBXBuildFile; fileRef = 0A1B6E031A8D442F00C17B1C /* EmailBody.html */; }; 11 | 0CF77C7FBA1E7CE5E8C4FFCD /* libPods-O365-iOS-Connect.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AFA81AFF62899EDFEFC2222D /* libPods-O365-iOS-Connect.a */; }; 12 | D3C128941A8BC53100E39E16 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D3C128931A8BC53100E39E16 /* main.m */; }; 13 | D3C128971A8BC53100E39E16 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D3C128961A8BC53100E39E16 /* AppDelegate.m */; }; 14 | D3C1289A1A8BC53100E39E16 /* SendMailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3C128991A8BC53100E39E16 /* SendMailViewController.m */; }; 15 | D3C1289D1A8BC53100E39E16 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D3C1289B1A8BC53100E39E16 /* Main.storyboard */; }; 16 | D3C1289F1A8BC53100E39E16 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D3C1289E1A8BC53100E39E16 /* Images.xcassets */; }; 17 | D3C128A21A8BC53100E39E16 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = D3C128A01A8BC53100E39E16 /* LaunchScreen.xib */; }; 18 | D3C128B81A8BCB1800E39E16 /* AuthenticationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D3C128B71A8BCB1800E39E16 /* AuthenticationManager.m */; }; 19 | D3C128BB1A8BCB8200E39E16 /* Office365ClientFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = D3C128BA1A8BCB8200E39E16 /* Office365ClientFetcher.m */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXFileReference section */ 23 | 0A1B6E031A8D442F00C17B1C /* EmailBody.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = EmailBody.html; sourceTree = ""; }; 24 | 9D43D0D2E863787BAD49C689 /* Pods-O365-iOS-Connect.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-O365-iOS-Connect.release.xcconfig"; path = "Pods/Target Support Files/Pods-O365-iOS-Connect/Pods-O365-iOS-Connect.release.xcconfig"; sourceTree = ""; }; 25 | AFA81AFF62899EDFEFC2222D /* libPods-O365-iOS-Connect.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-O365-iOS-Connect.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 26 | CEB1AD95D5305E3A92879613 /* Pods-O365-iOS-Connect.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-O365-iOS-Connect.debug.xcconfig"; path = "Pods/Target Support Files/Pods-O365-iOS-Connect/Pods-O365-iOS-Connect.debug.xcconfig"; sourceTree = ""; }; 27 | D3C1288E1A8BC53100E39E16 /* O365-iOS-Connect.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "O365-iOS-Connect.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | D3C128921A8BC53100E39E16 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 29 | D3C128931A8BC53100E39E16 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 30 | D3C128951A8BC53100E39E16 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 31 | D3C128961A8BC53100E39E16 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 32 | D3C128981A8BC53100E39E16 /* SendMailViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SendMailViewController.h; sourceTree = ""; }; 33 | D3C128991A8BC53100E39E16 /* SendMailViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SendMailViewController.m; sourceTree = ""; }; 34 | D3C1289C1A8BC53100E39E16 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 35 | D3C1289E1A8BC53100E39E16 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 36 | D3C128A11A8BC53100E39E16 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 37 | D3C128B71A8BCB1800E39E16 /* AuthenticationManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AuthenticationManager.m; sourceTree = ""; }; 38 | D3C128B91A8BCB2900E39E16 /* AuthenticationManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AuthenticationManager.h; sourceTree = ""; }; 39 | D3C128BA1A8BCB8200E39E16 /* Office365ClientFetcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Office365ClientFetcher.m; sourceTree = ""; }; 40 | D3C128BC1A8BCBAD00E39E16 /* Office365ClientFetcher.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Office365ClientFetcher.h; sourceTree = ""; }; 41 | /* End PBXFileReference section */ 42 | 43 | /* Begin PBXFrameworksBuildPhase section */ 44 | D3C1288B1A8BC53100E39E16 /* Frameworks */ = { 45 | isa = PBXFrameworksBuildPhase; 46 | buildActionMask = 2147483647; 47 | files = ( 48 | 0CF77C7FBA1E7CE5E8C4FFCD /* libPods-O365-iOS-Connect.a in Frameworks */, 49 | ); 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | /* End PBXFrameworksBuildPhase section */ 53 | 54 | /* Begin PBXGroup section */ 55 | C14D65D08E975E5D9163CEE7 /* Frameworks */ = { 56 | isa = PBXGroup; 57 | children = ( 58 | AFA81AFF62899EDFEFC2222D /* libPods-O365-iOS-Connect.a */, 59 | ); 60 | name = Frameworks; 61 | sourceTree = ""; 62 | }; 63 | CE6CFAF679DFE008F56D56AB /* Pods */ = { 64 | isa = PBXGroup; 65 | children = ( 66 | CEB1AD95D5305E3A92879613 /* Pods-O365-iOS-Connect.debug.xcconfig */, 67 | 9D43D0D2E863787BAD49C689 /* Pods-O365-iOS-Connect.release.xcconfig */, 68 | ); 69 | name = Pods; 70 | sourceTree = ""; 71 | }; 72 | D3C128851A8BC53100E39E16 = { 73 | isa = PBXGroup; 74 | children = ( 75 | D3C128901A8BC53100E39E16 /* O365-iOS-Connect */, 76 | D3C1288F1A8BC53100E39E16 /* Products */, 77 | CE6CFAF679DFE008F56D56AB /* Pods */, 78 | C14D65D08E975E5D9163CEE7 /* Frameworks */, 79 | ); 80 | sourceTree = ""; 81 | }; 82 | D3C1288F1A8BC53100E39E16 /* Products */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | D3C1288E1A8BC53100E39E16 /* O365-iOS-Connect.app */, 86 | ); 87 | name = Products; 88 | sourceTree = ""; 89 | }; 90 | D3C128901A8BC53100E39E16 /* O365-iOS-Connect */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | D3C128951A8BC53100E39E16 /* AppDelegate.h */, 94 | D3C128961A8BC53100E39E16 /* AppDelegate.m */, 95 | D3C128981A8BC53100E39E16 /* SendMailViewController.h */, 96 | D3C128991A8BC53100E39E16 /* SendMailViewController.m */, 97 | D3C1289B1A8BC53100E39E16 /* Main.storyboard */, 98 | D3C128BC1A8BCBAD00E39E16 /* Office365ClientFetcher.h */, 99 | D3C128BA1A8BCB8200E39E16 /* Office365ClientFetcher.m */, 100 | D3C128B91A8BCB2900E39E16 /* AuthenticationManager.h */, 101 | D3C128B71A8BCB1800E39E16 /* AuthenticationManager.m */, 102 | 0A1B6E031A8D442F00C17B1C /* EmailBody.html */, 103 | D3C1289E1A8BC53100E39E16 /* Images.xcassets */, 104 | D3C128A01A8BC53100E39E16 /* LaunchScreen.xib */, 105 | D3C128911A8BC53100E39E16 /* Supporting Files */, 106 | ); 107 | path = "O365-iOS-Connect"; 108 | sourceTree = ""; 109 | }; 110 | D3C128911A8BC53100E39E16 /* Supporting Files */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | D3C128921A8BC53100E39E16 /* Info.plist */, 114 | D3C128931A8BC53100E39E16 /* main.m */, 115 | ); 116 | name = "Supporting Files"; 117 | sourceTree = ""; 118 | }; 119 | /* End PBXGroup section */ 120 | 121 | /* Begin PBXNativeTarget section */ 122 | D3C1288D1A8BC53100E39E16 /* O365-iOS-Connect */ = { 123 | isa = PBXNativeTarget; 124 | buildConfigurationList = D3C128B11A8BC53100E39E16 /* Build configuration list for PBXNativeTarget "O365-iOS-Connect" */; 125 | buildPhases = ( 126 | 85466AA4F49C700AFA067BC4 /* Check Pods Manifest.lock */, 127 | D3C1288A1A8BC53100E39E16 /* Sources */, 128 | D3C1288B1A8BC53100E39E16 /* Frameworks */, 129 | D3C1288C1A8BC53100E39E16 /* Resources */, 130 | 042660DB9A9246ADBF890F2C /* Copy Pods Resources */, 131 | B567C908562E556B4FBDC5FD /* Embed Pods Frameworks */, 132 | ); 133 | buildRules = ( 134 | ); 135 | dependencies = ( 136 | ); 137 | name = "O365-iOS-Connect"; 138 | productName = "O365-iOS-Connect"; 139 | productReference = D3C1288E1A8BC53100E39E16 /* O365-iOS-Connect.app */; 140 | productType = "com.apple.product-type.application"; 141 | }; 142 | /* End PBXNativeTarget section */ 143 | 144 | /* Begin PBXProject section */ 145 | D3C128861A8BC53100E39E16 /* Project object */ = { 146 | isa = PBXProject; 147 | attributes = { 148 | LastUpgradeCheck = 0610; 149 | ORGANIZATIONNAME = Microsoft; 150 | TargetAttributes = { 151 | D3C1288D1A8BC53100E39E16 = { 152 | CreatedOnToolsVersion = 6.1.1; 153 | }; 154 | }; 155 | }; 156 | buildConfigurationList = D3C128891A8BC53100E39E16 /* Build configuration list for PBXProject "O365-iOS-Connect" */; 157 | compatibilityVersion = "Xcode 3.2"; 158 | developmentRegion = English; 159 | hasScannedForEncodings = 0; 160 | knownRegions = ( 161 | en, 162 | Base, 163 | ); 164 | mainGroup = D3C128851A8BC53100E39E16; 165 | productRefGroup = D3C1288F1A8BC53100E39E16 /* Products */; 166 | projectDirPath = ""; 167 | projectRoot = ""; 168 | targets = ( 169 | D3C1288D1A8BC53100E39E16 /* O365-iOS-Connect */, 170 | ); 171 | }; 172 | /* End PBXProject section */ 173 | 174 | /* Begin PBXResourcesBuildPhase section */ 175 | D3C1288C1A8BC53100E39E16 /* Resources */ = { 176 | isa = PBXResourcesBuildPhase; 177 | buildActionMask = 2147483647; 178 | files = ( 179 | D3C1289D1A8BC53100E39E16 /* Main.storyboard in Resources */, 180 | 0A1B6E041A8D442F00C17B1C /* EmailBody.html in Resources */, 181 | D3C128A21A8BC53100E39E16 /* LaunchScreen.xib in Resources */, 182 | D3C1289F1A8BC53100E39E16 /* Images.xcassets in Resources */, 183 | ); 184 | runOnlyForDeploymentPostprocessing = 0; 185 | }; 186 | /* End PBXResourcesBuildPhase section */ 187 | 188 | /* Begin PBXShellScriptBuildPhase section */ 189 | 042660DB9A9246ADBF890F2C /* Copy Pods Resources */ = { 190 | isa = PBXShellScriptBuildPhase; 191 | buildActionMask = 2147483647; 192 | files = ( 193 | ); 194 | inputPaths = ( 195 | ); 196 | name = "Copy Pods Resources"; 197 | outputPaths = ( 198 | ); 199 | runOnlyForDeploymentPostprocessing = 0; 200 | shellPath = /bin/sh; 201 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-O365-iOS-Connect/Pods-O365-iOS-Connect-resources.sh\"\n"; 202 | showEnvVarsInLog = 0; 203 | }; 204 | 85466AA4F49C700AFA067BC4 /* Check Pods Manifest.lock */ = { 205 | isa = PBXShellScriptBuildPhase; 206 | buildActionMask = 2147483647; 207 | files = ( 208 | ); 209 | inputPaths = ( 210 | ); 211 | name = "Check Pods Manifest.lock"; 212 | outputPaths = ( 213 | ); 214 | runOnlyForDeploymentPostprocessing = 0; 215 | shellPath = /bin/sh; 216 | 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"; 217 | showEnvVarsInLog = 0; 218 | }; 219 | B567C908562E556B4FBDC5FD /* Embed Pods Frameworks */ = { 220 | isa = PBXShellScriptBuildPhase; 221 | buildActionMask = 2147483647; 222 | files = ( 223 | ); 224 | inputPaths = ( 225 | ); 226 | name = "Embed Pods Frameworks"; 227 | outputPaths = ( 228 | ); 229 | runOnlyForDeploymentPostprocessing = 0; 230 | shellPath = /bin/sh; 231 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-O365-iOS-Connect/Pods-O365-iOS-Connect-frameworks.sh\"\n"; 232 | showEnvVarsInLog = 0; 233 | }; 234 | /* End PBXShellScriptBuildPhase section */ 235 | 236 | /* Begin PBXSourcesBuildPhase section */ 237 | D3C1288A1A8BC53100E39E16 /* Sources */ = { 238 | isa = PBXSourcesBuildPhase; 239 | buildActionMask = 2147483647; 240 | files = ( 241 | D3C1289A1A8BC53100E39E16 /* SendMailViewController.m in Sources */, 242 | D3C128BB1A8BCB8200E39E16 /* Office365ClientFetcher.m in Sources */, 243 | D3C128B81A8BCB1800E39E16 /* AuthenticationManager.m in Sources */, 244 | D3C128971A8BC53100E39E16 /* AppDelegate.m in Sources */, 245 | D3C128941A8BC53100E39E16 /* main.m in Sources */, 246 | ); 247 | runOnlyForDeploymentPostprocessing = 0; 248 | }; 249 | /* End PBXSourcesBuildPhase section */ 250 | 251 | /* Begin PBXVariantGroup section */ 252 | D3C1289B1A8BC53100E39E16 /* Main.storyboard */ = { 253 | isa = PBXVariantGroup; 254 | children = ( 255 | D3C1289C1A8BC53100E39E16 /* Base */, 256 | ); 257 | name = Main.storyboard; 258 | sourceTree = ""; 259 | }; 260 | D3C128A01A8BC53100E39E16 /* LaunchScreen.xib */ = { 261 | isa = PBXVariantGroup; 262 | children = ( 263 | D3C128A11A8BC53100E39E16 /* Base */, 264 | ); 265 | name = LaunchScreen.xib; 266 | sourceTree = ""; 267 | }; 268 | /* End PBXVariantGroup section */ 269 | 270 | /* Begin XCBuildConfiguration section */ 271 | D3C128AF1A8BC53100E39E16 /* Debug */ = { 272 | isa = XCBuildConfiguration; 273 | buildSettings = { 274 | ALWAYS_SEARCH_USER_PATHS = NO; 275 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 276 | CLANG_CXX_LIBRARY = "libc++"; 277 | CLANG_ENABLE_MODULES = YES; 278 | CLANG_ENABLE_OBJC_ARC = YES; 279 | CLANG_WARN_BOOL_CONVERSION = YES; 280 | CLANG_WARN_CONSTANT_CONVERSION = YES; 281 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 282 | CLANG_WARN_EMPTY_BODY = YES; 283 | CLANG_WARN_ENUM_CONVERSION = YES; 284 | CLANG_WARN_INT_CONVERSION = YES; 285 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 286 | CLANG_WARN_UNREACHABLE_CODE = YES; 287 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 288 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 289 | COPY_PHASE_STRIP = NO; 290 | ENABLE_STRICT_OBJC_MSGSEND = YES; 291 | GCC_C_LANGUAGE_STANDARD = gnu99; 292 | GCC_DYNAMIC_NO_PIC = NO; 293 | GCC_OPTIMIZATION_LEVEL = 0; 294 | GCC_PREPROCESSOR_DEFINITIONS = ( 295 | "DEBUG=1", 296 | "$(inherited)", 297 | ); 298 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 299 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 300 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 301 | GCC_WARN_UNDECLARED_SELECTOR = YES; 302 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 303 | GCC_WARN_UNUSED_FUNCTION = YES; 304 | GCC_WARN_UNUSED_VARIABLE = YES; 305 | HEADER_SEARCH_PATHS = "$(SRCROOT)/**"; 306 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 307 | MTL_ENABLE_DEBUG_INFO = YES; 308 | ONLY_ACTIVE_ARCH = YES; 309 | SDKROOT = iphoneos; 310 | TARGETED_DEVICE_FAMILY = "1,2"; 311 | }; 312 | name = Debug; 313 | }; 314 | D3C128B01A8BC53100E39E16 /* Release */ = { 315 | isa = XCBuildConfiguration; 316 | buildSettings = { 317 | ALWAYS_SEARCH_USER_PATHS = NO; 318 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 319 | CLANG_CXX_LIBRARY = "libc++"; 320 | CLANG_ENABLE_MODULES = YES; 321 | CLANG_ENABLE_OBJC_ARC = YES; 322 | CLANG_WARN_BOOL_CONVERSION = YES; 323 | CLANG_WARN_CONSTANT_CONVERSION = YES; 324 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 325 | CLANG_WARN_EMPTY_BODY = YES; 326 | CLANG_WARN_ENUM_CONVERSION = YES; 327 | CLANG_WARN_INT_CONVERSION = YES; 328 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 329 | CLANG_WARN_UNREACHABLE_CODE = YES; 330 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 331 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 332 | COPY_PHASE_STRIP = YES; 333 | ENABLE_NS_ASSERTIONS = NO; 334 | ENABLE_STRICT_OBJC_MSGSEND = YES; 335 | GCC_C_LANGUAGE_STANDARD = gnu99; 336 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 337 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 338 | GCC_WARN_UNDECLARED_SELECTOR = YES; 339 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 340 | GCC_WARN_UNUSED_FUNCTION = YES; 341 | GCC_WARN_UNUSED_VARIABLE = YES; 342 | HEADER_SEARCH_PATHS = "$(SRCROOT)/**"; 343 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 344 | MTL_ENABLE_DEBUG_INFO = NO; 345 | SDKROOT = iphoneos; 346 | TARGETED_DEVICE_FAMILY = "1,2"; 347 | VALIDATE_PRODUCT = YES; 348 | }; 349 | name = Release; 350 | }; 351 | D3C128B21A8BC53100E39E16 /* Debug */ = { 352 | isa = XCBuildConfiguration; 353 | baseConfigurationReference = CEB1AD95D5305E3A92879613 /* Pods-O365-iOS-Connect.debug.xcconfig */; 354 | buildSettings = { 355 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 356 | INFOPLIST_FILE = "O365-iOS-Connect/Info.plist"; 357 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 358 | PRODUCT_NAME = "$(TARGET_NAME)"; 359 | TARGETED_DEVICE_FAMILY = 1; 360 | }; 361 | name = Debug; 362 | }; 363 | D3C128B31A8BC53100E39E16 /* Release */ = { 364 | isa = XCBuildConfiguration; 365 | baseConfigurationReference = 9D43D0D2E863787BAD49C689 /* Pods-O365-iOS-Connect.release.xcconfig */; 366 | buildSettings = { 367 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 368 | INFOPLIST_FILE = "O365-iOS-Connect/Info.plist"; 369 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 370 | PRODUCT_NAME = "$(TARGET_NAME)"; 371 | TARGETED_DEVICE_FAMILY = 1; 372 | }; 373 | name = Release; 374 | }; 375 | /* End XCBuildConfiguration section */ 376 | 377 | /* Begin XCConfigurationList section */ 378 | D3C128891A8BC53100E39E16 /* Build configuration list for PBXProject "O365-iOS-Connect" */ = { 379 | isa = XCConfigurationList; 380 | buildConfigurations = ( 381 | D3C128AF1A8BC53100E39E16 /* Debug */, 382 | D3C128B01A8BC53100E39E16 /* Release */, 383 | ); 384 | defaultConfigurationIsVisible = 0; 385 | defaultConfigurationName = Release; 386 | }; 387 | D3C128B11A8BC53100E39E16 /* Build configuration list for PBXNativeTarget "O365-iOS-Connect" */ = { 388 | isa = XCConfigurationList; 389 | buildConfigurations = ( 390 | D3C128B21A8BC53100E39E16 /* Debug */, 391 | D3C128B31A8BC53100E39E16 /* Release */, 392 | ); 393 | defaultConfigurationIsVisible = 0; 394 | defaultConfigurationName = Release; 395 | }; 396 | /* End XCConfigurationList section */ 397 | }; 398 | rootObject = D3C128861A8BC53100E39E16 /* Project object */; 399 | } 400 | -------------------------------------------------------------------------------- /objective-c/O365-iOS-Connect.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /objective-c/O365-iOS-Connect.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /objective-c/O365-iOS-Connect/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 3 | */ 4 | 5 | #import 6 | 7 | @interface AppDelegate : UIResponder 8 | 9 | @property (strong, nonatomic) UIWindow *window; 10 | 11 | @end 12 | 13 | // ********************************************************* 14 | // 15 | // O365-iOS-Connect, https://github.com/OfficeDev/O365-iOS-Connect 16 | // 17 | // Copyright (c) Microsoft Corporation 18 | // All rights reserved. 19 | // 20 | // MIT License: 21 | // Permission is hereby granted, free of charge, to any person obtaining 22 | // a copy of this software and associated documentation files (the 23 | // "Software"), to deal in the Software without restriction, including 24 | // without limitation the rights to use, copy, modify, merge, publish, 25 | // distribute, sublicense, and/or sell copies of the Software, and to 26 | // permit persons to whom the Software is furnished to do so, subject to 27 | // the following conditions: 28 | // 29 | // The above copyright notice and this permission notice shall be 30 | // included in all copies or substantial portions of the Software. 31 | // 32 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 33 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 34 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 35 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 36 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 37 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 38 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 39 | // 40 | // ********************************************************* 41 | -------------------------------------------------------------------------------- /objective-c/O365-iOS-Connect/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 3 | */ 4 | 5 | #import "AppDelegate.h" 6 | 7 | @interface AppDelegate () 8 | 9 | @end 10 | 11 | @implementation AppDelegate 12 | 13 | 14 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 15 | 16 | return YES; 17 | } 18 | 19 | - (void)applicationWillResignActive:(UIApplication *)application { 20 | // 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. 21 | // 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. 22 | } 23 | 24 | - (void)applicationDidEnterBackground:(UIApplication *)application { 25 | // 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. 26 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 27 | } 28 | 29 | - (void)applicationWillEnterForeground:(UIApplication *)application { 30 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 31 | } 32 | 33 | - (void)applicationDidBecomeActive:(UIApplication *)application { 34 | // 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. 35 | } 36 | 37 | - (void)applicationWillTerminate:(UIApplication *)application { 38 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 39 | } 40 | 41 | @end 42 | 43 | // ********************************************************* 44 | // 45 | // O365-iOS-Connect, https://github.com/OfficeDev/O365-iOS-Connect 46 | // 47 | // Copyright (c) Microsoft Corporation 48 | // All rights reserved. 49 | // 50 | // MIT License: 51 | // Permission is hereby granted, free of charge, to any person obtaining 52 | // a copy of this software and associated documentation files (the 53 | // "Software"), to deal in the Software without restriction, including 54 | // without limitation the rights to use, copy, modify, merge, publish, 55 | // distribute, sublicense, and/or sell copies of the Software, and to 56 | // permit persons to whom the Software is furnished to do so, subject to 57 | // the following conditions: 58 | // 59 | // The above copyright notice and this permission notice shall be 60 | // included in all copies or substantial portions of the Software. 61 | // 62 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 63 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 64 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 65 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 66 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 67 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 68 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 69 | // 70 | // ********************************************************* 71 | -------------------------------------------------------------------------------- /objective-c/O365-iOS-Connect/AuthenticationManager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 3 | */ 4 | 5 | #import 6 | #import 7 | #import 8 | #import 9 | #import 10 | #import 11 | 12 | @interface AuthenticationManager : NSObject 13 | 14 | @property (readonly, nonatomic) ADALDependencyResolver *dependencyResolver; 15 | 16 | // Singleton authentication manager. 17 | + (AuthenticationManager *)sharedInstance; 18 | 19 | // Call to get an access token. 20 | - (void)acquireAuthTokenWithResourceId:(NSString *)resourceId 21 | completionHandler:(void (^)(BOOL authenticated))completionBlock; 22 | 23 | // Clears the ADAL token cache and the cookie cache. 24 | - (void)clearCredentials; 25 | 26 | @end 27 | // ********************************************************* 28 | // 29 | // O365-iOS-Connect, https://github.com/OfficeDev/O365-iOS-Connect 30 | // 31 | // Copyright (c) Microsoft Corporation 32 | // All rights reserved. 33 | // 34 | // MIT License: 35 | // Permission is hereby granted, free of charge, to any person obtaining 36 | // a copy of this software and associated documentation files (the 37 | // "Software"), to deal in the Software without restriction, including 38 | // without limitation the rights to use, copy, modify, merge, publish, 39 | // distribute, sublicense, and/or sell copies of the Software, and to 40 | // permit persons to whom the Software is furnished to do so, subject to 41 | // the following conditions: 42 | // 43 | // The above copyright notice and this permission notice shall be 44 | // included in all copies or substantial portions of the Software. 45 | // 46 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 47 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 48 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 49 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 50 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 51 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 52 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 53 | // 54 | // ********************************************************* -------------------------------------------------------------------------------- /objective-c/O365-iOS-Connect/AuthenticationManager.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 3 | */ 4 | 5 | #import "AuthenticationManager.h" 6 | 7 | // You will set your application's clientId and redirect URI. You get 8 | // these when you register your application in Azure AD. 9 | static NSString * const REDIRECT_URL_STRING = @"ENTER_REDIRECT_URI_HERE"; 10 | static NSString * const CLIENT_ID = @"ENTER_CLIENT_ID_HERE"; 11 | static NSString * const AUTHORITY = @"https://login.microsoftonline.com/common"; 12 | 13 | @interface AuthenticationManager () 14 | 15 | @property (strong, nonatomic) ADAuthenticationContext *authContext; 16 | @property (readwrite, nonatomic) ADALDependencyResolver *dependencyResolver; 17 | 18 | @property (readonly, nonatomic) NSURL *redirectURL; 19 | @property (readonly, nonatomic) NSString *authority; 20 | @property (readonly, nonatomic) NSString *clientId; 21 | 22 | @end 23 | 24 | @implementation AuthenticationManager 25 | 26 | - (instancetype)init 27 | { 28 | self = [super init]; 29 | 30 | if (self) { 31 | // These are settings that you need to set based on your 32 | // client registration in Azure AD. 33 | _redirectURL = [NSURL URLWithString:REDIRECT_URL_STRING]; 34 | _authority = AUTHORITY; 35 | _clientId = CLIENT_ID; 36 | } 37 | 38 | return self; 39 | } 40 | 41 | // Use a single authentication manager for the application. 42 | + (AuthenticationManager *)sharedInstance 43 | { 44 | static AuthenticationManager *sharedInstance; 45 | static dispatch_once_t onceToken; 46 | 47 | // Initialize the AuthenticationManager only once. 48 | dispatch_once(&onceToken, ^{ 49 | sharedInstance = [[AuthenticationManager alloc] init]; 50 | }); 51 | 52 | return sharedInstance; 53 | } 54 | 55 | // Acquire access and refresh tokens from Azure AD for the user 56 | - (void)acquireAuthTokenWithResourceId:(NSString *)resourceId 57 | completionHandler:(void (^)(BOOL authenticated))completionBlock 58 | { 59 | ADAuthenticationError *error; 60 | self.authContext = [ADAuthenticationContext authenticationContextWithAuthority:self.authority 61 | error:&error]; 62 | 63 | // The first time this application is run, the [ADAuthenticationContext acquireTokenWithResource] 64 | // manager will send a request to the AUTHORITY (see the const at the top of this file) which 65 | // will redirect you to a login page. You will provide your credentials and the response will 66 | // contain your refresh and access tokens. The second time this application is run, and assuming 67 | // you didn't clear your token cache, the authentication manager will use the access or refresh 68 | // token in the cache to authenticate client requests. 69 | // This will result in a call to the service if you need to get an access token. 70 | [self.authContext acquireTokenWithResource:resourceId 71 | clientId:self.clientId 72 | redirectUri:self.redirectURL 73 | completionBlock:^(ADAuthenticationResult *result) { 74 | if (AD_SUCCEEDED != result.status) { 75 | completionBlock(NO); 76 | } 77 | else { 78 | 79 | // Saving the logged in user's userId. 80 | NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 81 | [userDefaults setObject:result.tokenCacheStoreItem.userInformation.userId 82 | forKey:@"LogInUser"]; 83 | [userDefaults synchronize]; 84 | 85 | // Setting the dependency resolver on the authentication manager. 86 | self.dependencyResolver = [[ADALDependencyResolver alloc] initWithContext:self.authContext 87 | resourceId:resourceId 88 | clientId:self.clientId 89 | redirectUri:self.redirectURL]; 90 | completionBlock(YES); 91 | } 92 | }]; 93 | 94 | } 95 | 96 | // Clear the ADAL token cache and remove this application's cookies. 97 | -(void)clearCredentials{ 98 | id cache = [ADAuthenticationSettings sharedInstance].defaultTokenCacheStore; 99 | ADAuthenticationError *error; 100 | 101 | // Clear the token cache. 102 | if ([[cache allItemsWithError:&error] count] > 0) 103 | [cache removeAllWithError:&error]; 104 | 105 | // Remove all the cookies from this application's sandbox. The authorization code is stored in the 106 | // cookies and ADAL will try to get to access tokens based on auth code in the cookie. 107 | NSHTTPCookieStorage *cookieStore = [NSHTTPCookieStorage sharedHTTPCookieStorage]; 108 | for (NSHTTPCookie *cookie in cookieStore.cookies) { 109 | [cookieStore deleteCookie:cookie]; 110 | } 111 | } 112 | 113 | @end 114 | // ********************************************************* 115 | // 116 | // O365-iOS-Connect, https://github.com/OfficeDev/O365-iOS-Connect 117 | // 118 | // Copyright (c) Microsoft Corporation 119 | // All rights reserved. 120 | // 121 | // MIT License: 122 | // Permission is hereby granted, free of charge, to any person obtaining 123 | // a copy of this software and associated documentation files (the 124 | // "Software"), to deal in the Software without restriction, including 125 | // without limitation the rights to use, copy, modify, merge, publish, 126 | // distribute, sublicense, and/or sell copies of the Software, and to 127 | // permit persons to whom the Software is furnished to do so, subject to 128 | // the following conditions: 129 | // 130 | // The above copyright notice and this permission notice shall be 131 | // included in all copies or substantial portions of the Software. 132 | // 133 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 134 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 135 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 136 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 137 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 138 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 139 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 140 | // 141 | // ********************************************************* -------------------------------------------------------------------------------- /objective-c/O365-iOS-Connect/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /objective-c/O365-iOS-Connect/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 60 | 61 | 62 | 63 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 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 | -------------------------------------------------------------------------------- /objective-c/O365-iOS-Connect/EmailBody.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Congratulations!

5 |

You just sent this email from the Office 365 Connect sample. How cool is that? You are well on your way to incorporating Office 365 services in your apps.

6 |

Give us feedback

7 |

We hope you found this sample useful. We would love to hear from you, so drop us an email at 8 | docthis@microsoft.com with your comments or 9 | log an issue in our GitHub repository.

10 |

For more details on what else you can do with the Office 365 services in your iOS app, start with the 11 | Getting started with iOS page on dev.office.com.

12 |

Thanks, and happy coding!

13 |

Your Office 365 Development team

14 |
15 | 16 | 17 | 21 | 25 | 26 |
18 | See on GitHub 19 | 20 | 22 | Suggest on UserVoice 23 | 24 |
27 |
28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /objective-c/O365-iOS-Connect/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /objective-c/O365-iOS-Connect/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.microsoft.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationPortrait 41 | UIInterfaceOrientationPortraitUpsideDown 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | NSAppTransportSecurity 45 | 46 | NSExceptionDomains 47 | 48 | outlook.office365.com 49 | 50 | NSIncludeSubmdomains 51 | 52 | NSExceptionRequiresForwardSecrecy 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /objective-c/O365-iOS-Connect/Office365ClientFetcher.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 3 | */ 4 | 5 | #import 6 | #import 7 | #import 8 | #import "MSDiscoveryClient.h" 9 | #import 10 | 11 | // Provides the client objects for making requests against the service. 12 | @interface Office365ClientFetcher : NSObject 13 | 14 | - (void)fetchOutlookClient:(void (^)(MSOutlookClient *outlookClient))callback; 15 | - (void)fetchDiscoveryClient:(void (^)(MSDiscoveryClient *discoveryClient))callback; 16 | 17 | @end 18 | // ********************************************************* 19 | // 20 | // O365-iOS-Connect, https://github.com/OfficeDev/O365-iOS-Connect 21 | // 22 | // Copyright (c) Microsoft Corporation 23 | // All rights reserved. 24 | // 25 | // MIT License: 26 | // Permission is hereby granted, free of charge, to any person obtaining 27 | // a copy of this software and associated documentation files (the 28 | // "Software"), to deal in the Software without restriction, including 29 | // without limitation the rights to use, copy, modify, merge, publish, 30 | // distribute, sublicense, and/or sell copies of the Software, and to 31 | // permit persons to whom the Software is furnished to do so, subject to 32 | // the following conditions: 33 | // 34 | // The above copyright notice and this permission notice shall be 35 | // included in all copies or substantial portions of the Software. 36 | // 37 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 38 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 39 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 40 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 41 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 42 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 43 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 44 | // 45 | // ********************************************************* -------------------------------------------------------------------------------- /objective-c/O365-iOS-Connect/Office365ClientFetcher.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 3 | */ 4 | 5 | #import "Office365ClientFetcher.h" 6 | #import "AuthenticationManager.h" 7 | 8 | @implementation Office365ClientFetcher 9 | 10 | // Gets the Outlook Services client. This will authenticate a user with the service 11 | // and get the application an access and refresh token to act on behalf of the user. 12 | // The access and refresh token will be cached. The next time a user attempts 13 | // to access the service, the access token will be used. If the access token 14 | // has expired, the client will use the refresh token to get a new access token. 15 | // If the refresh token has expired, then ADAL will get the authorization code 16 | // from the cookie cache and use that to get a new access and refresh token. 17 | - (void)fetchOutlookClient:(void (^)(MSOutlookClient *outlookClient))callback 18 | { 19 | // Get an instance of the authentication controller. 20 | AuthenticationManager *authenticationManager = [AuthenticationManager sharedInstance]; 21 | 22 | // The first time this application is run, the authentication manager will send a request 23 | // to the authority which will redirect you to a login page. You will provide your credentials 24 | // and the response will contain your refresh and access tokens. The second time this 25 | // application is run, and assuming you didn't clear your token cache, the authentication 26 | // manager will use the access or refresh token in the cache to authenticate client requests. 27 | // This will result in a call to the service if you need to get an access token. 28 | [authenticationManager acquireAuthTokenWithResourceId:@"https://outlook.office365.com/" 29 | completionHandler:^(BOOL authenticated) { 30 | 31 | if(authenticated){ 32 | NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 33 | 34 | NSDictionary *serviceEndpoints = [userDefaults objectForKey:@"O365ServiceEndpoints"]; 35 | 36 | // Gets the MSOutlookClient with the URL for the Mail service. 37 | callback([[MSOutlookClient alloc] initWithUrl:serviceEndpoints[@"Mail"] 38 | dependencyResolver:authenticationManager.dependencyResolver]); 39 | 40 | } 41 | else{ 42 | //Display an alert in case of an error 43 | dispatch_async(dispatch_get_main_queue(), ^{ 44 | NSLog(@"Error in the authentication"); 45 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" 46 | message:@"Authentication failed. Check the log for errors." 47 | delegate:self 48 | cancelButtonTitle:@"OK" 49 | otherButtonTitles:nil]; 50 | [alert show]; 51 | 52 | }); 53 | } 54 | }]; 55 | } 56 | 57 | 58 | //Gets the DiscoveryClient which is used to discover the service endpoints 59 | - (void)fetchDiscoveryClient:(void (^)(MSDiscoveryClient *discoveryClient))callback 60 | { 61 | 62 | AuthenticationManager *authenticationManager = [AuthenticationManager sharedInstance]; 63 | 64 | // The first time this application is run, the authentication manager will send a request 65 | // to the authority which will redirect you to a login page. You will provide your credentials 66 | // and the response will contain your refresh and access tokens. The second time this 67 | // application is run, and assuming you didn't clear your token cache, the authentication 68 | // manager will use the access or refresh token in the cache to authenticate client requests. 69 | // This will result in a call to the service if you need to get an access token. 70 | [authenticationManager acquireAuthTokenWithResourceId:@"https://api.office.com/discovery/" 71 | completionHandler:^(BOOL authenticated) { 72 | if (authenticated) { 73 | callback([[MSDiscoveryClient alloc] initWithUrl:@"https://api.office.com/discovery/v1.0/me/" 74 | dependencyResolver:authenticationManager.dependencyResolver]); 75 | 76 | } 77 | else { 78 | dispatch_async(dispatch_get_main_queue(), ^{ 79 | NSLog(@"Error in the authentication"); 80 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" 81 | message:@"Authentication failed. This may be because the Internet connection is offline or perhaps the credentials are incorrect. Check the log for errors and try again." 82 | delegate:self 83 | cancelButtonTitle:@"OK" 84 | otherButtonTitles:nil]; 85 | [alert show]; 86 | 87 | }); 88 | } 89 | }]; 90 | } 91 | 92 | @end 93 | // ********************************************************* 94 | // 95 | // O365-iOS-Connect, https://github.com/OfficeDev/O365-iOS-Connect 96 | // 97 | // Copyright (c) Microsoft Corporation 98 | // All rights reserved. 99 | // 100 | // MIT License: 101 | // Permission is hereby granted, free of charge, to any person obtaining 102 | // a copy of this software and associated documentation files (the 103 | // "Software"), to deal in the Software without restriction, including 104 | // without limitation the rights to use, copy, modify, merge, publish, 105 | // distribute, sublicense, and/or sell copies of the Software, and to 106 | // permit persons to whom the Software is furnished to do so, subject to 107 | // the following conditions: 108 | // 109 | // The above copyright notice and this permission notice shall be 110 | // included in all copies or substantial portions of the Software. 111 | // 112 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 113 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 114 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 115 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 116 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 117 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 118 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 119 | // 120 | // ********************************************************* -------------------------------------------------------------------------------- /objective-c/O365-iOS-Connect/SendMailViewController.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 3 | */ 4 | 5 | #import 6 | 7 | @interface SendMailViewController : UIViewController 8 | 9 | @end 10 | 11 | // ********************************************************* 12 | // 13 | // O365-iOS-Connect, https://github.com/OfficeDev/O365-iOS-Connect 14 | // 15 | // Copyright (c) Microsoft Corporation 16 | // All rights reserved. 17 | // 18 | // MIT License: 19 | // Permission is hereby granted, free of charge, to any person obtaining 20 | // a copy of this software and associated documentation files (the 21 | // "Software"), to deal in the Software without restriction, including 22 | // without limitation the rights to use, copy, modify, merge, publish, 23 | // distribute, sublicense, and/or sell copies of the Software, and to 24 | // permit persons to whom the Software is furnished to do so, subject to 25 | // the following conditions: 26 | // 27 | // The above copyright notice and this permission notice shall be 28 | // included in all copies or substantial portions of the Software. 29 | // 30 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 31 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 32 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 33 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 34 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 35 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 36 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 37 | // 38 | // ********************************************************* 39 | -------------------------------------------------------------------------------- /objective-c/O365-iOS-Connect/SendMailViewController.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 3 | */ 4 | 5 | #import "SendMailViewController.h" 6 | #import "Office365ClientFetcher.h" 7 | #import "AuthenticationManager.h" 8 | #import "MSDiscoveryServiceInfoCollectionFetcher.h" 9 | 10 | @interface SendMailViewController () 11 | 12 | @property (weak, nonatomic) IBOutlet UILabel *headerLabel; 13 | @property (weak, nonatomic) IBOutlet UITextView *mainContentTextView; 14 | @property (weak, nonatomic) IBOutlet UITextView *statusTextView; 15 | @property (weak, nonatomic) IBOutlet UITextField *emailTextField; 16 | @property (weak, nonatomic) IBOutlet UIBarButtonItem *disconnectBarButtonItem; 17 | @property (weak, nonatomic) IBOutlet UIButton *sendMailButton; 18 | @property (weak, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator; 19 | 20 | @property (strong, nonatomic) Office365ClientFetcher *baseController; 21 | @property (strong, nonatomic) NSMutableDictionary *serviceEndpointLookup; 22 | 23 | - (IBAction)sendMailTapped:(id)sender; 24 | - (IBAction)disconnectTapped:(id)sender; 25 | 26 | @end 27 | 28 | 29 | @implementation SendMailViewController 30 | 31 | #pragma mark - Properties 32 | - (Office365ClientFetcher *)baseController 33 | { 34 | if (!_baseController) { 35 | _baseController = [[Office365ClientFetcher alloc] init]; 36 | } 37 | 38 | return _baseController; 39 | } 40 | 41 | #pragma mark - Lifecycle Methods 42 | - (void)viewDidLoad 43 | { 44 | [super viewDidLoad]; 45 | 46 | self.disconnectBarButtonItem.enabled = NO; 47 | self.sendMailButton.hidden = YES; 48 | self.emailTextField.hidden = YES; 49 | self.mainContentTextView.hidden = YES; 50 | self.headerLabel.hidden = YES; 51 | 52 | [self connectToOffice365]; 53 | } 54 | 55 | #pragma mark - IBActions 56 | //Send a mail message when the Send button is clicked 57 | - (IBAction)sendMailTapped:(id)sender 58 | { 59 | [self sendMailMessage]; 60 | } 61 | 62 | // Clear the token cache and update the UI when the Disconnect button is tapped 63 | - (IBAction)disconnectTapped:(id)sender 64 | { 65 | self.disconnectBarButtonItem.enabled = NO; 66 | self.sendMailButton.hidden = YES; 67 | self.mainContentTextView.text = @"You're no longer connected to Office 365."; 68 | self.headerLabel.hidden = YES; 69 | self.emailTextField.hidden = YES; 70 | self.statusTextView.hidden = YES; 71 | 72 | // Clear the access and refresh tokens from the credential cache. You need to clear cookies 73 | // since ADAL uses information stored in the cookies to get a new access token. 74 | AuthenticationManager *authenticationManager = [AuthenticationManager sharedInstance]; 75 | [authenticationManager clearCredentials]; 76 | } 77 | 78 | #pragma mark - Helper Methods 79 | - (void)connectToOffice365 80 | { 81 | // Connect to the service by discovering the service endpoints and authorizing 82 | // the application to access the user's email. This will store the user's 83 | // service URLs in a property list to be accessed when calls are made to the 84 | // service. This results in two calls: one to authenticate, and one to get the 85 | // URLs. ADAL will cache the access and refresh tokens so you won't need to 86 | // provide credentials unless you sign out. 87 | 88 | // Get the discovery client. First time this is ran you will be prompted 89 | // to provide your credentials which will authenticate you with the service. 90 | // The application will get an access token in the response. 91 | [self.baseController fetchDiscoveryClient:^(MSDiscoveryClient *discoveryClient) { 92 | MSDiscoveryServiceInfoCollectionFetcher *servicesInfoFetcher = [discoveryClient getservices]; 93 | 94 | // Call the Discovery Service and get back an array of service endpoint information 95 | NSURLSessionTask *servicesTask = [servicesInfoFetcher readWithCallback:^(NSArray *serviceEndpoints, MSODataException *error) { 96 | if (serviceEndpoints) { 97 | 98 | // Here is where we cache the service URLs returned by the Discovery Service. You may not 99 | // need to call the Discovery Service again until either this cache is removed, or you 100 | // get an error that indicates that the endpoint is no longer valid. 101 | self.serviceEndpointLookup = [[NSMutableDictionary alloc] init]; 102 | 103 | for(MSDiscoveryServiceInfo *serviceEndpoint in serviceEndpoints) { 104 | self.serviceEndpointLookup[serviceEndpoint.capability] = serviceEndpoint.serviceEndpointUri; 105 | } 106 | 107 | // Keep track of the service endpoints in the user defaults 108 | NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 109 | 110 | [userDefaults setObject:self.serviceEndpointLookup 111 | forKey:@"O365ServiceEndpoints"]; 112 | 113 | [userDefaults synchronize]; 114 | 115 | dispatch_async(dispatch_get_main_queue(), ^{ 116 | 117 | NSString *userEmail = [userDefaults stringForKey:@"LogInUser"]; 118 | NSArray *parts = [userEmail componentsSeparatedByString: @"@"]; 119 | 120 | self.headerLabel.text = [NSString stringWithFormat:@"Hi %@!", parts[0]]; 121 | self.headerLabel.hidden = NO; 122 | self.mainContentTextView.hidden = NO; 123 | self.emailTextField.text = userEmail; 124 | self.statusTextView.text = @""; 125 | self.disconnectBarButtonItem.enabled = YES; 126 | self.sendMailButton.hidden = NO; 127 | self.emailTextField.hidden = NO; 128 | }); 129 | } 130 | else { 131 | dispatch_async(dispatch_get_main_queue(), ^{ 132 | NSLog(@"Error in the authentication: %@", error); 133 | 134 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" 135 | message:@"Authentication failed. This may be because the Internet connection is offline or perhaps the credentials are incorrect. Check the log for errors and try again." 136 | delegate:nil 137 | cancelButtonTitle:@"OK" 138 | otherButtonTitles:nil]; 139 | [alert show]; 140 | }); 141 | } 142 | }]; 143 | 144 | [servicesTask resume]; 145 | }]; 146 | } 147 | 148 | // This method creates a new mail message and sends it to the specified address 149 | // by using Office 365. 150 | - (void)sendMailMessage 151 | { 152 | MSOutlookMessage *message = [self buildMessage]; 153 | 154 | // Get the MSOutlookClient. A call will be made to Azure AD and you will be prompted for credentials if you don't 155 | // have an access or refresh token in your token cache. 156 | [self.baseController fetchOutlookClient:^(MSOutlookClient *outlookClient) { 157 | dispatch_async(dispatch_get_main_queue(), ^{ 158 | // Show the activity indicator 159 | [self.activityIndicator startAnimating]; 160 | }); 161 | 162 | MSOutlookUserFetcher *userFetcher = [outlookClient getMe]; 163 | MSOutlookUserOperations *userOperations = [userFetcher operations]; 164 | 165 | // Send the mail message. This results in a call to the service. 166 | NSURLSessionTask *task = [userOperations sendMailWithMessage:message 167 | saveToSentItems:YES 168 | callback:^(int returnValue, MSODataException *error) { 169 | NSString *statusText; 170 | 171 | if (error == nil) { 172 | statusText = @"Check your inbox, you have a new message. :)"; 173 | } 174 | else { 175 | statusText = @"The email could not be sent. Check the log for errors."; 176 | NSLog(@"%@",[error localizedDescription]); 177 | } 178 | 179 | // Update the UI. 180 | dispatch_async(dispatch_get_main_queue(), ^{ 181 | self.statusTextView.text = statusText; 182 | [self.activityIndicator stopAnimating]; 183 | }); 184 | }]; 185 | 186 | [task resume]; 187 | }]; 188 | } 189 | 190 | //Compose the mail message 191 | - (MSOutlookMessage *)buildMessage 192 | { 193 | // Create a new message. Set properties on the message. 194 | MSOutlookMessage *message = [[MSOutlookMessage alloc] init]; 195 | message.Subject = @"Welcome to Office 365 development on iOS with the Office 365 Connect sample"; 196 | 197 | // Get the recipient's email address. 198 | // The ToRecipients property is an array of MSOulookRecipient objects. 199 | // See the helper method getRecipients to understand the usage. 200 | NSString *toEmail = self.emailTextField.text; 201 | 202 | MSOutlookRecipient *recipient = [[MSOutlookRecipient alloc] init]; 203 | 204 | recipient.EmailAddress = [[MSOutlookEmailAddress alloc] init]; 205 | recipient.EmailAddress.Address = [toEmail stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 206 | 207 | // The cast here is required to maintain compatibility with the API. 208 | message.ToRecipients = (NSMutableArray *)[[NSMutableArray alloc] initWithObjects:recipient, nil]; 209 | 210 | // Get the email text and put in the email body. 211 | NSString *filePath = [[NSBundle mainBundle] pathForResource:@"EmailBody" ofType:@"html" ]; 212 | NSString *body = [[NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil] 213 | stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; 214 | message.Body = [[MSOutlookItemBody alloc] init]; 215 | message.Body.ContentType = MSOutlook_BodyType_HTML; 216 | message.Body.Content = body; 217 | 218 | return message; 219 | } 220 | 221 | @end 222 | 223 | // ********************************************************* 224 | // 225 | // O365-iOS-Connect, https://github.com/OfficeDev/O365-iOS-Connect 226 | // 227 | // Copyright (c) Microsoft Corporation 228 | // All rights reserved. 229 | // 230 | // MIT License: 231 | // Permission is hereby granted, free of charge, to any person obtaining 232 | // a copy of this software and associated documentation files (the 233 | // "Software"), to deal in the Software without restriction, including 234 | // without limitation the rights to use, copy, modify, merge, publish, 235 | // distribute, sublicense, and/or sell copies of the Software, and to 236 | // permit persons to whom the Software is furnished to do so, subject to 237 | // the following conditions: 238 | // 239 | // The above copyright notice and this permission notice shall be 240 | // included in all copies or substantial portions of the Software. 241 | // 242 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 243 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 244 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 245 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 246 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 247 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 248 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 249 | // 250 | // ********************************************************* 251 | -------------------------------------------------------------------------------- /objective-c/O365-iOS-Connect/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // O365-iOS-Connect 4 | // 5 | // Created by Brendan Mitchell on 2/11/15. 6 | // Copyright (c) 2015 Microsoft. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /objective-c/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | 3 | source 'https://github.com/Cocoapods/Specs.git' 4 | platform :ios, '8.0' 5 | 6 | target 'O365-iOS-Connect' do 7 | 8 | pod 'ADALiOS', '~> 1.2.1' 9 | pod 'Office365/Outlook', '= 0.9.1' 10 | pod 'Office365/Discovery', '= 0.9.1' 11 | 12 | end 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /readme-images/O365-iOS-Connect-video_play_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/O365-iOS-Connect/61dd6b4df35a2f630a2e799a801efde69a031ed9/readme-images/O365-iOS-Connect-video_play_icon.png -------------------------------------------------------------------------------- /swift/O365-iOS-Connect-Swift.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 952E24491B0A92A20089B710 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 952E24481B0A92A20089B710 /* AppDelegate.swift */; }; 11 | 952E244E1B0A92A20089B710 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 952E244C1B0A92A20089B710 /* Main.storyboard */; }; 12 | 952E24501B0A92A20089B710 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 952E244F1B0A92A20089B710 /* Images.xcassets */; }; 13 | 952E24531B0A92A20089B710 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 952E24511B0A92A20089B710 /* LaunchScreen.xib */; }; 14 | 952E24A11B0AA0320089B710 /* SendMailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 952E24A01B0AA0320089B710 /* SendMailViewController.swift */; }; 15 | 952E24A31B0AA0880089B710 /* AuthenticationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 952E24A21B0AA0880089B710 /* AuthenticationManager.swift */; }; 16 | 952E24A51B0AA0A50089B710 /* O365ClientFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 952E24A41B0AA0A50089B710 /* O365ClientFetcher.swift */; }; 17 | 95D883CB1B1381A300DD851C /* EmailBody.html in Resources */ = {isa = PBXBuildFile; fileRef = 95D883CA1B1381A300DD851C /* EmailBody.html */; }; 18 | AE015CAC727BB639E0379994 /* libPods-O365-iOS-Connect-Swift.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 90B85D21B25C884AA99B0BD0 /* libPods-O365-iOS-Connect-Swift.a */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXFileReference section */ 22 | 6DF25871C499CDFDE0C5106B /* Pods-O365-iOS-Connect-Swift.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-O365-iOS-Connect-Swift.release.xcconfig"; path = "Pods/Target Support Files/Pods-O365-iOS-Connect-Swift/Pods-O365-iOS-Connect-Swift.release.xcconfig"; sourceTree = ""; }; 23 | 7307BBA639980E95CC67B04B /* Pods-O365-iOS-Connect-Swift.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-O365-iOS-Connect-Swift.debug.xcconfig"; path = "Pods/Target Support Files/Pods-O365-iOS-Connect-Swift/Pods-O365-iOS-Connect-Swift.debug.xcconfig"; sourceTree = ""; }; 24 | 90B85D21B25C884AA99B0BD0 /* libPods-O365-iOS-Connect-Swift.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-O365-iOS-Connect-Swift.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 25 | 952C94041B0AA450002D38A0 /* O365-Connect-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "O365-Connect-Bridging-Header.h"; sourceTree = ""; }; 26 | 952E24431B0A92A20089B710 /* O365-iOS-Connect-Swift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "O365-iOS-Connect-Swift.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | 952E24471B0A92A20089B710 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 28 | 952E24481B0A92A20089B710 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 29 | 952E244D1B0A92A20089B710 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 30 | 952E244F1B0A92A20089B710 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 31 | 952E24521B0A92A20089B710 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 32 | 952E24A01B0AA0320089B710 /* SendMailViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendMailViewController.swift; sourceTree = ""; }; 33 | 952E24A21B0AA0880089B710 /* AuthenticationManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthenticationManager.swift; sourceTree = ""; }; 34 | 952E24A41B0AA0A50089B710 /* O365ClientFetcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = O365ClientFetcher.swift; sourceTree = ""; }; 35 | 95D883CA1B1381A300DD851C /* EmailBody.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = EmailBody.html; sourceTree = ""; }; 36 | /* End PBXFileReference section */ 37 | 38 | /* Begin PBXFrameworksBuildPhase section */ 39 | 952E24401B0A92A20089B710 /* Frameworks */ = { 40 | isa = PBXFrameworksBuildPhase; 41 | buildActionMask = 2147483647; 42 | files = ( 43 | AE015CAC727BB639E0379994 /* libPods-O365-iOS-Connect-Swift.a in Frameworks */, 44 | ); 45 | runOnlyForDeploymentPostprocessing = 0; 46 | }; 47 | /* End PBXFrameworksBuildPhase section */ 48 | 49 | /* Begin PBXGroup section */ 50 | 1260717DB072B61D024DBCA4 /* Pods */ = { 51 | isa = PBXGroup; 52 | children = ( 53 | 7307BBA639980E95CC67B04B /* Pods-O365-iOS-Connect-Swift.debug.xcconfig */, 54 | 6DF25871C499CDFDE0C5106B /* Pods-O365-iOS-Connect-Swift.release.xcconfig */, 55 | ); 56 | name = Pods; 57 | sourceTree = ""; 58 | }; 59 | 912D0AA4C701F2A61AB91D1B /* Frameworks */ = { 60 | isa = PBXGroup; 61 | children = ( 62 | 90B85D21B25C884AA99B0BD0 /* libPods-O365-iOS-Connect-Swift.a */, 63 | ); 64 | name = Frameworks; 65 | sourceTree = ""; 66 | }; 67 | 952E243A1B0A92A20089B710 = { 68 | isa = PBXGroup; 69 | children = ( 70 | 952E24451B0A92A20089B710 /* O365-iOS-Connect-Swift */, 71 | 952E24441B0A92A20089B710 /* Products */, 72 | 1260717DB072B61D024DBCA4 /* Pods */, 73 | 912D0AA4C701F2A61AB91D1B /* Frameworks */, 74 | ); 75 | sourceTree = ""; 76 | }; 77 | 952E24441B0A92A20089B710 /* Products */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | 952E24431B0A92A20089B710 /* O365-iOS-Connect-Swift.app */, 81 | ); 82 | name = Products; 83 | sourceTree = ""; 84 | }; 85 | 952E24451B0A92A20089B710 /* O365-iOS-Connect-Swift */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | 952E24481B0A92A20089B710 /* AppDelegate.swift */, 89 | 952E24A21B0AA0880089B710 /* AuthenticationManager.swift */, 90 | 952E24A41B0AA0A50089B710 /* O365ClientFetcher.swift */, 91 | 952E24A01B0AA0320089B710 /* SendMailViewController.swift */, 92 | 9AAD25101B1757F9009A6936 /* Resources */, 93 | 952E24461B0A92A20089B710 /* Supporting Files */, 94 | ); 95 | path = "O365-iOS-Connect-Swift"; 96 | sourceTree = ""; 97 | }; 98 | 952E24461B0A92A20089B710 /* Supporting Files */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 952E24471B0A92A20089B710 /* Info.plist */, 102 | 952C94041B0AA450002D38A0 /* O365-Connect-Bridging-Header.h */, 103 | ); 104 | name = "Supporting Files"; 105 | sourceTree = ""; 106 | }; 107 | 9AAD25101B1757F9009A6936 /* Resources */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 95D883CA1B1381A300DD851C /* EmailBody.html */, 111 | 952E244C1B0A92A20089B710 /* Main.storyboard */, 112 | 952E244F1B0A92A20089B710 /* Images.xcassets */, 113 | 952E24511B0A92A20089B710 /* LaunchScreen.xib */, 114 | ); 115 | name = Resources; 116 | sourceTree = ""; 117 | }; 118 | /* End PBXGroup section */ 119 | 120 | /* Begin PBXNativeTarget section */ 121 | 952E24421B0A92A20089B710 /* O365-iOS-Connect-Swift */ = { 122 | isa = PBXNativeTarget; 123 | buildConfigurationList = 952E24621B0A92A20089B710 /* Build configuration list for PBXNativeTarget "O365-iOS-Connect-Swift" */; 124 | buildPhases = ( 125 | E6C7BF6C474C6C3FE9BF7FBF /* Check Pods Manifest.lock */, 126 | 952E243F1B0A92A20089B710 /* Sources */, 127 | 952E24401B0A92A20089B710 /* Frameworks */, 128 | 952E24411B0A92A20089B710 /* Resources */, 129 | 0C65CE7BDBAA9DBBA54CBB49 /* Copy Pods Resources */, 130 | FA7ABFDD6EE5EB5CAA9D86FB /* Embed Pods Frameworks */, 131 | ); 132 | buildRules = ( 133 | ); 134 | dependencies = ( 135 | ); 136 | name = "O365-iOS-Connect-Swift"; 137 | productName = "O365-iOS-Connect-Swift"; 138 | productReference = 952E24431B0A92A20089B710 /* O365-iOS-Connect-Swift.app */; 139 | productType = "com.apple.product-type.application"; 140 | }; 141 | /* End PBXNativeTarget section */ 142 | 143 | /* Begin PBXProject section */ 144 | 952E243B1B0A92A20089B710 /* Project object */ = { 145 | isa = PBXProject; 146 | attributes = { 147 | LastSwiftMigration = 0700; 148 | LastSwiftUpdateCheck = 0700; 149 | LastUpgradeCheck = 0700; 150 | ORGANIZATIONNAME = Microsoft; 151 | TargetAttributes = { 152 | 952E24421B0A92A20089B710 = { 153 | CreatedOnToolsVersion = 6.3.1; 154 | }; 155 | }; 156 | }; 157 | buildConfigurationList = 952E243E1B0A92A20089B710 /* Build configuration list for PBXProject "O365-iOS-Connect-Swift" */; 158 | compatibilityVersion = "Xcode 3.2"; 159 | developmentRegion = English; 160 | hasScannedForEncodings = 0; 161 | knownRegions = ( 162 | en, 163 | Base, 164 | ); 165 | mainGroup = 952E243A1B0A92A20089B710; 166 | productRefGroup = 952E24441B0A92A20089B710 /* Products */; 167 | projectDirPath = ""; 168 | projectRoot = ""; 169 | targets = ( 170 | 952E24421B0A92A20089B710 /* O365-iOS-Connect-Swift */, 171 | ); 172 | }; 173 | /* End PBXProject section */ 174 | 175 | /* Begin PBXResourcesBuildPhase section */ 176 | 952E24411B0A92A20089B710 /* Resources */ = { 177 | isa = PBXResourcesBuildPhase; 178 | buildActionMask = 2147483647; 179 | files = ( 180 | 952E244E1B0A92A20089B710 /* Main.storyboard in Resources */, 181 | 952E24531B0A92A20089B710 /* LaunchScreen.xib in Resources */, 182 | 952E24501B0A92A20089B710 /* Images.xcassets in Resources */, 183 | 95D883CB1B1381A300DD851C /* EmailBody.html in Resources */, 184 | ); 185 | runOnlyForDeploymentPostprocessing = 0; 186 | }; 187 | /* End PBXResourcesBuildPhase section */ 188 | 189 | /* Begin PBXShellScriptBuildPhase section */ 190 | 0C65CE7BDBAA9DBBA54CBB49 /* Copy Pods Resources */ = { 191 | isa = PBXShellScriptBuildPhase; 192 | buildActionMask = 2147483647; 193 | files = ( 194 | ); 195 | inputPaths = ( 196 | ); 197 | name = "Copy Pods Resources"; 198 | outputPaths = ( 199 | ); 200 | runOnlyForDeploymentPostprocessing = 0; 201 | shellPath = /bin/sh; 202 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-O365-iOS-Connect-Swift/Pods-O365-iOS-Connect-Swift-resources.sh\"\n"; 203 | showEnvVarsInLog = 0; 204 | }; 205 | E6C7BF6C474C6C3FE9BF7FBF /* Check Pods Manifest.lock */ = { 206 | isa = PBXShellScriptBuildPhase; 207 | buildActionMask = 2147483647; 208 | files = ( 209 | ); 210 | inputPaths = ( 211 | ); 212 | name = "Check Pods Manifest.lock"; 213 | outputPaths = ( 214 | ); 215 | runOnlyForDeploymentPostprocessing = 0; 216 | shellPath = /bin/sh; 217 | 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"; 218 | showEnvVarsInLog = 0; 219 | }; 220 | FA7ABFDD6EE5EB5CAA9D86FB /* Embed Pods Frameworks */ = { 221 | isa = PBXShellScriptBuildPhase; 222 | buildActionMask = 2147483647; 223 | files = ( 224 | ); 225 | inputPaths = ( 226 | ); 227 | name = "Embed Pods Frameworks"; 228 | outputPaths = ( 229 | ); 230 | runOnlyForDeploymentPostprocessing = 0; 231 | shellPath = /bin/sh; 232 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-O365-iOS-Connect-Swift/Pods-O365-iOS-Connect-Swift-frameworks.sh\"\n"; 233 | showEnvVarsInLog = 0; 234 | }; 235 | /* End PBXShellScriptBuildPhase section */ 236 | 237 | /* Begin PBXSourcesBuildPhase section */ 238 | 952E243F1B0A92A20089B710 /* Sources */ = { 239 | isa = PBXSourcesBuildPhase; 240 | buildActionMask = 2147483647; 241 | files = ( 242 | 952E24A31B0AA0880089B710 /* AuthenticationManager.swift in Sources */, 243 | 952E24491B0A92A20089B710 /* AppDelegate.swift in Sources */, 244 | 952E24A11B0AA0320089B710 /* SendMailViewController.swift in Sources */, 245 | 952E24A51B0AA0A50089B710 /* O365ClientFetcher.swift in Sources */, 246 | ); 247 | runOnlyForDeploymentPostprocessing = 0; 248 | }; 249 | /* End PBXSourcesBuildPhase section */ 250 | 251 | /* Begin PBXVariantGroup section */ 252 | 952E244C1B0A92A20089B710 /* Main.storyboard */ = { 253 | isa = PBXVariantGroup; 254 | children = ( 255 | 952E244D1B0A92A20089B710 /* Base */, 256 | ); 257 | name = Main.storyboard; 258 | sourceTree = ""; 259 | }; 260 | 952E24511B0A92A20089B710 /* LaunchScreen.xib */ = { 261 | isa = PBXVariantGroup; 262 | children = ( 263 | 952E24521B0A92A20089B710 /* Base */, 264 | ); 265 | name = LaunchScreen.xib; 266 | sourceTree = ""; 267 | }; 268 | /* End PBXVariantGroup section */ 269 | 270 | /* Begin XCBuildConfiguration section */ 271 | 952E24601B0A92A20089B710 /* Debug */ = { 272 | isa = XCBuildConfiguration; 273 | buildSettings = { 274 | ALWAYS_SEARCH_USER_PATHS = NO; 275 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 276 | CLANG_CXX_LIBRARY = "libc++"; 277 | CLANG_ENABLE_MODULES = YES; 278 | CLANG_ENABLE_OBJC_ARC = YES; 279 | CLANG_WARN_BOOL_CONVERSION = YES; 280 | CLANG_WARN_CONSTANT_CONVERSION = YES; 281 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 282 | CLANG_WARN_EMPTY_BODY = YES; 283 | CLANG_WARN_ENUM_CONVERSION = YES; 284 | CLANG_WARN_INT_CONVERSION = YES; 285 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 286 | CLANG_WARN_UNREACHABLE_CODE = YES; 287 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 288 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 289 | COPY_PHASE_STRIP = NO; 290 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 291 | ENABLE_STRICT_OBJC_MSGSEND = YES; 292 | ENABLE_TESTABILITY = YES; 293 | GCC_C_LANGUAGE_STANDARD = gnu99; 294 | GCC_DYNAMIC_NO_PIC = NO; 295 | GCC_NO_COMMON_BLOCKS = YES; 296 | GCC_OPTIMIZATION_LEVEL = 0; 297 | GCC_PREPROCESSOR_DEFINITIONS = ( 298 | "DEBUG=1", 299 | "$(inherited)", 300 | ); 301 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 302 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 303 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 304 | GCC_WARN_UNDECLARED_SELECTOR = YES; 305 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 306 | GCC_WARN_UNUSED_FUNCTION = YES; 307 | GCC_WARN_UNUSED_VARIABLE = YES; 308 | HEADER_SEARCH_PATHS = "$(SRCROOT)/**"; 309 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 310 | MTL_ENABLE_DEBUG_INFO = YES; 311 | ONLY_ACTIVE_ARCH = YES; 312 | SDKROOT = iphoneos; 313 | SWIFT_OBJC_BRIDGING_HEADER = "O365-Connect-Bridging-Header.h"; 314 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 315 | }; 316 | name = Debug; 317 | }; 318 | 952E24611B0A92A20089B710 /* Release */ = { 319 | isa = XCBuildConfiguration; 320 | buildSettings = { 321 | ALWAYS_SEARCH_USER_PATHS = NO; 322 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 323 | CLANG_CXX_LIBRARY = "libc++"; 324 | CLANG_ENABLE_MODULES = YES; 325 | CLANG_ENABLE_OBJC_ARC = YES; 326 | CLANG_WARN_BOOL_CONVERSION = YES; 327 | CLANG_WARN_CONSTANT_CONVERSION = YES; 328 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 329 | CLANG_WARN_EMPTY_BODY = YES; 330 | CLANG_WARN_ENUM_CONVERSION = YES; 331 | CLANG_WARN_INT_CONVERSION = YES; 332 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 333 | CLANG_WARN_UNREACHABLE_CODE = YES; 334 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 335 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 336 | COPY_PHASE_STRIP = NO; 337 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 338 | ENABLE_NS_ASSERTIONS = NO; 339 | ENABLE_STRICT_OBJC_MSGSEND = YES; 340 | GCC_C_LANGUAGE_STANDARD = gnu99; 341 | GCC_NO_COMMON_BLOCKS = YES; 342 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 343 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 344 | GCC_WARN_UNDECLARED_SELECTOR = YES; 345 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 346 | GCC_WARN_UNUSED_FUNCTION = YES; 347 | GCC_WARN_UNUSED_VARIABLE = YES; 348 | HEADER_SEARCH_PATHS = "$(SRCROOT)/**"; 349 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 350 | MTL_ENABLE_DEBUG_INFO = NO; 351 | SDKROOT = iphoneos; 352 | SWIFT_OBJC_BRIDGING_HEADER = "O365-Connect-Bridging-Header.h"; 353 | VALIDATE_PRODUCT = YES; 354 | }; 355 | name = Release; 356 | }; 357 | 952E24631B0A92A20089B710 /* Debug */ = { 358 | isa = XCBuildConfiguration; 359 | baseConfigurationReference = 7307BBA639980E95CC67B04B /* Pods-O365-iOS-Connect-Swift.debug.xcconfig */; 360 | buildSettings = { 361 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 362 | INFOPLIST_FILE = "O365-iOS-Connect-Swift/Info.plist"; 363 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 364 | PRODUCT_BUNDLE_IDENTIFIER = "Microsoft.$(PRODUCT_NAME:rfc1034identifier)"; 365 | PRODUCT_NAME = "$(TARGET_NAME)"; 366 | SWIFT_OBJC_BRIDGING_HEADER = "O365-iOS-Connect-Swift/O365-Connect-Bridging-Header.h"; 367 | }; 368 | name = Debug; 369 | }; 370 | 952E24641B0A92A20089B710 /* Release */ = { 371 | isa = XCBuildConfiguration; 372 | baseConfigurationReference = 6DF25871C499CDFDE0C5106B /* Pods-O365-iOS-Connect-Swift.release.xcconfig */; 373 | buildSettings = { 374 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 375 | INFOPLIST_FILE = "O365-iOS-Connect-Swift/Info.plist"; 376 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 377 | PRODUCT_BUNDLE_IDENTIFIER = "Microsoft.$(PRODUCT_NAME:rfc1034identifier)"; 378 | PRODUCT_NAME = "$(TARGET_NAME)"; 379 | SWIFT_OBJC_BRIDGING_HEADER = "O365-iOS-Connect-Swift/O365-Connect-Bridging-Header.h"; 380 | }; 381 | name = Release; 382 | }; 383 | /* End XCBuildConfiguration section */ 384 | 385 | /* Begin XCConfigurationList section */ 386 | 952E243E1B0A92A20089B710 /* Build configuration list for PBXProject "O365-iOS-Connect-Swift" */ = { 387 | isa = XCConfigurationList; 388 | buildConfigurations = ( 389 | 952E24601B0A92A20089B710 /* Debug */, 390 | 952E24611B0A92A20089B710 /* Release */, 391 | ); 392 | defaultConfigurationIsVisible = 0; 393 | defaultConfigurationName = Release; 394 | }; 395 | 952E24621B0A92A20089B710 /* Build configuration list for PBXNativeTarget "O365-iOS-Connect-Swift" */ = { 396 | isa = XCConfigurationList; 397 | buildConfigurations = ( 398 | 952E24631B0A92A20089B710 /* Debug */, 399 | 952E24641B0A92A20089B710 /* Release */, 400 | ); 401 | defaultConfigurationIsVisible = 0; 402 | defaultConfigurationName = Release; 403 | }; 404 | /* End XCConfigurationList section */ 405 | }; 406 | rootObject = 952E243B1B0A92A20089B710 /* Project object */; 407 | } 408 | -------------------------------------------------------------------------------- /swift/O365-iOS-Connect-Swift.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /swift/O365-iOS-Connect-Swift.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /swift/O365-iOS-Connect-Swift/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // ********************************************************* 2 | // 3 | // O365-iOS-Connect, https://github.com/OfficeDev/O365-iOS-Connect 4 | // 5 | // Copyright (c) Microsoft Corporation 6 | // All rights reserved. 7 | // 8 | // MIT License: 9 | // Permission is hereby granted, free of charge, to any person obtaining 10 | // a copy of this software and associated documentation files (the 11 | // "Software"), to deal in the Software without restriction, including 12 | // without limitation the rights to use, copy, modify, merge, publish, 13 | // distribute, sublicense, and/or sell copies of the Software, and to 14 | // permit persons to whom the Software is furnished to do so, subject to 15 | // the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be 18 | // included in all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | // ********************************************************* 29 | 30 | import UIKit 31 | 32 | @UIApplicationMain 33 | class AppDelegate: UIResponder, UIApplicationDelegate { 34 | 35 | var window: UIWindow? 36 | 37 | 38 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 39 | // Override point for customization after application launch. 40 | return true 41 | } 42 | 43 | func applicationWillResignActive(application: UIApplication) { 44 | // 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. 45 | // 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. 46 | } 47 | 48 | func applicationDidEnterBackground(application: UIApplication) { 49 | // 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. 50 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 51 | } 52 | 53 | func applicationWillEnterForeground(application: UIApplication) { 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 | func applicationDidBecomeActive(application: UIApplication) { 58 | // 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. 59 | } 60 | 61 | func applicationWillTerminate(application: UIApplication) { 62 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /swift/O365-iOS-Connect-Swift/AuthenticationManager.swift: -------------------------------------------------------------------------------- 1 | // ********************************************************* 2 | // 3 | // O365-iOS-Connect, https://github.com/OfficeDev/O365-iOS-Connect 4 | // 5 | // Copyright (c) Microsoft Corporation 6 | // All rights reserved. 7 | // 8 | // MIT License: 9 | // Permission is hereby granted, free of charge, to any person obtaining 10 | // a copy of this software and associated documentation files (the 11 | // "Software"), to deal in the Software without restriction, including 12 | // without limitation the rights to use, copy, modify, merge, publish, 13 | // distribute, sublicense, and/or sell copies of the Software, and to 14 | // permit persons to whom the Software is furnished to do so, subject to 15 | // the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be 18 | // included in all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | // ********************************************************* 29 | 30 | import Foundation 31 | 32 | // You will set your application's clientId and redirect URI. You get 33 | // these when you register your application in Azure AD. 34 | let REDIRECT_URL_STRING = "ENTER_REDIRECT_URI_HERE" 35 | let CLIENT_ID = "ENTER_CLIENT_ID_HERE" 36 | let AUTHORITY = "https://login.microsoftonline.com/common" 37 | 38 | class AuthenticationManager { 39 | var redirectURL: NSURL 40 | var authority: String = "" 41 | var clientId: String = "" 42 | var dependencyResolver: ADALDependencyResolver 43 | 44 | init () { 45 | // These are settings that you need to set based on your 46 | // client registration in Azure AD. 47 | redirectURL = NSURL(string: REDIRECT_URL_STRING)! 48 | authority = AUTHORITY 49 | clientId = CLIENT_ID 50 | dependencyResolver = ADALDependencyResolver() 51 | } 52 | 53 | // Use a single authentication manager for the application. 54 | class var sharedInstance: AuthenticationManager { 55 | struct Singleton { 56 | static let instance = AuthenticationManager() 57 | } 58 | return Singleton.instance 59 | } 60 | 61 | // Acquire access and refresh tokens from Azure AD for the user 62 | func acquireAuthTokenWithResourceId(resourceId: String, completionHandler:((Bool) -> Void)) { 63 | var error: ADAuthenticationError? 64 | let authContext: ADAuthenticationContext = ADAuthenticationContext(authority: authority, error:&error) 65 | 66 | // The first time this application is run, the [ADAuthenticationContext acquireTokenWithResource] 67 | // manager will send a request to the AUTHORITY (see the const at the top of this file) which 68 | // will redirect you to a login page. You will provide your credentials and the response will 69 | // contain your refresh and access tokens. The second time this application is run, and assuming 70 | // you didn't clear your token cache, the authentication manager will use the access or refresh 71 | // token in the cache to authenticate client requests. 72 | // This will result in a call to the service if you need to get an access token. 73 | 74 | authContext.acquireTokenWithResource(resourceId, clientId: clientId, redirectUri: redirectURL) { 75 | (result:ADAuthenticationResult!) -> Void in 76 | 77 | if result.status.rawValue != AD_SUCCEEDED.rawValue { 78 | completionHandler(false) 79 | } 80 | else { 81 | let userDefaults = NSUserDefaults.standardUserDefaults() 82 | 83 | userDefaults.setObject(result.tokenCacheStoreItem.userInformation.userId, forKey: "LogInUser") 84 | userDefaults.synchronize() 85 | 86 | self.dependencyResolver = ADALDependencyResolver(context: authContext, resourceId: resourceId, clientId: self.clientId , redirectUri: self.redirectURL) 87 | completionHandler(true) 88 | } 89 | } 90 | } 91 | 92 | // Clear the ADAL token cache and remove this application's cookies. 93 | func clearCredentials () { 94 | var error: ADAuthenticationError? 95 | let cache: ADTokenCacheStoring = ADAuthenticationSettings.sharedInstance().defaultTokenCacheStore 96 | 97 | // Clear the token cache 98 | let allItemsArray = cache.allItemsWithError(&error) 99 | if (!allItemsArray.isEmpty) { 100 | cache.removeAllWithError(&error) 101 | } 102 | 103 | // Remove all the cookies from this application's sandbox. The authorization code is stored in the 104 | // cookies and ADAL will try to get to access tokens based on auth code in the cookie. 105 | let cookieStore = NSHTTPCookieStorage.sharedHTTPCookieStorage() 106 | if let cookies = cookieStore.cookies { 107 | for cookie in cookies { 108 | cookieStore.deleteCookie(cookie ) 109 | } 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /swift/O365-iOS-Connect-Swift/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /swift/O365-iOS-Connect-Swift/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 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 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda. 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 | -------------------------------------------------------------------------------- /swift/O365-iOS-Connect-Swift/EmailBody.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Congratulations!

5 |

You just sent this email from the Office 365 Connect sample. How cool is that? You are well on your way to incorporating Office 365 services in your apps.

6 |

Give us feedback

7 |

We hope you found this sample useful. We would love to hear from you, so drop us an email at 8 | docthis@microsoft.com with your comments or 9 | log an issue in our GitHub repository.

10 |

For more details on what else you can do with the Office 365 services in your iOS app, start with the 11 | Getting started with iOS page on dev.office.com.

12 |

Thanks, and happy coding!

13 |

Your Office 365 Development team

14 |
15 | 16 | 17 | 21 | 25 | 26 |
18 | See on GitHub 19 | 20 | 22 | Suggest on UserVoice 23 | 24 |
27 |
28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /swift/O365-iOS-Connect-Swift/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /swift/O365-iOS-Connect-Swift/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | NSAppTransportSecurity 40 | 41 | NSExceptionDomains 42 | 43 | outlook.office365.com 44 | 45 | NSIncludeSubmdomains 46 | 47 | NSExceptionRequiresForwardSecrecy 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /swift/O365-iOS-Connect-Swift/O365-Connect-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license at the bottom of this file. 3 | */ 4 | 5 | #ifndef O365_iOS_Connect_Swift_O365_Connect_Bridging_Header_h 6 | #define O365_iOS_Connect_Swift_O365_Connect_Bridging_Header_h 7 | 8 | #import 9 | #import 10 | #import 11 | #import 12 | #import 13 | #import 14 | #import 15 | #import 16 | 17 | 18 | #endif 19 | 20 | //-(MSOutlookUserCollectionFetcher*) getUsers; 21 | //-(MSOutlookUserFetcher*) getMe; 22 | 23 | // ********************************************************* 24 | // 25 | // O365-iOS-Connect, https://github.com/OfficeDev/O365-iOS-Connect 26 | // 27 | // Copyright (c) Microsoft Corporation 28 | // All rights reserved. 29 | // 30 | // MIT License: 31 | // Permission is hereby granted, free of charge, to any person obtaining 32 | // a copy of this software and associated documentation files (the 33 | // "Software"), to deal in the Software without restriction, including 34 | // without limitation the rights to use, copy, modify, merge, publish, 35 | // distribute, sublicense, and/or sell copies of the Software, and to 36 | // permit persons to whom the Software is furnished to do so, subject to 37 | // the following conditions: 38 | // 39 | // The above copyright notice and this permission notice shall be 40 | // included in all copies or substantial portions of the Software. 41 | // 42 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 43 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 44 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 45 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 46 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 47 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 48 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 49 | // 50 | // ********************************************************* -------------------------------------------------------------------------------- /swift/O365-iOS-Connect-Swift/O365ClientFetcher.swift: -------------------------------------------------------------------------------- 1 | // ********************************************************* 2 | // 3 | // O365-iOS-Connect, https://github.com/OfficeDev/O365-iOS-Connect 4 | // 5 | // Copyright (c) Microsoft Corporation 6 | // All rights reserved. 7 | // 8 | // MIT License: 9 | // Permission is hereby granted, free of charge, to any person obtaining 10 | // a copy of this software and associated documentation files (the 11 | // "Software"), to deal in the Software without restriction, including 12 | // without limitation the rights to use, copy, modify, merge, publish, 13 | // distribute, sublicense, and/or sell copies of the Software, and to 14 | // permit persons to whom the Software is furnished to do so, subject to 15 | // the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be 18 | // included in all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | // ********************************************************* 29 | 30 | import Foundation 31 | 32 | class Office365ClientFetcher { 33 | 34 | // Gets the Outlook Services client. This will authenticate a user with the service 35 | // and get the application an access and refresh token to act on behalf of the user. 36 | // The access and refresh token will be cached. The next time a user attempts 37 | // to access the service, the access token will be used. If the access token 38 | // has expired, the client will use the refresh token to get a new access token. 39 | // If the refresh token has expired, then ADAL will get the authorization code 40 | // from the cookie cache and use that to get a new access and refresh token. 41 | 42 | 43 | func fetchOutlookClient(completionHandler:((outlookClient: MSOutlookClient) -> Void)) { 44 | // Get an instance of the authentication controller. 45 | let authenticationManager = AuthenticationManager.sharedInstance 46 | 47 | // The first time this application is run, the authentication manager will send a request 48 | // to the authority which will redirect you to a login page. You will provide your credentials 49 | // and the response will contain your refresh and access tokens. The second time this 50 | // application is run, and assuming you didn't clear your token cache, the authentication 51 | // manager will use the access or refresh token in the cache to authenticate client requests. 52 | // This will result in a call to the service if you need to get an access token. 53 | 54 | authenticationManager.acquireAuthTokenWithResourceId("https://outlook.office365.com/") { 55 | (authenticated:Bool) -> Void in 56 | 57 | if (authenticated) { 58 | let userDefaults = NSUserDefaults.standardUserDefaults() 59 | 60 | if let serviceEndpoints = userDefaults.dictionaryForKey("O365ServiceEndpoints") { 61 | if let serviceEndpointUrl: AnyObject = serviceEndpoints["Mail"] { 62 | // Gets the MSOutlookClient with the URL for the Mail service. 63 | let outlookClient = MSOutlookClient(url: serviceEndpointUrl as! String, dependencyResolver: authenticationManager.dependencyResolver) 64 | completionHandler(outlookClient: outlookClient) 65 | } 66 | } 67 | } 68 | else { 69 | // Display an alert in case of an error 70 | dispatch_async(dispatch_get_main_queue()) { 71 | NSLog("Error in the authentication") 72 | let alert = UIAlertView(title: "Error", message: "Authentication failed. Check the log for errors.", delegate: self, cancelButtonTitle: "OK") 73 | alert.show() 74 | } 75 | } 76 | } 77 | } 78 | 79 | // Gets the DiscoveryClient which is used to discover the service endpoints 80 | func fetchDiscoveryClient(completionHandler:((discoveryClient: MSDiscoveryClient) -> Void)) { 81 | 82 | // Get an instance of the authentication controller. 83 | let authenticationManager:AuthenticationManager = AuthenticationManager.sharedInstance 84 | 85 | // The first time this application is run, the authentication manager will send a request 86 | // to the authority which will redirect you to a login page. You will provide your credentials 87 | // and the response will contain your refresh and access tokens. The second time this 88 | // application is run, and assuming you didn't clear your token cache, the authentication 89 | // manager will use the access or refresh token in the cache to authenticate client requests. 90 | // This will result in a call to the service if you need to get an access token. 91 | 92 | authenticationManager.acquireAuthTokenWithResourceId("https://api.office.com/discovery/") { 93 | (authenticated:Bool) -> Void in 94 | 95 | if (authenticated) { 96 | // Gets the MSDiscoveryClient with the URL for the Discovery service. 97 | let discoveryClient = MSDiscoveryClient(url: "https://api.office.com/discovery/v1.0/me/", dependencyResolver: authenticationManager.dependencyResolver) 98 | completionHandler(discoveryClient: discoveryClient) 99 | } 100 | else { 101 | // Display an alert in case of an error 102 | dispatch_async(dispatch_get_main_queue()) { 103 | NSLog("Error in the authentication") 104 | let alert: UIAlertView = UIAlertView(title: "Error", message: "Authentication failed. Check the log for errors.", delegate: self, cancelButtonTitle: "OK") 105 | alert.show() 106 | } 107 | } 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /swift/O365-iOS-Connect-Swift/SendMailViewController.swift: -------------------------------------------------------------------------------- 1 | // ********************************************************* 2 | // 3 | // O365-iOS-Connect, https://github.com/OfficeDev/O365-iOS-Connect 4 | // 5 | // Copyright (c) Microsoft Corporation 6 | // All rights reserved. 7 | // 8 | // MIT License: 9 | // Permission is hereby granted, free of charge, to any person obtaining 10 | // a copy of this software and associated documentation files (the 11 | // "Software"), to deal in the Software without restriction, including 12 | // without limitation the rights to use, copy, modify, merge, publish, 13 | // distribute, sublicense, and/or sell copies of the Software, and to 14 | // permit persons to whom the Software is furnished to do so, subject to 15 | // the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be 18 | // included in all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | // ********************************************************* 29 | 30 | import UIKit 31 | 32 | class SendMailViewController: UIViewController { 33 | 34 | @IBOutlet weak var headerLabel: UILabel! 35 | @IBOutlet weak var mainContentTextView: UITextView! 36 | @IBOutlet weak var emailTextField: UITextField! 37 | @IBOutlet weak var sendMailButton: UIButton! 38 | @IBOutlet weak var activityIndicator: UIActivityIndicatorView! 39 | @IBOutlet weak var statusTextView: UITextView! 40 | @IBOutlet weak var disconnectButton: UIBarButtonItem! 41 | 42 | var baseController = Office365ClientFetcher() 43 | var serviceEndpointLookup = NSMutableDictionary() 44 | 45 | override func viewDidLoad() { 46 | super.viewDidLoad() 47 | 48 | // Do any additional setup after loading the view, typically from a nib. 49 | disconnectButton.enabled = false 50 | sendMailButton.hidden = true 51 | emailTextField.hidden = true 52 | mainContentTextView.hidden = true 53 | headerLabel.hidden = true 54 | statusTextView.hidden = true 55 | activityIndicator.hidden = true 56 | 57 | connectToOffice365() 58 | } 59 | 60 | func connectToOffice365() { 61 | // Connect to the service by discovering the service endpoints and authorizing 62 | // the application to access the user's email. This will store the user's 63 | // service URLs in a property list to be accessed when calls are made to the 64 | // service. This results in two calls: one to authenticate, and one to get the 65 | // URLs. ADAL will cache the access and refresh tokens so you won't need to 66 | // provide credentials unless you sign out. 67 | 68 | // Get the discovery client. First time this is ran you will be prompted 69 | // to provide your credentials which will authenticate you with the service. 70 | // The application will get an access token in the response. 71 | 72 | baseController.fetchDiscoveryClient { (discoveryClient) -> () in 73 | let servicesInfoFetcher = discoveryClient.getservices() 74 | 75 | // Call the Discovery Service and get back an array of service endpoint information 76 | 77 | let servicesTask = servicesInfoFetcher.readWithCallback{(serviceEndPointObjects:[AnyObject]!, error:MSODataException!) -> Void in 78 | let serviceEndpoints = serviceEndPointObjects as! [MSDiscoveryServiceInfo] 79 | 80 | if (serviceEndpoints.count > 0) { 81 | // Here is where we cache the service URLs returned by the Discovery Service. You may not 82 | // need to call the Discovery Service again until either this cache is removed, or you 83 | // get an error that indicates that the endpoint is no longer valid. 84 | 85 | var serviceEndpointLookup = [NSObject: AnyObject]() 86 | 87 | for serviceEndpoint in serviceEndpoints { 88 | serviceEndpointLookup[serviceEndpoint.capability] = serviceEndpoint.serviceEndpointUri 89 | } 90 | 91 | // Keep track of the service endpoints in the user defaults 92 | let userDefaults = NSUserDefaults.standardUserDefaults() 93 | 94 | userDefaults.setObject(serviceEndpointLookup, forKey: "O365ServiceEndpoints") 95 | userDefaults.synchronize() 96 | 97 | dispatch_async(dispatch_get_main_queue()) { 98 | let userEmail = userDefaults.stringForKey("LogInUser")! 99 | var parts = userEmail.componentsSeparatedByString("@") 100 | 101 | self.headerLabel.text = String(format:"Hi %@!", parts[0]) 102 | self.headerLabel.hidden = false 103 | self.mainContentTextView.hidden = false 104 | self.emailTextField.text = userEmail 105 | self.statusTextView.text = "" 106 | self.disconnectButton.enabled = true 107 | self.sendMailButton.hidden = false 108 | self.emailTextField.hidden = false 109 | } 110 | } 111 | 112 | else { 113 | dispatch_async(dispatch_get_main_queue()) { 114 | NSLog("Error in the authentication: %@", error) 115 | let alert: UIAlertView = UIAlertView(title: "Error", message: "Authentication failed. This may be because the Internet connection is offline or perhaps the credentials are incorrect. Check the log for errors and try again.", delegate: self, cancelButtonTitle: "OK") 116 | alert.show() 117 | } 118 | } 119 | } 120 | 121 | servicesTask.resume() 122 | } 123 | } 124 | 125 | func sendMailMessage() { 126 | let message = buildMessage() 127 | 128 | // Get the MSOutlookClient. A call will be made to Azure AD and you will be prompted for credentials if you don't 129 | // have an access or refresh token in your token cache. 130 | 131 | baseController.fetchOutlookClient { 132 | (outlookClient) -> Void in 133 | 134 | dispatch_async(dispatch_get_main_queue()) { 135 | // Show the activity indicator 136 | self.activityIndicator.hidden = false 137 | self.activityIndicator.startAnimating() 138 | } 139 | 140 | let userFetcher = outlookClient.getMe() 141 | let userOperations = (userFetcher.operations as MSOutlookUserOperations) 142 | 143 | let task = userOperations.sendMailWithMessage(message, saveToSentItems: true) { 144 | (returnValue:Int32, error:MSODataException!) -> Void in 145 | 146 | var statusText: String 147 | 148 | if (error == nil) { 149 | statusText = "Check your inbox, you have a new message. :)" 150 | } 151 | else { 152 | statusText = "The email could not be sent. Check the log for errors." 153 | NSLog("%@",[error.localizedDescription]) 154 | } 155 | 156 | // Update the UI. 157 | 158 | dispatch_async(dispatch_get_main_queue()) { 159 | self.statusTextView.text = statusText 160 | self.statusTextView.hidden = false 161 | self.activityIndicator .stopAnimating() 162 | self.activityIndicator.hidden = true 163 | } 164 | } 165 | 166 | task.resume() 167 | } 168 | } 169 | 170 | // Compose the mail message 171 | func buildMessage() -> MSOutlookMessage { 172 | // Create a new message. Set properties on the message. 173 | let message: MSOutlookMessage = MSOutlookMessage() 174 | message.Subject = "Welcome to Office 365 development on iOS with the Office 365 Connect sample" 175 | 176 | // Get the recipient's email address. 177 | // The ToRecipients property is an array of MSOulookRecipient objects. 178 | // See the helper method getRecipients to understand the usage. 179 | let toEmail = emailTextField.text 180 | 181 | let recipient = MSOutlookRecipient() 182 | recipient.EmailAddress = MSOutlookEmailAddress() 183 | recipient.EmailAddress.Address = toEmail!.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet()) 184 | 185 | // The mutable array here is required to maintain compatibility with the API 186 | var recipientArray: [MSOutlookRecipient] = [] 187 | recipientArray.append(recipient as MSOutlookRecipient) 188 | let mutableRecipientArray = NSMutableArray(array: recipientArray) 189 | message.ToRecipients = mutableRecipientArray 190 | 191 | // Get the email text and put in the email body. 192 | let filePath = NSBundle.mainBundle().pathForResource("EmailBody", ofType:"html") 193 | let body = (try? NSString(contentsOfFile: filePath!, encoding: NSUTF8StringEncoding))?.stringByReplacingOccurrencesOfString("\"", withString: "\\\""); 194 | 195 | message.Body = MSOutlookItemBody() 196 | message.Body.ContentType = MSOutlookBodyType.BodyType_HTML 197 | message.Body.Content = body! as String 198 | 199 | return message 200 | } 201 | 202 | @IBAction func disconnectBtnClicked(sender: AnyObject) { 203 | disconnectButton.enabled = false 204 | sendMailButton.hidden = true 205 | mainContentTextView.text = "You're no longer connected to Office 365." 206 | headerLabel.hidden = true 207 | emailTextField.hidden = true 208 | statusTextView.hidden = true 209 | 210 | // Clear the access and refresh tokens from the credential cache. You need to clear cookies 211 | // since ADAL uses information stored in the cookies to get a new access token. 212 | let authenticationManager:AuthenticationManager = AuthenticationManager.sharedInstance 213 | authenticationManager.clearCredentials() 214 | } 215 | 216 | @IBAction func sendMailBtnClicked(sender: AnyObject) { 217 | self.emailTextField.resignFirstResponder() 218 | 219 | sendMailMessage() 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /swift/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | source 'https://github.com/Cocoapods/Specs.git' 3 | platform :ios, '8.0' 4 | 5 | target 'O365-iOS-Connect-Swift' do 6 | 7 | pod 'ADALiOS', '~> 1.2.1' 8 | pod 'Office365/Outlook', '= 0.9.1' 9 | pod 'Office365/Discovery', '= 0.9.1' 10 | 11 | end 12 | 13 | --------------------------------------------------------------------------------