$FILE
16 | {
17 | "test.clientId" : "$1",
18 | "test.username" : "$2",
19 | "test.password" : "$3"
20 | }
21 | EOM
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 |
3 | ## Build generated
4 | build/
5 | DerivedData/
6 |
7 | ## Various settings
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata/
17 |
18 | ## Other
19 | *.moved-aside
20 | *.xcuserstate
21 |
22 | ## Obj-C/Swift specific
23 | *.hmap
24 | *.ipa
25 | *.dSYM.zip
26 | *.dSYM
27 |
28 | ## Playgrounds
29 | timeline.xctimeline
30 | playground.xcworkspace
31 |
32 | # Swift Package Manager
33 | #
34 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
35 | # Packages/
36 | .build/
37 |
38 | # CocoaPods
39 | #
40 | Pods/
41 |
42 |
--------------------------------------------------------------------------------
/Graph-iOS-Swift-Snippets/Assets.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 | }
--------------------------------------------------------------------------------
/Graph-iOS-Swift-SnippetsTests/Graph_iOS_Swift_SnippetsTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Graph_iOS_Swift_SnippetsTests.swift
3 | // Graph-iOS-Swift-SnippetsTests
4 | //
5 | // Created by Jason Kim on 7/8/16.
6 | // Copyright © 2016 Jason Kim. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | @testable import Graph_iOS_Swift_Snippets
12 |
13 | class Graph_iOS_Swift_SnippetsTests: XCTestCase {
14 |
15 | override func setUp() {
16 | super.setUp()
17 | // Put setup code here. This method is called before the invocation of each test method in the class.
18 |
19 | }
20 |
21 | override func tearDown() {
22 | // Put teardown code here. This method is called after the invocation of each test method in the class.
23 | super.tearDown()
24 | }
25 |
26 |
27 |
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/Graph-iOS-Swift-SnippetsTests/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 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Graph-iOS-Swift-Snippets/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 | import UIKit
7 | import MSAL
8 |
9 | @UIApplicationMain
10 | class AppDelegate: UIResponder, UIApplicationDelegate
11 | {
12 | var window: UIWindow?
13 |
14 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
15 | {
16 | return true
17 | }
18 |
19 | func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool
20 | {
21 | guard let sourceApplication = options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String else { return false }
22 |
23 | return MSALPublicClientApplication.handleMSALResponse(url, sourceApplication: sourceApplication)
24 | }
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - MSAL (0.4.0):
3 | - MSAL/app-lib (= 0.4.0)
4 | - MSAL/app-lib (0.4.0)
5 | - MSGraphSDK (0.10.1):
6 | - MSGraphSDK/Common (= 0.10.1)
7 | - MSGraphSDK/Extensions (= 0.10.1)
8 | - MSGraphSDK/Implementations (= 0.10.1)
9 | - MSGraphSDK/MSGraphCoreSDK (= 0.10.1)
10 | - MSGraphSDK/Common (0.10.1)
11 | - MSGraphSDK/Extensions (0.10.1):
12 | - MSGraphSDK/Implementations
13 | - MSGraphSDK/MSGraphCoreSDK
14 | - MSGraphSDK/Implementations (0.10.1):
15 | - MSGraphSDK/Common
16 | - MSGraphSDK/MSGraphCoreSDK (0.10.1):
17 | - MSGraphSDK/Common
18 |
19 | DEPENDENCIES:
20 | - MSAL (~> 0.4.0)
21 | - MSGraphSDK
22 |
23 | SPEC REPOS:
24 | https://github.com/cocoapods/specs.git:
25 | - MSAL
26 | - MSGraphSDK
27 |
28 | SPEC CHECKSUMS:
29 | MSAL: fb209227bd464771648206286eb2bcca46f438ec
30 | MSGraphSDK: 3c43eb632ca969593f1bdd5612b573e436bd3283
31 |
32 | PODFILE CHECKSUM: 3ad47728eb54cefdfb1d559e398f484d13aca6a9
33 |
34 | COCOAPODS: 1.6.1
35 |
--------------------------------------------------------------------------------
/License.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 |
4 | Copyright (c) 2016 Microsoft
5 |
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 |
15 | The above copyright notice and this permission notice shall be included in
16 | all copies or substantial portions of the Software.
17 |
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | THE SOFTWARE.
--------------------------------------------------------------------------------
/Graph-iOS-Swift-Snippets/EmailBody.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Congratulations!
5 | You just sent this email from the Snippets Sample for iOS Swift Using the Microsoft Graph SDK. How cool is that? You are well on your way to incorporating Microsoft Graph services in your apps.
6 | Give us feedback
7 | We'd love to get your feedback about the project. You can send your questions and suggestions to us in the issues section of the repository.
8 |
For more details on what else you can do with the Microsoft Graph endpoint in your iOS app, start with the
9 | Microsoft Graph page.
10 | Thanks, and happy coding!
11 | Your Microsoft Graph Development team
12 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Graph-iOS-Swift-Snippets/ApplicationConstants.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 |
7 | import Foundation
8 |
9 | struct ApplicationConstants
10 | {
11 | // You will set your application's clientId
12 | static let clientId = "YOUR CLIENT ID"
13 | static let authority = "https://login.microsoftonline.com/common"
14 |
15 | // Set scopes
16 | static let scopes = [
17 | "https://graph.microsoft.com/User.Read",
18 | "https://graph.microsoft.com/User.ReadWrite",
19 | "https://graph.microsoft.com/User.ReadBasic.All",
20 | "https://graph.microsoft.com/Mail.Send",
21 | "https://graph.microsoft.com/Calendars.ReadWrite",
22 | "https://graph.microsoft.com/Mail.ReadWrite",
23 | "https://graph.microsoft.com/Files.ReadWrite",
24 | // Admin-only scopes. Uncomment these if you're running the sample with an admin work account.
25 | // You won't be able to sign in with a non-admin work account if you request these scopes.
26 | "https://graph.microsoft.com/Directory.AccessAsUser.All",
27 | "https://graph.microsoft.com/User.ReadWrite.All"
28 | ]
29 | }
30 |
31 |
32 | enum MSGraphError: Swift.Error
33 | {
34 | case NSErrorType(error: NSError)
35 | case UnexpectecError(errorString: String)
36 | }
37 |
--------------------------------------------------------------------------------
/Graph-iOS-Swift-Snippets/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Graph-iOS-Swift-Snippets/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 | UIStatusBarTintParameters
34 |
35 | UINavigationBar
36 |
37 | Style
38 | UIBarStyleDefault
39 | Translucent
40 |
41 |
42 |
43 | UISupportedInterfaceOrientations
44 |
45 | UIInterfaceOrientationPortrait
46 | UIInterfaceOrientationLandscapeLeft
47 | UIInterfaceOrientationLandscapeRight
48 |
49 | CFBundleURLTypes
50 |
51 |
52 | CFBundleTypeRole
53 | Editor
54 | CFBundleURLName
55 | $(PRODUCT_BUNDLE_IDENTIFIER)
56 | CFBundleURLSchemes
57 |
58 | msauth.com.microsoft.Graph-iOS-Swift-Snippets
59 |
60 |
61 |
62 | LSApplicationQueriesSchemes
63 |
64 | msauth
65 | msauthv2
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/Graph-iOS-Swift-Snippets/MasterViewController.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 |
7 | import UIKit
8 |
9 | class MasterViewController: UITableViewController
10 | {
11 | var detailViewController: DetailViewController?
12 | var authenticationProvider: AuthenticationProvider!
13 | var snippets: Snippets!
14 | var objects = [AnyObject]()
15 |
16 | override func viewDidLoad()
17 | {
18 | super.viewDidLoad()
19 |
20 | snippets = Snippets(authenticationProvider: authenticationProvider)
21 | }
22 |
23 | override func viewWillAppear(_ animated: Bool)
24 | {
25 | super.viewWillAppear(animated)
26 |
27 | self.clearsSelectionOnViewWillAppear = self.splitViewController!.isCollapsed
28 | }
29 |
30 | // MARK: - Segues
31 |
32 | override func prepare(for segue: UIStoryboardSegue, sender: Any?)
33 | {
34 | if segue.identifier == "showDetail" {
35 | if let indexPath = self.tableView.indexPathForSelectedRow {
36 | let snippet = snippets[indexPath.section][indexPath.row]
37 | let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
38 |
39 | controller.snippet = snippet
40 | controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem
41 | controller.navigationItem.leftItemsSupplementBackButton = true
42 | }
43 | }
44 | }
45 |
46 | @IBAction func disconnect(_ sender: Any)
47 | {
48 | authenticationProvider.disconnect()
49 | self.navigationController?.splitViewController?.dismiss(animated: true, completion: nil)
50 | }
51 |
52 | // MARK: - UITableViewController
53 |
54 | override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
55 | {
56 | return snippets[section].name
57 | }
58 |
59 | override func numberOfSections(in tableView: UITableView) -> Int
60 | {
61 | return snippets.count
62 | }
63 |
64 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
65 | {
66 | return snippets[section].count
67 | }
68 |
69 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
70 | {
71 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
72 |
73 | let snippet = snippets[indexPath.section][indexPath.row]
74 |
75 | cell.textLabel!.text = snippet.name
76 | if snippet.needAdminAccess {
77 | cell.detailTextLabel!.text = "Need admin access"
78 | } else {
79 | cell.detailTextLabel!.text = ""
80 | }
81 |
82 | return cell
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/README-Localized/README-zh-cn.md:
--------------------------------------------------------------------------------
1 | ---
2 | page_type: sample
3 | products:
4 | - office-365
5 | - office-outlook
6 | - ms-graph
7 | languages:
8 | - swift
9 | extensions:
10 | contentType: samples
11 | technologies:
12 | - Microsoft Graph
13 | services:
14 | - Office 365
15 | - Outlook
16 | - Groups
17 | platforms:
18 | - iOS
19 | createdDate: 5/26/2016 8:08:35 AM
20 | ---
21 | # Microsoft Graph iOS Swift 代码段示例
22 |
23 | ## 目录
24 |
25 | - [简介](#introduction)
26 | - [先决条件](#prerequisites)
27 | - [注册和配置应用](#register-and-configure-the-app)
28 | - [构建和调试](#build-and-debug)
29 | - [运行示例](#running-the-sample)
30 |
31 | ## 简介
32 |
33 | 本示例包含介绍如何使用 Microsoft Graph SDK 以发送电子邮件、管理组和使用 Office 365 数据执行其他活动的代码段存储库。它使用[适用于 iOS 的 Microsoft Graph SDK](https://github.com/microsoftgraph/msgraph-sdk-ios) 以结合使用由 Microsoft Graph 返回的数据。
34 |
35 | 此存储库介绍如何通过在 iOS 应用中向 Microsoft Graph API 生成 HTTP 请求来访问多个资源,包括 Microsoft Azure Active Directory (AD) 和 Office 365 API。
36 |
37 | 这些代码段简单且是自包含的,你可以在任何合适的时间将其复制并粘贴到你自己的代码中,或将其作为学习如何使用适用于 iOS 的 Microsoft Graph SDK 的资源。
38 |
39 | **注意:** 如果可能,请通过“非工作”或测试帐户使用该示例。该示例并非总能清理邮箱和日历中创建的对象。此时,需要手动删除示例邮件和日历事件。此外,请注意获取和发送邮件的代码段和其中的获取、创建、更新和删除事件在所有个人帐户中不可用。只有在这些帐户更新至使用 v2 身份验证终结点时,这些操作才可用。
40 |
41 | ## 先决条件
42 |
43 | 此示例要求如下:
44 |
45 | - [Xcode](https://developer.apple.com/xcode/downloads/) 版本 10.2.1
46 | - 安装 [CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html) 成为依存关系管理器。
47 | - Microsoft 工作或个人电子邮件帐户,例如 Office 365 或 outlook.com、hotmail.com 等。你可以注册 [Office 365 开发人员订阅](https://aka.ms/devprogramsignup),其中包含你开始构建 Office 365 应用所需的资源。
48 |
49 | ## 注册和配置应用
50 |
51 | 1. 打开浏览器,并导航到 [Azure Active Directory 管理中心](https://aad.portal.azure.com),然后使用**个人帐户**(亦称为“Microsoft 帐户”)或**工作/学校帐户**登录。
52 |
53 | 1. 选择左侧导航栏中的“Azure Active Directory”,再选择“管理”下的“应用注册”。
54 |
55 | 1. 选择“新注册”。在“注册应用”页上,按如下方式设置值。
56 |
57 | - 将“名称”设置为 `Swift 代码段示例`。
58 | - 将“受支持的帐户类型”设置为“任何组织目录中的帐户和个人 Microsoft 帐户”。
59 | - 在“重定向 URI”中,将下拉列表更改为“公共客户端(移动和桌面)”,然后将值设为 `msauth.com.microsoft.Graph-iOS-Swift-Snippets://auth`.
60 |
61 | 1. 选择“注册”。在“Swift 代码段示例”页上,复制并保存“应用程序(客户端) ID”的值,将在下一步中用到它。
62 |
63 | ## 构建和调试
64 |
65 | 1. 克隆该存储库
66 |
67 | 1. 打开**终端**,然后导航到该项目的根。输入下面的命令来安装依赖项。
68 |
69 | ```Shell
70 | pod install
71 | ```
72 |
73 | 1. 打开 Xcode 中的 **Graph-iOS-Swift-Snippets.xcworkspace**。
74 |
75 | 1. 打开 **ApplicationConstants.swift**。将 `ENTER_CLIENT_ID` 替换为你从注册应用中获得的应用程序 ID。
76 |
77 | ```swift
78 | // You will set your application's clientId
79 | static let clientId = "ENTER_CLIENT_ID"
80 | ```
81 |
82 | 1. 运行示例。
83 |
84 | ## 运行示例
85 |
86 | 启动时,应用将显示常见用户任务列表。这些任务可以基于帐户类型和权限级别运行,并在注释中进行了说明:
87 |
88 | - 适用于工作或学校以及个人帐户的任务,如接收和发送电子邮件、创建文件等。
89 | - 仅适用于工作或学校帐户的任务,如获取用户的管理器或帐户照片。
90 | - 仅适用于具有管理权限的工作或学校帐户的任务,如获取组成员或新建用户帐户。
91 |
92 | 选择想要执行的任务并对其单击以运行。请注意,如果未使用对所选任务适用的权限的帐户进行登录,则会失败。例如,如果在组织中没有管理员特权的帐户中运行某个特定的代码段(如获取所有租户组),则该操作会失败。或者,如果使用个人帐户进行登录并尝试获取登录用户的管理器,则该操作会失败。
93 |
94 | ## 参与
95 |
96 | 如果想要参与本示例,请参阅 [CONTRIBUTING.MD](/CONTRIBUTING.md)。
97 |
98 | 此项目已采用 [Microsoft 开放源代码行为准则](https://opensource.microsoft.com/codeofconduct/)。有关详细信息,请参阅[行为准则常见问题解答](https://opensource.microsoft.com/codeofconduct/faq/)。如有其他任何问题或意见,也可联系 [opencode@microsoft.com](mailto:opencode@microsoft.com)。
99 |
100 | ## 版权信息
101 |
102 | 版权所有 (c) 2016 Microsoft。保留所有权利。
103 |
--------------------------------------------------------------------------------
/README-Localized/README-zh-tw.md:
--------------------------------------------------------------------------------
1 | ---
2 | page_type: sample
3 | products:
4 | - office-365
5 | - office-outlook
6 | - ms-graph
7 | languages:
8 | - swift
9 | extensions:
10 | contentType: samples
11 | technologies:
12 | - Microsoft Graph
13 | services:
14 | - Office 365
15 | - Outlook
16 | - Groups
17 | platforms:
18 | - iOS
19 | createdDate: 5/26/2016 8:08:35 AM
20 | ---
21 | # Microsoft Graph iOS Swift 程式碼片段範例
22 |
23 | ## 目錄
24 |
25 | - [簡介](#introduction)
26 | - [必要條件](#prerequisites)
27 | - [註冊和設定應用程式](#register-and-configure-the-app)
28 | - [建置和偵錯](#build-and-debug)
29 | - [執行範例](#running-the-sample)
30 |
31 | ## 簡介
32 |
33 | 這個範例包含程式碼片段的儲存機制,顯示如何使用 Microsoft Graph SDK 來傳送電子郵件、管理群組,以及執行其他使用 Office 365 資料的活動。它會使用 [Microsoft Graph SDK for iOS](https://github.com/microsoftgraph/msgraph-sdk-ios),使用 Microsoft Graph 所傳回的資料。
34 |
35 | 這個儲存機制會示範如何在 iOS 應用程式中向 Microsoft Graph API 發出 HTTP 要求,以存取多個資源 (包括 Microsoft Azure Active Directory (AD) 和 Office 365 API)。
36 |
37 | 這些程式碼片段簡單且獨立,您可以適當地複製並貼到自己的程式碼,或使用它們做為資源來學習如何使用 Microsoft Graph SDK for iOS。
38 |
39 | **注意事項:** 請盡可能以「非工作」或測試帳戶來使用這個範例。範例不會一律清除您的信箱和行事曆中建立的物件。目前,您必須手動移除範例郵件及行事曆事件。另請注意取得和傳送訊息的程式碼片段,以及取得、建立、更新和刪除事件的程式碼片段不適用於所有個人帳戶。當這些帳戶升級為使用 v2 驗證端點時,這些作業最終可以運作。
40 |
41 | ## 必要條件
42 |
43 | 此範例需要下列項目:
44 |
45 | - [Xcode](https://developer.apple.com/xcode/downloads/)版本 10.2.1
46 | - 安裝 [CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html) 做為相依性管理員。
47 | - Microsoft 工作或個人電子郵件帳戶,例如 Office 365,或 outlook.com、hotmail.com 等等。您可以註冊 [Office 365 開發人員訂用帳戶](https://aka.ms/devprogramsignup),其中包含開始建置 Office 365 應用程式所需的資源。
48 |
49 | ## 註冊和設定應用程式
50 |
51 | 1. 開啟瀏覽器並瀏覽至[Azure Active Directory 管理中心](https://aad.portal.azure.com)並登入使用**個人帳戶**(也稱為:Microsoft 帳戶)或**公司或學校帳戶**。
52 |
53 | 1. 在左側導覽中選取 **Azure Active Directory**,然後在**管理**下選取**應用程式註冊**。
54 |
55 | 1. 選取 **新增註冊**。在**註冊應用程式**頁面上,如下所示設定數值。
56 |
57 | - 設定**名稱**到`迅速的程式碼片段範例`。
58 | - 在 **支援的帳戶類型**底下,選取 **任何組織目錄中的帳戶及個人的 Microsoft 帳戶**。
59 | - 在**重新導向 URI**,變更下拉式清單至**公用用戶端(行動裝置及電腦)**,並將值設定為`msauth.com.microsoft.Graph-iOS-Swift-Snippets://auth`。
60 |
61 | 1. 選擇**註冊**。在**快速的程式碼片段範例**頁面上,複製**應用程式(用戶端)識別碼**的值,儲存起來,在下一個步驟會需要它。
62 |
63 | ## 建置和偵錯
64 |
65 | 1. 複製此儲存機制
66 |
67 | 1. 開啟**終端機**瀏覽至專案的根目錄。執行下列命令以安裝相依性。
68 |
69 | ```Shell
70 | pod install
71 | ```
72 |
73 | 1. 在 Xcode 中開啟 **Graph-iOS-Swift-Snippets.xcworkspace**。
74 |
75 | 1. 開啟 **ApplicationConstants.swift**。用`ENTER_CLIENT_ID`取代註冊您的應用程式時所提供的應用程式識別碼。
76 |
77 | ```swift
78 | // You will set your application's clientId
79 | static let clientId = "ENTER_CLIENT_ID"
80 | ```
81 |
82 | 1. 執行範例。
83 |
84 | ## 執行範例
85 |
86 | 啟動時,應用程式會顯示一般使用者工作的清單。這些工作可以根據帳戶類型和權限層級執行,並且在註解中附註︰
87 |
88 | - 適用於工作或學校和個人帳戶的工作,例如取得和傳送電子郵件、建立檔案等等。
89 | - 只適用於工作或學校帳戶的工作,例如取得使用者的經理或帳戶相片。
90 | - 只適用於具有管理權限的工作或學校帳戶的工作,例如取得群組成員,或建立新的使用者帳戶。
91 |
92 | 選取您想要執行的工作,並且按一下它以執行。請注意,如果您登入沒有工作的適用權限的帳戶,您選取的工作就會失敗。例如,如果嘗試從組織中沒有系統管理權限的帳戶,執行特定的程式碼片段 (例如取得所有租用戶群組),則作業會失敗。或者,如果您登入個人帳戶,並且嘗試取得已登入使用者的主管,也會失敗。
93 |
94 | ## 參與
95 |
96 | 如果您想要參與這個範例,請參閱 [CONTRIBUTING.MD](/CONTRIBUTING.md)。
97 |
98 | 此專案已採用[Microsoft 開放原始碼管理辦法](https://opensource.microsoft.com/codeofconduct/)。如需詳細資訊,請參閱[管理辦法常見問題集](https://opensource.microsoft.com/codeofconduct/faq/),如果有其他問題或意見,請連絡 [opencode@microsoft.com](mailto:opencode@microsoft.com)。
99 |
100 | ## 著作權
101 |
102 | Copyright (c) 2016 Microsoft.著作權所有,並保留一切權利。
103 |
--------------------------------------------------------------------------------
/Graph-iOS-Swift-Snippets/Snippets.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 |
7 | import Foundation
8 | import MSGraphSDK
9 |
10 | // MARK: - Enum Result
11 | enum Result
12 | {
13 | case Success(displayText: String?)
14 | case SuccessDownloadImage(displayImage: UIImage?)
15 | case Failure(error: MSGraphError)
16 | }
17 |
18 | // MARK: - Protocol Snippet
19 | protocol Snippet
20 | {
21 | func execute(with completion: @escaping (_ result: Result) -> Void)
22 |
23 | var needAdminAccess: Bool { get }
24 | var name: String { get }
25 | }
26 |
27 | // MARK: - Snippet group
28 | struct SnippetSection
29 | {
30 | let name: String
31 | let snippets: [Snippet]
32 |
33 | var count: Int
34 | {
35 | get { return snippets.count }
36 | }
37 |
38 | subscript(index: Int) -> Snippet
39 | {
40 | get { return snippets[index] }
41 | }
42 | }
43 |
44 | // MARK: - Snippets
45 | struct Snippets
46 | {
47 | static var graphClient: MSGraphClient = {
48 | return MSGraphClient.defaultClient()
49 | }()
50 |
51 | let snippetSections: [SnippetSection]
52 |
53 | init(authenticationProvider: MSAuthenticationProvider)
54 | {
55 | let userArray = SnippetSection(name: "User",
56 | snippets: [
57 | GetMe(),
58 | GetUsers(),
59 | GetDrive(),
60 | GetEvents(),
61 | CreateEvent(),
62 | UpdateEvent(),
63 | DeleteEevnt(),
64 | GetMessages(),
65 | SendMessage(),
66 | SendMessageHTML(),
67 | GetUserFiles(),
68 | CreateTextFile(),
69 | CreateFolder(),
70 | UploadFile(),
71 | DownloadFile(),
72 | UpdateFile(),
73 | RenameFile(),
74 | DeleteFile(),
75 | GetManager(),
76 | GetDirects(),
77 | GetPhoto(),
78 | GetPhotoValue(),
79 | ])
80 |
81 | let groupsArray = SnippetSection(name: "Groups",
82 | snippets: [
83 | CreateUser(),
84 | GetUserGroups(),
85 | GetAllGroups(),
86 | GetSingleGroup(),
87 | GetMembers(),
88 | GetOwners(),
89 | CreateGroup(),
90 | UpdateGroup(),
91 | DeleteGroup()
92 | ])
93 |
94 | snippetSections = [userArray, groupsArray]
95 | MSGraphClient.setAuthenticationProvider(authenticationProvider)
96 | }
97 |
98 | var count: Int
99 | {
100 | get { return snippetSections.count }
101 | }
102 |
103 | subscript(index: Int) -> SnippetSection
104 | {
105 | get { return snippetSections[index] }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/README-Localized/README-ja-jp.md:
--------------------------------------------------------------------------------
1 | ---
2 | page_type: sample
3 | products:
4 | - office-365
5 | - office-outlook
6 | - ms-graph
7 | languages:
8 | - swift
9 | extensions:
10 | contentType: samples
11 | technologies:
12 | - Microsoft Graph
13 | services:
14 | - Office 365
15 | - Outlook
16 | - Groups
17 | platforms:
18 | - iOS
19 | createdDate: 5/26/2016 8:08:35 AM
20 | ---
21 | # Microsoft Graph iOS Swift スニペットのサンプル
22 |
23 | ## 目次
24 |
25 | - [はじめに](#introduction)
26 | - [前提条件](#prerequisites)
27 | - [アプリを登録して構成する](#register-and-configure-the-app)
28 | - [ビルドとデバッグ](#build-and-debug)
29 | - [サンプルの実行](#running-the-sample)
30 |
31 | ## はじめに
32 |
33 | このサンプルには、メールの送信、グループの管理、Office 365 データを使用した他のアクティビティの実行に Microsoft Graph SDK を使用する方法を示すコード スニペットのリポジトリが含まれています。[Microsoft Graph SDK for iOS](https://github.com/microsoftgraph/msgraph-sdk-ios) を使用して、Microsoft Graph が返すデータを操作します。
34 |
35 | このリポジトリでは、iOS アプリで Microsoft Graph API への HTTP 要求を実行して、Microsoft Azure Active Directory (AD) と Office 365 API などの複数のリソースにアクセスする方法を示します。
36 |
37 | これらのスニペットは、簡潔な自己完結型であり、必要に応じて、コピーして独自のコードに貼り付けたり、Microsoft Graph SDK for iOS の使用方法を学習するためのリソースとして使用したりすることができます。
38 |
39 | **注:** 可能であれば、"職場以外"のアカウントまたはテスト アカウントでこのサンプルを使用してください。サンプルでは、メールボックスと予定表で作成されたオブジェクトが常にクリーンアップされるとは限りません。現時点では、手動でサンプルのメールと予定表イベントを削除する必要があります。また、メッセージを送受信し、イベントを取得、作成、更新および削除するスニペットは、一部の個人用アカウントでは操作できないことにも注意してください。これらの操作は、それらのアカウントが更新されて v2 認証エンドポイントで操作できるようになったときに、最終的に機能するようになります。
40 |
41 | ## 前提条件
42 |
43 | このサンプルを実行するには次のものが必要です。
44 |
45 | - [Xcode](https://developer.apple.com/xcode/downloads/) バージョン 10.2.1
46 | - 依存関係マネージャーとしての [CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html) のインストール。
47 | - Office 365、outlook.com、hotmail.com などの、Microsoft の職場または個人用のメール アカウント。Office 365 アプリのビルドを開始するために必要なリソースを含む [Office 365 Developer サブスクリプション](https://aka.ms/devprogramsignup)にサインアップできます。
48 |
49 | ## アプリを登録して構成する
50 |
51 | 1. ブラウザーを開き、[Azure Active Directory 管理センター](https://aad.portal.azure.com)へ移動して、**個人用アカウント** (別名: Microsoft アカウント)、または**職場/学校アカウント**を使用してログインします。
52 |
53 | 1. 左側のナビゲーションで **\[Azure Active Directory]** を選択し、それから **\[管理]** で **\[アプリの登録]** を選択します。
54 |
55 | 1. **\[新規登録]** を選択します。**\[アプリケーションの登録]** ページで、次のように値を設定します。
56 |
57 | - **\[名前]** を `[Swift スニペットのサンプル]` に設定します。
58 | - **\[サポートされているアカウントの種類]** を **\[任意の組織のディレクトリ内のアカウントと個人用の Microsoft アカウント]** に設定します。
59 | - **\[リダイレクト URI]** で、ドロップ ダウンを **\[パブリック クライアント (モバイルとデスクトップ)]** に変更し、値を `msauth.com.microsoft.Graph-iOS-Swift-Snippets://auth` に設定します。
60 |
61 | 1. **\[登録]** を選択します。**\[Swift スニペットのサンプル]** ページで、**\[アプリケーション (クライアント) ID]** の値をコピーして保存し、次の手順に移ります。
62 |
63 | ## ビルドとデバッグ
64 |
65 | 1. このリポジトリの複製を作成する
66 |
67 | 1. **\[ターミナル]** を開いて、プロジェクトのルート フォルダーに移動します。次のコマンドを実行して、依存関係をインストールします。
68 |
69 | ```Shell
70 | pod install
71 | ```
72 |
73 | 1. Xcode で **Graph-iOS-Swift-Snippets.xcworkspace** を開きます。
74 |
75 | 1. **ApplicationConstants.swift** を開きます。`ENTER_CLIENT_ID` を、アプリを登録したときに取得したアプリケーション ID に置き換えます。
76 |
77 | ```swift
78 | // You will set your application's clientId
79 | static let clientId = "ENTER_CLIENT_ID"
80 | ```
81 |
82 | 1. サンプルを実行します。
83 |
84 | ## サンプルの実行
85 |
86 | 起動すると、共通のユーザー タスクの一覧がアプリに表示されます。これらのタスクは、アカウントの種類とアクセス許可のレベルに基づいて実行でき、コメントに記載されています:
87 |
88 | - メールの送受信、ファイルの作成など、職場または学校のアカウントおよび個人用アカウントの両方に適用可能なタスク。
89 | - ユーザーの上司またはアカウントの写真の取得など、職場または学校のアカウントにのみ適用可能なタスク。
90 | - グループ メンバーの取得または新しいユーザーの作成など、管理アクセス許可を持つ職場または学校のアカウントにのみ適用可能なタスク。
91 |
92 | 実行するタスクを選択し、それをクリックして実行します。選択したタスクに適用可能なアクセス許可のないアカウントでログインすると、タスクが失敗しますので注意してください。たとえば、組織内の管理権限のないアカウントからすべてのテナント グループを取得するなど、特定のスニペットを実行しようとすると、その操作は失敗します。または、個人用アカウントでログインしている場合にサインインしているユーザーの上司を取得しようとすると、失敗します。
93 |
94 | ## 投稿
95 |
96 | このサンプルに投稿する場合は、[CONTRIBUTING.MD](/CONTRIBUTING.md) を参照してください。
97 |
98 | このプロジェクトでは、[Microsoft オープン ソース倫理規定](https://opensource.microsoft.com/codeofconduct/)が採用されています。詳細については、「[倫理規定の FAQ](https://opensource.microsoft.com/codeofconduct/faq/)」を参照してください。また、その他の質問やコメントがあれば、[opencode@microsoft.com](mailto:opencode@microsoft.com) までお問い合わせください。
99 |
100 | ## 著作権
101 |
102 | Copyright (c) 2016 Microsoft.All rights reserved.
103 |
--------------------------------------------------------------------------------
/Graph-iOS-Swift-SnippetsTests/testAuthProvider.swift:
--------------------------------------------------------------------------------
1 | //
2 | // testAuthProvider.swift
3 | // Graph-iOS-Swift-Connect
4 | //
5 | // Created by Jason Kim on 6/23/16.
6 | // Copyright © 2016 Jason Kim. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @testable import Graph_iOS_Swift_Snippets
12 |
13 | class testAuthProvider: NSObject, MSAuthenticationProvider {
14 |
15 | var accessToken: String?
16 | var userEmail: String!
17 | var domainName: String!
18 |
19 | let contentType = "application/x-www-form-urlencoded"
20 | let grantType = "password"
21 | let tokenEndPoint = "https://login.microsoftonline.com/common/oauth2/token"
22 | let requestType = "POST"
23 | let resourceId = "https://graph.microsoft.com"
24 |
25 | let tokenType = "bearer"
26 | let apiHeaderAuthrization = "Authorization"
27 |
28 | override init() {
29 | super.init()
30 | let path = NSBundle(forClass: self.dynamicType).pathForResource("testUserArgs", ofType: "json")
31 |
32 | let jsonData = try! NSData(contentsOfFile: path!, options: .DataReadingMappedIfSafe)
33 | let jsonResult = try! NSJSONSerialization.JSONObjectWithData(jsonData, options: []) as! NSDictionary
34 |
35 | userEmail = jsonResult["test.username"] as! String
36 | domainName = userEmail.componentsSeparatedByString("@")[1]
37 | }
38 |
39 | @objc func appendAuthenticationHeaders(request: NSMutableURLRequest!, completion completionHandler: MSAuthenticationCompletion!) {
40 |
41 | if let _ = accessToken {
42 | let oauthAuthorizationHeader = String(format: "%@ %@", tokenType, accessToken!)
43 | request.setValue(oauthAuthorizationHeader, forHTTPHeaderField: self.apiHeaderAuthrization)
44 | completionHandler(request, nil)
45 | }
46 | else {
47 | let path = NSBundle(forClass: self.dynamicType).pathForResource("testUserArgs", ofType: "json")
48 |
49 | let jsonData = try! NSData(contentsOfFile: path!, options: .DataReadingMappedIfSafe)
50 | let jsonResult = try! NSJSONSerialization.JSONObjectWithData(jsonData, options: []) as! NSDictionary
51 |
52 | let username = jsonResult["test.username"] as! String
53 | let password = jsonResult["test.password"] as! String
54 | let clientId = jsonResult["test.clientId"] as! String
55 |
56 | userEmail = username
57 |
58 | let authRequest = NSMutableURLRequest()
59 | let bodyString = "grant_type=\(grantType)&resource=\(resourceId)&client_id=\(clientId)&username=\(username)&password=\(password)"
60 |
61 | authRequest.URL = NSURL(string: tokenEndPoint)
62 | authRequest.HTTPMethod = requestType
63 | authRequest.setValue(contentType, forHTTPHeaderField: "Content_Type")
64 | authRequest.HTTPBody = bodyString.dataUsingEncoding(NSUTF8StringEncoding)
65 |
66 | let session = NSURLSession.sharedSession()
67 | let task = session.dataTaskWithRequest(authRequest, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) in
68 |
69 | if let validData = data {
70 | let jsonDictionary = try! NSJSONSerialization.JSONObjectWithData(validData, options: .AllowFragments) as! NSDictionary
71 | if let accessTokenReturned = jsonDictionary["access_token"] {
72 | self.accessToken = accessTokenReturned as? String
73 | }
74 | else {
75 | self.accessToken = "WRONG_TOKEN"
76 | }
77 | }
78 |
79 | let oauthAuthorizationHeader = String(format: "%@ %@", self.tokenType, self.accessToken!)
80 | request.setValue(oauthAuthorizationHeader, forHTTPHeaderField: self.apiHeaderAuthrization)
81 | completionHandler(request, error)
82 | })
83 | task.resume()
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/Graph-iOS-Swift-Snippets/DetailViewController.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 |
7 | import UIKit
8 |
9 | class DetailViewController: UIViewController {
10 |
11 | @IBOutlet var activityIndicatorView: UIActivityIndicatorView!
12 | @IBOutlet var snippetNameLabel: UILabel!
13 | @IBOutlet var resultStackView: UIStackView!
14 | @IBOutlet var accessLevelLabel: UILabel!
15 |
16 | var snippet: Snippet?
17 | {
18 | didSet { configureView() }
19 | }
20 |
21 | override func viewDidLoad()
22 | {
23 | super.viewDidLoad()
24 | configureView()
25 | }
26 |
27 | override func viewDidAppear(_ animated: Bool)
28 | {
29 | super.viewDidAppear(animated)
30 |
31 | guard let _ = snippet else { return }
32 |
33 | executeSnippet()
34 | }
35 |
36 | // MARK: - Private
37 |
38 | private func executeSnippet()
39 | {
40 | guard let _ = snippet else { return }
41 |
42 | self.snippet!.execute { (result: Result) in
43 | switch result {
44 | case .Failure(let error):
45 | var displayText: String = "Failed\n\n"
46 | switch error {
47 | case .NSErrorType(let nsError):
48 | displayText = nsError.localizedDescription
49 |
50 | for (key, value) in nsError.userInfo.enumerated() {
51 | displayText += "\n\(key): \(value)"
52 | }
53 |
54 | break
55 | case.UnexpectecError(let errorString):
56 | displayText = errorString
57 | break
58 | }
59 |
60 | DispatchQueue.main.async {
61 | let result = UILabel()
62 | result.numberOfLines = 0
63 | result.text = displayText
64 |
65 | self.resultStackView.addArrangedSubview(result)
66 | self.accessLevelLabel.removeFromSuperview()
67 |
68 | self.hideActivityIndicator()
69 | }
70 |
71 | break
72 | case .Success(let displayText):
73 | if let text = displayText {
74 | DispatchQueue.main.async {
75 | let result = UILabel()
76 | result.numberOfLines = 0
77 | result.text = "Success\n\n\(text)"
78 |
79 | self.resultStackView.addArrangedSubview(result)
80 | self.hideActivityIndicator()
81 | }
82 | }
83 | break
84 |
85 | case .SuccessDownloadImage(let displayImage):
86 | DispatchQueue.main.async {
87 | let imageView = UIImageView(image: displayImage)
88 |
89 | self.resultStackView.addArrangedSubview(imageView)
90 | self.hideActivityIndicator()
91 | }
92 | break
93 | }
94 | }
95 | }
96 |
97 | private func hideActivityIndicator()
98 | {
99 | self.activityIndicatorView.stopAnimating()
100 |
101 | UIView.animate(withDuration: 0.35, animations: {
102 | self.activityIndicatorView.isHidden = true
103 | }) { (finished) in
104 | self.activityIndicatorView.stopAnimating()
105 | }
106 | }
107 |
108 | func configureView()
109 | {
110 | if let label = snippetNameLabel, let snippet = self.snippet {
111 | label.text = snippet.name
112 | accessLevelLabel.isHidden = !snippet.needAdminAccess
113 | }
114 | }
115 |
116 | func setResult(with string: String)
117 | {
118 | let label = UILabel()
119 | label.numberOfLines = 0
120 | label.text = string
121 |
122 | resultStackView.addArrangedSubview(label)
123 | }
124 | }
125 |
126 |
--------------------------------------------------------------------------------
/Graph-iOS-Swift-Snippets.xcodeproj/xcshareddata/xcschemes/Graph-iOS-Swift-Snippets.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
66 |
72 |
73 |
74 |
75 |
76 |
77 |
83 |
85 |
91 |
92 |
93 |
94 |
96 |
97 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/Graph-iOS-Swift-Snippets/ConnectViewController.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 |
7 | import UIKit
8 | import MSAL
9 |
10 | class ConnectViewController: UIViewController, UISplitViewControllerDelegate
11 | {
12 | @IBOutlet var activityIndicator: UIActivityIndicatorView!
13 | @IBOutlet var connectButton: UIButton!
14 |
15 | let authenticationProvider: AuthenticationProvider? = {
16 | guard let authorityUrl = URL(string: ApplicationConstants.authority) else { return nil }
17 |
18 | var authenticationProvider: AuthenticationProvider?
19 | do {
20 | let authority = try MSALAADAuthority(url: authorityUrl)
21 | let clientId = ApplicationConstants.clientId
22 | authenticationProvider = try AuthenticationProvider(clientId: clientId, authority: authority)
23 | } catch let error as NSError {
24 | print("Error: ", error)
25 | }
26 |
27 | return authenticationProvider
28 | }()
29 |
30 | // MARK: - Split view
31 |
32 | func splitViewController(splitViewController: UISplitViewController, collapseSecondaryViewController secondaryViewController:UIViewController, ontoPrimaryViewController primaryViewController:UIViewController) -> Bool
33 | {
34 | guard let secondaryAsNavController = secondaryViewController as? UINavigationController else { return false }
35 | guard let topAsDetailController = secondaryAsNavController.topViewController as? DetailViewController else { return false }
36 | if topAsDetailController.snippet == nil {
37 | // collapse when there is no snippet. i.e./ initial loading of the view controller.
38 | return true
39 | }
40 | return false
41 | }
42 |
43 |
44 | @IBAction func connectToGraph(_ sender: Any)
45 | {
46 | authenticate()
47 | }
48 |
49 | override func prepare(for segue: UIStoryboardSegue, sender: Any?)
50 | {
51 | if segue.identifier == "showSnippets" {
52 | let splitViewController = segue.destination as! UISplitViewController
53 |
54 | let navigationController = splitViewController.viewControllers[splitViewController.viewControllers.count-1] as! UINavigationController
55 | navigationController.topViewController!.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem
56 |
57 | let navController = splitViewController.viewControllers.first as! UINavigationController
58 | print(navController)
59 |
60 | let masterViewController = navController.topViewController as! MasterViewController
61 | masterViewController.authenticationProvider = self.authenticationProvider
62 |
63 | splitViewController.delegate = self
64 | }
65 | }
66 |
67 | // MARK: - Private
68 |
69 | private func authenticate()
70 | {
71 | guard let authenticationProvider = self.authenticationProvider else { return }
72 | let scopes = ApplicationConstants.scopes
73 |
74 | showLoadingView(show: true)
75 | authenticationProvider.acquireAuthToken(scopes: scopes) { (success, error) in
76 | self.showLoadingView(show: false)
77 |
78 | if success {
79 | DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
80 | self.performSegue(withIdentifier: "showSnippets", sender: nil)
81 | }
82 |
83 | return;
84 | }
85 |
86 | print("Error: ", error?.description ?? "nil error")
87 | self.showError(message: "Check print log for error details")
88 | }
89 | }
90 |
91 | private func showLoadingView(show: Bool)
92 | {
93 | if show {
94 | activityIndicator.startAnimating()
95 | connectButton.setTitle("Connecting...", for: .normal)
96 | connectButton.isEnabled = false
97 | } else {
98 | activityIndicator.stopAnimating()
99 | connectButton.setTitle("Connect", for: .normal)
100 | connectButton.isEnabled = true
101 | }
102 | }
103 |
104 | func showError(message: String)
105 | {
106 | DispatchQueue.main.async {
107 | let alertControl = UIAlertController(title: "Error", message: message, preferredStyle: .alert)
108 | alertControl.addAction(UIAlertAction(title: "Close", style: .default, handler: nil))
109 |
110 | self.present(alertControl, animated: true, completion: nil)
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Microsoft Graph iOS Swift Snippets Sample
2 |
3 | ## Table of contents
4 |
5 | - [Introduction](#introduction)
6 | - [Prerequisites](#prerequisites)
7 | - [Register and configure the app](#register-and-configure-the-app)
8 | - [Build and debug](#build-and-debug)
9 | - [Running the sample](#running-the-sample)
10 |
11 | ## Introduction
12 |
13 | This sample contains a repository of code snippets that show how to use the Microsoft Graph SDK to send email, manage groups, and perform other activities with Office 365 data. It uses the [Microsoft Graph SDK for iOS](https://github.com/microsoftgraph/msgraph-sdk-ios) to work with data returned by Microsoft Graph.
14 |
15 | This repository shows you how to access multiple resources, including Microsoft Azure Active Directory (AD) and the Office 365 APIs, by making HTTP requests to the Microsoft Graph API in an iOS app.
16 |
17 | These snippets are simple and self-contained, and you can copy and paste them into your own code, whenever appropriate, or use them as a resource for learning how to use the Microsoft Graph SDK for iOS.
18 |
19 | **Note:** If possible, please use this sample with a "non-work" or test account. The sample does not always clean up the created objects in your mailbox and calendar. At this time you'll have to manually remove sample mails and calendar events. Also note that the snippets that get and send messages and that get, create, update, and delete events won't work with all personal accounts. These operations will eventually work when those accounts are updated to work with the v2 authentication endpoint.
20 |
21 | ## Prerequisites
22 |
23 | This sample requires the following:
24 |
25 | - [Xcode](https://developer.apple.com/xcode/downloads/) version 10.2.1
26 | - Installation of [CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html) as a dependency manager.
27 | - A Microsoft work or personal email account such as Office 365, or outlook.com, hotmail.com, etc. You can sign up for [an Office 365 Developer subscription](https://aka.ms/devprogramsignup) that includes the resources that you need to start building Office 365 apps.
28 |
29 | ## Register and configure the app
30 |
31 | 1. Open a browser and navigate to the [Azure Active Directory admin center](https://aad.portal.azure.com) and login using a **personal account** (aka: Microsoft Account) or **Work or School Account**.
32 |
33 | 1. Select **Azure Active Directory** in the left-hand navigation, then select **App registrations** under **Manage**.
34 |
35 | 1. Select **New registration**. On the **Register an application** page, set the values as follows.
36 |
37 | - Set **Name** to `Swift Snippets Sample`.
38 | - Set **Supported account types** to **Accounts in any organizational directory and personal Microsoft accounts**.
39 | - Under **Redirect URI**, change the drop down to **Public client (mobile & desktop)**, and set the value to `msauth.com.microsoft.Graph-iOS-Swift-Snippets://auth`.
40 |
41 | 1. Choose **Register**. On the **Swift Snippets Sample** page, copy the value of the **Application (client) ID** and save it, you will need it in the next step.
42 |
43 | ## Build and debug
44 |
45 | 1. Clone this repository
46 |
47 | 1. Open **Terminal** and navigate to the root of the project. Run the following command to install dependencies.
48 |
49 | ```Shell
50 | pod install
51 | ```
52 |
53 | 1. Open **Graph-iOS-Swift-Snippets.xcworkspace** in Xcode.
54 |
55 | 1. Open **ApplicationConstants.swift**. Replace `ENTER_CLIENT_ID` with the application ID you got from registering your app.
56 |
57 | ```swift
58 | // You will set your application's clientId
59 | static let clientId = "ENTER_CLIENT_ID"
60 | ```
61 |
62 | 1. Run the sample.
63 |
64 | ## Running the sample
65 |
66 | When launched, the app displays a list of common user tasks. These tasks can be run based on account type and permission level, and are noted in comments:
67 |
68 | - Tasks that are applicable to both work or school and personal accounts, such as getting and sending email, creating files, etc.
69 | - Tasks that are only applicable to work or school accounts, such as getting a user's manager or account photo.
70 | - Tasks that are only applicable to a work or school account with administrative permissions, such as getting group members or creating new user accounts.
71 |
72 | Select the task that you want to perform and click on it to run. Be aware that if you log in with an account that doesn't have applicable permissions for the tasks you've selected they'll fail. For example if try to run a particular snippet, like get all tenant groups, from an account that doesn't not have admin privileges in the org the operation will fail. Or, if you log in with a personal account and attempt to get the manager of the signed in user, it will fail.
73 |
74 | ## Contributing
75 |
76 | If you'd like to contribute to this sample, see [CONTRIBUTING.MD](/CONTRIBUTING.md).
77 |
78 | 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.
79 |
80 | ## Copyright
81 |
82 | Copyright (c) 2016 Microsoft. All rights reserved.
83 |
--------------------------------------------------------------------------------
/Graph-iOS-Swift-Snippets/AuthenticationProvider.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 | import Foundation
7 | import MSAL
8 | import MSGraphSDK
9 |
10 | class AuthenticationProvider: NSObject, MSAuthenticationProvider
11 | {
12 | var accessToken: String?
13 | var account: MSALAccount?
14 | var msalClient: MSALPublicClientApplication
15 |
16 | init(clientId: String, authority: MSALAuthority) throws
17 | {
18 | let config = MSALPublicClientApplicationConfig(clientId: clientId)
19 | msalClient = try MSALPublicClientApplication(configuration: config)
20 | }
21 |
22 | func acquireAuthToken(scopes: [String], completion:@escaping (_ success:Bool, _ error: NSError?) -> Void)
23 | {
24 | var completionBlock: MSALCompletionBlock?
25 | completionBlock = { (result, error) in
26 |
27 | if let error = error as NSError?
28 | {
29 | if (error.domain == MSALErrorDomain)
30 | {
31 | let msalError = MSALError(rawValue: error.code)!
32 |
33 | switch msalError {
34 | case MSALError.interactionRequired:
35 | let interactiveParameters = MSALInteractiveTokenParameters(scopes: scopes)
36 | self.msalClient.acquireToken(with: interactiveParameters, completionBlock: completionBlock!)
37 |
38 | case MSALError.serverDeclinedScopes:
39 | var declinedScopes = [String]()
40 | if let ds = error.userInfo[MSALDeclinedScopesKey] as? Array { declinedScopes = ds }
41 | print("The following scopes were declined: ", declinedScopes)
42 |
43 | var grantedScopes = [String]()
44 | if let gs = error.userInfo[MSALGrantedScopesKey] as? Array { grantedScopes = gs }
45 | print("Trying to acquire a token with granted scopes: ", grantedScopes)
46 |
47 | self.acquireTokenSilent(scopes: grantedScopes, msalCompletionBlock: completionBlock!, completion: completion)
48 |
49 | case MSALError.internal:
50 |
51 | // Log the error, then inspect the MSALInternalErrorCodeKey
52 | // in the userInfo dictionary.
53 | // More detailed information about the specific error
54 | // under MSALInternalErrorCodeKey can be found in MSALInternalError enum.
55 | print("Failed with internal MSAL error ", error)
56 | default:
57 | print("Failed with unknown MSAL error ", error)
58 | }
59 | }
60 |
61 | completion(false, error)
62 |
63 | } else if let result = result {
64 | self.accessToken = result.accessToken
65 | self.account = result.account
66 | completion(true, nil)
67 |
68 | return
69 | } else {
70 | assert(false, "result and error should never be nil at the same time.")
71 | }
72 | }
73 |
74 | var accounts = [MSALAccount]()
75 | do {
76 | accounts = try msalClient.allAccounts()
77 | } catch let error as NSError {
78 | print("Error: ", error)
79 | }
80 |
81 | if let account = accounts.first {
82 | let silentParameters = MSALSilentTokenParameters(scopes: scopes, account: account)
83 | msalClient.acquireTokenSilent(with: silentParameters, completionBlock: completionBlock!)
84 | } else {
85 | let interactiveParameters = MSALInteractiveTokenParameters(scopes: scopes)
86 | msalClient.acquireToken(with: interactiveParameters, completionBlock: completionBlock!)
87 | }
88 | }
89 |
90 | func disconnect()
91 | {
92 | guard let account = self.account else { return }
93 |
94 | do {
95 | try msalClient.remove(account)
96 | } catch let error as NSError {
97 | print("Error: ", error)
98 | }
99 | }
100 |
101 | // MARK: - MSAuthenticationProvider
102 |
103 | func appendAuthenticationHeaders(_ request: NSMutableURLRequest!, completion completionHandler: MSAuthenticationCompletion!)
104 | {
105 | if let accessToken = self.accessToken {
106 | let header = "Bearer \(accessToken)"
107 | request.setValue(header, forHTTPHeaderField:"Authorization")
108 | }
109 |
110 | completionHandler(request, nil);
111 | }
112 |
113 | // MARK: - Private
114 |
115 | private func acquireTokenSilent(scopes: [String], msalCompletionBlock: @escaping MSALCompletionBlock, completion:@escaping (_ success:Bool, _ error: NSError?) -> Void)
116 | {
117 | var accounts = [MSALAccount]()
118 | do {
119 | accounts = try self.msalClient.allAccounts()
120 | } catch let error as NSError {
121 | print("Error: ", error)
122 | completion(false, error)
123 | return
124 | }
125 |
126 | if let account = accounts.first {
127 | let silentParameters = MSALSilentTokenParameters(scopes: scopes, account: account)
128 | self.msalClient.acquireTokenSilent(with: silentParameters, completionBlock: msalCompletionBlock)
129 | } else {
130 | completion(false, nil)
131 | }
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/README-Localized/README-pt-br.md:
--------------------------------------------------------------------------------
1 | ---
2 | page_type: sample
3 | products:
4 | - office-365
5 | - office-outlook
6 | - ms-graph
7 | languages:
8 | - swift
9 | extensions:
10 | contentType: samples
11 | technologies:
12 | - Microsoft Graph
13 | services:
14 | - Office 365
15 | - Outlook
16 | - Groups
17 | platforms:
18 | - iOS
19 | createdDate: 5/26/2016 8:08:35 AM
20 | ---
21 | # Exemplo de Trechos de Código do iOS Swift do Microsoft Graph
22 |
23 | ## Sumário
24 |
25 | - [Introdução](#introduction)
26 | - [Pré-requisitos](#prerequisites)
27 | - [Registrar e configurar o aplicativo](#register-and-configure-the-app)
28 | - [Criar e depurar](#build-and-debug)
29 | - [Execução do exemplo](#running-the-sample)
30 |
31 | ## Introdução
32 |
33 | Este exemplo contém um repositório de trechos de código que mostram como usar o SDK do Microsoft Graph SDK para enviar emails, gerenciar grupos e realizar outras atividades com os dados do Office 365. Ele usa o [SDK do Microsoft Graph para iOS](https://github.com/microsoftgraph/msgraph-sdk-ios) para trabalhar com dados retornados pelo Microsoft Graph.
34 |
35 | Este repositório mostra como acessar vários recursos, incluindo o Microsoft Azure Active Directory (AD) e APIs do Office 365, fazendo solicitações HTTP para a API do Microsoft Graph em um aplicativo iOS.
36 |
37 | Esses trechos são simples e autocontidos e você pode copiá-los e colá-los em seu próprio código, quando apropriado, ou usá-los como um recurso para aprender a usar o SDK do Microsoft Graph para iOS.
38 |
39 | **Observação:** Se possível, use este exemplo com uma conta "não comercial" ou de teste. O exemplo nem sempre limpa os objetos criados em sua caixa de correio e calendário. Neste momento, você terá que remover manualmente os exemplos de correios e eventos do calendário. Observe também que os trechos de código que recebem e enviam mensagens e que recebem, criam, atualizam e excluem eventos não funcionarão com todas as contas pessoais. Essas operações eventualmente funcionarão quando essas contas forem atualizadas para funcionar com o ponto de extremidade de autenticação v2.
40 |
41 | ## Pré-requisitos
42 |
43 | Esse exemplo requer o seguinte:
44 |
45 | - [Xcode](https://developer.apple.com/xcode/downloads/) versão 10.2.1
46 | - A instalação de [CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html) como um gerenciador de dependências.
47 | - Uma conta de email comercial ou pessoal da Microsoft como o Office 365, ou outlook.com, hotmail.com, etc. Inscreva-se para uma [Assinatura de Desenvolvedor do Office 365](https://aka.ms/devprogramsignup), que inclui os recursos necessários para começar a criação de aplicativos do Office 365.
48 |
49 | ## Registrar e configurar o aplicativo
50 |
51 | 1. Abra um navegador e navegue até o [centro de administração do Azure Active Directory](https://aad.portal.azure.com) e faça logon usando uma **conta pessoal** (também conhecida como: Conta da Microsoft) **Conta Corporativa ou de Estudante**.
52 |
53 | 1. Selecione **Azure Active Directory** na navegação à esquerda e, em seguida, selecione **Registros de aplicativos** em **Gerenciar**.
54 |
55 | 1. Selecione **Novo registro**. Na página **Registrar um aplicativo**, defina os valores da seguinte forma.
56 |
57 | - Defina o **Nome** para `Exemplo de Trechos Swift`.
58 | - Defina **Tipos de contas com suporte** para **Contas em qualquer diretório organizacional e contas pessoais da Microsoft**.
59 | - Em URI de Redirecionamento, altere a lista suspensa para Cliente público (celular & desktop), e defina o valor como `msauth.com.microsoft.Graph-iOS-Swift-Snippets://auth`.
60 |
61 | 1. Escolha **Registrar**. Na página **Exemplo de Trechos Swift**, copie o valor da **ID do aplicativo (cliente)** e salve-o, você precisará dele na próxima etapa.
62 |
63 | ## Criar e depurar
64 |
65 | 1. Clonar este repositório
66 |
67 | 1. Abra o **Terminal** e navegue até a raiz do projeto. Execute o seguinte comando para instalar as dependências.
68 |
69 | ```Shell
70 | pod install
71 | ```
72 |
73 | 1. Abra **Graph-Ios-Swift-Snippets. xcworkspace** no Xcode.
74 |
75 | 1. Abra **ApplicationConstants.swift**. Substitua `ENTER_CLIENT_ID` pela ID do aplicativo obtida do registro de seu aplicativo.
76 |
77 | ```swift
78 | // You will set your application's clientId
79 | static let clientId = "ENTER_CLIENT_ID"
80 | ```
81 |
82 | 1. Execute o exemplo.
83 |
84 | ## Execução do exemplo
85 |
86 | Após ser iniciado, o aplicativo exibe uma lista de tarefas comuns de usuários. Essas tarefas podem ser executadas com base no nível de permissão e de tipo de conta e trazem uma anotação nos comentários:
87 |
88 | - Tarefas que são aplicáveis a contas comerciais ou escolares e contas pessoais, como receber e enviar emails, criar arquivos, etc.
89 | - Tarefas que só são aplicáveis a contas comerciais ou escolares, como receber a foto da conta e o gerenciador do usuário.
90 | - Tarefas que só são aplicáveis a contas comerciais ou escolares com permissões administrativas, como receber membros do grupo ou criar novas contas de usuário.
91 |
92 | Escolha a tarefa que você deseja realizar e clique nela para executar. Lembre-se de que se você fizer logon com uma conta que não tem permissões aplicáveis para as tarefas selecionadas, elas falharão. Por exemplo, se você tentar executar um determinado trecho de código, como obter todos os grupos de um locatário, de uma conta que não tem privilégios de administrador na organização, a operação falhará. Ou, se você entrar com uma conta pessoal do e tentar obter o gerenciador do usuário conectado, ele falhará.
93 |
94 | ## Colaboração
95 |
96 | Se quiser contribuir para esse exemplo, confira [CONTRIBUTING.MD](/CONTRIBUTING.md).
97 |
98 | Este projeto adotou o [Código de Conduta de Código Aberto da Microsoft](https://opensource.microsoft.com/codeofconduct/). Para saber mais, confira as [Perguntas frequentes sobre o Código de Conduta](https://opensource.microsoft.com/codeofconduct/faq/) ou entre em contato pelo [opencode@microsoft.com](mailto:opencode@microsoft.com) se tiver outras dúvidas ou comentários.
99 |
100 | ## Direitos autorais
101 |
102 | Copyright © 2016 Microsoft. Todos os direitos reservados.
103 |
--------------------------------------------------------------------------------
/README-Localized/README-es-es.md:
--------------------------------------------------------------------------------
1 | ---
2 | page_type: sample
3 | products:
4 | - office-365
5 | - office-outlook
6 | - ms-graph
7 | languages:
8 | - swift
9 | extensions:
10 | contentType: samples
11 | technologies:
12 | - Microsoft Graph
13 | services:
14 | - Office 365
15 | - Outlook
16 | - Groups
17 | platforms:
18 | - iOS
19 | createdDate: 5/26/2016 8:08:35 AM
20 | ---
21 | # Ejemplo de fragmentos de código de muestra de iOS en Swift de Microsoft Graph
22 |
23 | ## Tabla de contenido
24 |
25 | - [Introducción](#introduction)
26 | - [Requisitos previos](#prerequisites)
27 | - [Registrar y configurar la aplicación](#register-and-configure-the-app)
28 | - [Compilar y depurar](#build-and-debug)
29 | - [Ejecución del ejemplo](#running-the-sample)
30 |
31 | ## Introducción
32 |
33 | Este ejemplo contiene un repositorio de fragmentos de código que muestran cómo usar el SDK de Microsoft Graph para enviar correos electrónicos, administrar grupos y realizar otras actividades con los datos de Office 365. Usa el [SDK de Microsoft Graph para iOS](https://github.com/microsoftgraph/msgraph-sdk-ios) para trabajar con los datos devueltos por Microsoft Graph.
34 |
35 | Este repositorio muestra cómo tener acceso a varios recursos, incluidos Microsoft Azure Active Directory (AD) y las API de Office 365, realizando solicitudes HTTP a la API de Microsoft Graph en una aplicación de iOS.
36 |
37 | Estos fragmentos de código son simples e independientes, y puede copiarlos y pegarlos en su propio código, cuando sea apropiado, o usarlos como un recurso para aprender a usar el SDK de Microsoft Graph para iOS.
38 |
39 | **Nota:** Si es posible, use este ejemplo con una cuenta de prueba o "no profesional". El ejemplo no siempre limpia los objetos creados en el buzón de correo y el calendario. En este momento, tendrá que eliminar manualmente los eventos del calendario y los correos del ejemplo. Tenga en cuenta que los fragmentos de código que reciben y envían mensajes, y que obtienen, crean, actualizan y eliminan eventos no funcionarán con todas las cuentas personales. Estas operaciones funcionarán finalmente cuando esas cuentas se actualicen para su funcionamiento con el modelo de autenticación v2.
40 |
41 | ## Requisitos previos
42 |
43 | Este ejemplo necesita lo siguiente:
44 |
45 | - La versión 10.2.1 de [Xcode](https://developer.apple.com/xcode/downloads/)
46 | - La instalación de [CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html) como administrador de dependencias.
47 | - Una cuenta de correo electrónico personal o profesional de Microsoft como Office 365, outlook.com, hotmail.com, etc. Puede realizar [una suscripción a Office 365 Developer](https://aka.ms/devprogramsignup) que incluye los recursos que necesita para comenzar a crear aplicaciones de Office 365.
48 |
49 | ## Registrar y configurar la aplicación
50 |
51 | 1. Abra un explorador y vaya al [Centro de administración de Azure Active Directory](https://aad.portal.azure.com) e inicie sesión con una **cuenta personal** (también conocida como: una cuenta de Microsoft) o una **cuenta profesional o educativa**.
52 |
53 | 1. Seleccione **Azure Active Directory** en el panel de navegación izquierdo y, después, **Registros de aplicaciones** en **Administrar**.
54 |
55 | 1. Seleccione **Nuevo registro**. En la página **Registrar una aplicación**, establezca los valores siguientes.
56 |
57 | - Establezca el **Nombre** en `Ejemplo de fragmentos de código de Swift`.
58 | - Establezca **Tipos de cuenta admitidos** en **Cuentas en cualquier directorio de organización y cuentas personales de Microsoft**.
59 | - En **URI de redirección**, cambie la lista desplegable a **Cliente público (móvil y escritorio)** y establezca el valor en `msauth.com.microsoft.Graph-iOS-Swift-Snippets://auth`.
60 |
61 | 1. Elija **Registrar**. En la página **Ejemplo de fragmentos de código de Swift**, copie el valor del **Id. de aplicación (cliente)** y guárdelo. Lo necesitará en el paso siguiente.
62 |
63 | ## Compilar y depurar
64 |
65 | 1. Clone este repositorio.
66 |
67 | 1. Abra el **Terminal** y desplácese hasta la raíz del proyecto. Ejecute el siguiente comando para instalar dependencias.
68 |
69 | ```Shell
70 | pod install
71 | ```
72 |
73 | 1. Abra **Graph-iOS-Swift-Snippets.xcworkspace** en Xcode.
74 |
75 | 1. Abra **ApplicationConstants.swift**. Reemplace `ESCRIBIR_ID_CLIENTE` por el id. de la aplicación que obtuvo al registrar la aplicación.
76 |
77 | ```swift
78 | // You will set your application's clientId
79 | static let clientId = "ENTER_CLIENT_ID"
80 | ```
81 |
82 | 1. Ejecute el ejemplo.
83 |
84 | ## Ejecución del ejemplo
85 |
86 | Al iniciarse, la aplicación muestra una lista de tareas de usuario comunes. Estas tareas se pueden ejecutar basándose en el tipo de cuenta y nivel de permiso, y están marcadas en comentarios:
87 |
88 | - Tareas que son aplicables a cuentas profesionales, educativas y personales, como recibir y enviar correo electrónico, crear archivos, etc.
89 | - Tareas que solamente son aplicables a cuentas profesionales o educativas, como obtener fotos de administrador o de la cuenta de un usuario.
90 | - Tareas que solo son aplicables a una cuenta profesional o educativa con permisos administrativos, como obtener miembros del grupo o crear nuevas cuentas de usuario.
91 |
92 | Seleccione la tarea que desea realizar y haga clic en ella para ejecutarla. Tenga en cuenta que, si inicia una sesión con una cuenta que no tiene permisos aplicables para las tareas que ha seleccionado, no se realizarán correctamente. Por ejemplo, si intenta ejecutar un fragmento de código determinado, como obtener todos los grupos del inquilino a partir de una cuenta que no tiene privilegios de administrador en la organización, se producirá un error en la operación. Si inicia una sesión con una cuenta personal e intenta obtener el administrador del usuario con la sesión iniciada, se producirá un error.
93 |
94 | ## Colaboradores
95 |
96 | Si le gustaría contribuir a este ejemplo, vea [CONTRIBUTING.MD](/CONTRIBUTING.md).
97 |
98 | Este proyecto ha adoptado el [Código de conducta de código abierto de Microsoft](https://opensource.microsoft.com/codeofconduct/). Para obtener más información, vea [Preguntas frecuentes sobre el código de conducta](https://opensource.microsoft.com/codeofconduct/faq/) o póngase en contacto con [opencode@microsoft.com](mailto:opencode@microsoft.com) si tiene otras preguntas o comentarios.
99 |
100 | ## Copyright
101 |
102 | Copyright (c) 2016 Microsoft. Todos los derechos reservados.
103 |
--------------------------------------------------------------------------------
/README-Localized/README-ru-ru.md:
--------------------------------------------------------------------------------
1 | ---
2 | page_type: sample
3 | products:
4 | - office-365
5 | - office-outlook
6 | - ms-graph
7 | languages:
8 | - swift
9 | extensions:
10 | contentType: samples
11 | technologies:
12 | - Microsoft Graph
13 | services:
14 | - Office 365
15 | - Outlook
16 | - Groups
17 | platforms:
18 | - iOS
19 | createdDate: 5/26/2016 8:08:35 AM
20 | ---
21 | # Пример фрагментов кода Microsoft Graph на Swift для iOS
22 |
23 | ## Содержание
24 |
25 | - [Введение](#introduction)
26 | - [Предварительные требования](#prerequisites)
27 | - [Регистрация и настройка приложения](#register-and-configure-the-app)
28 | - [Сборка и отладка](#build-and-debug)
29 | - [Запуск приложения](#running-the-sample)
30 |
31 | ## Введение
32 |
33 | Этот пример содержит репозиторий фрагментов кода, в которых показано, как использовать пакет SDK Microsoft Graph, чтобы отправлять электронные сообщения, управлять группами и выполнять другие действия с данными Office 365. Для работы с данными, возвращаемыми Microsoft Graph, используется [пакет SDK Microsoft Graph для iOS](https://github.com/microsoftgraph/msgraph-sdk-ios).
34 |
35 | Этот репозиторий показывает, как получить доступ к нескольким ресурсам, в том числе Microsoft Azure Active Directory (AD) и API Office 365, совершая HTTP-запросы в API Microsoft Graph в приложении iOS.
36 |
37 | Эти фрагменты простые и автономные. Вы можете копировать их в свой код или брать их за основу при изучении пакета SDK Microsoft Graph для iOS.
38 |
39 | **Примечание.** Если возможно, используйте этот пример с "нерабочей" или тестовой учетной записью. Если вы используете пример, созданные объекты в почтовом ящике и календаре не всегда очищаются. В настоящее время вам необходимо вручную удалить примеры сообщений и событий календаря. Обратите внимание, что фрагменты кода, которые используются для получения и отправки сообщений, а также получения, создания, обновления и удаления событий, работают не со всеми личными учетными записями. Настоящие операции будут поддерживаться в полном объеме, когда эти учетные записи будут обновлены для работы с конечной точкой проверки подлинности версии 2.
40 |
41 | ## Необходимые компоненты
42 |
43 | Для этого примера требуются приведенные ниже компоненты.
44 |
45 | - [Xcode](https://developer.apple.com/xcode/downloads/) версии 10.2.1.
46 | - Установка [CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html) в качестве диспетчера зависимостей.
47 | - Рабочая или личная учетная запись Майкрософт, например Office 365, outlook.com или hotmail.com. Вы можете [подписаться на план Office 365 для разработчиков](https://aka.ms/devprogramsignup), который включает ресурсы, необходимые для создания приложений Office 365.
48 |
49 | ## Регистрация и настройка приложения
50 |
51 | 1. Откройте браузер, перейдите в [Центр администрирования Azure Active Directory](https://aad.portal.azure.com) и войдите с помощью **личной учетной записи** (т. е. учетной записи Майкрософт) или **рабочей или учебной учетной записи**.
52 |
53 | 1. Выберите **Azure Active Directory** на панели навигации слева, затем выберите **Регистрация приложения** в разделе **Управление**.
54 |
55 | 1. Выберите **Новая регистрация**. На странице **Регистрация приложения** задайте необходимые значения следующим образом.
56 |
57 | - Задайте для параметра **Имя** значение `Swift Snippets Sample`.
58 | - Задайте для параметра **Поддерживаемые типы учетных записей** значение **Учетные записи в любом каталоге организации и личные учетные записи Майкрософт**.
59 | - В разделе **URI перенаправления** выберите в раскрывающемся списке **Общедоступный клиент (для мобильных и классических приложений)** и задайте значение `msauth.com.microsoft.Graph-iOS-Swift-Snippets://auth`.
60 |
61 | 1. Нажмите кнопку **Зарегистрировать**. На странице **Пример фрагментов кода на Swift** скопируйте значение **Идентификатор приложения (клиента)** и сохраните его — оно потребуется на следующем шаге.
62 |
63 | ## Сборка и отладка
64 |
65 | 1. Клонируйте этот репозиторий
66 |
67 | 1. Откройте раздел **Терминал** и перейдите к корневой папке проекта. Чтобы установить зависимости, выполните указанную ниже команду.
68 |
69 | ```Shell
70 | pod install
71 | ```
72 |
73 | 1. Откройте **Graph-iOS-Swift-Snippets.xcworkspace** в Xcode.
74 |
75 | 1. Откройте файл **ApplicationConstants.swift**. Замените `ENTER_CLIENT_ID` на идентификатор приложения, полученный при регистрации приложения.
76 |
77 | ```swift
78 | // You will set your application's clientId
79 | static let clientId = "ENTER_CLIENT_ID"
80 | ```
81 |
82 | 1. Запустите пример.
83 |
84 | ## Запуск приложения
85 |
86 | Когда вы запустите приложение, в нем появится список типичных задач. Доступные задачи будут зависеть от типа учетной записи и уровня разрешений и отражены в примечаниях:
87 |
88 | - Задачи, доступные для рабочих, учебных и личных учетных записей, например получение и отправка электронной почты, создание файлов и т. д.
89 | - Задачи, доступные только для рабочих или учебных учетных записей, например получение фотографии учетной записи или сведений о руководителе пользователя.
90 | - Задачи, доступные только для рабочей или учебной учетной записи с административными разрешениями, например получение сведений о членах группы или создание учетных записей пользователей.
91 |
92 | Выберите задачу, которую необходимо выполнить, и щелчком запустите ее. Обратите внимание, что при входе в систему с помощью учетной записи, не имеющей соответствующих разрешений для выбранных задач, последние невозможно выполнить. Например, если вы попытаетесь выполнить определенный фрагмент кода (например, получить все клиентские группы) из учетной записи без прав администратора в организации, операция завершится ошибкой. Если вы войдете в систему с помощью личной учетной записи, вам не удастся получить сведения о руководителе пользователя, который вошел в систему.
93 |
94 | ## Участие
95 |
96 | Если вы хотите добавить код в этот пример, просмотрите статью [CONTRIBUTING.MD](/CONTRIBUTING.md).
97 |
98 | Этот проект соответствует [правилам поведения Майкрософт, касающимся обращения с открытым кодом](https://opensource.microsoft.com/codeofconduct/). Дополнительные сведения см. в разделе [Часто задаваемые вопросы о правилах поведения](https://opensource.microsoft.com/codeofconduct/faq/). Если у вас возникли вопросы или замечания, напишите нам по адресу [opencode@microsoft.com](mailto:opencode@microsoft.com).
99 |
100 | ## Авторское право
101 |
102 | (c) Корпорация Майкрософт (Microsoft Corporation), 2016. Все права защищены.
103 |
--------------------------------------------------------------------------------
/README-Localized/README-de-de.md:
--------------------------------------------------------------------------------
1 | ---
2 | page_type: sample
3 | products:
4 | - office-365
5 | - office-outlook
6 | - ms-graph
7 | languages:
8 | - swift
9 | extensions:
10 | contentType: samples
11 | technologies:
12 | - Microsoft Graph
13 | services:
14 | - Office 365
15 | - Outlook
16 | - Groups
17 | platforms:
18 | - iOS
19 | createdDate: 5/26/2016 8:08:35 AM
20 | ---
21 | # Beispiel für iOS-Swift-Codeausschnitte für Microsoft Graph
22 |
23 | ## Inhaltsverzeichnis
24 |
25 | - [Einführung](#introduction)
26 | - [Voraussetzungen](#prerequisites)
27 | - [Registrieren und Konfigurieren der App](#register-and-configure-the-app)
28 | - [Erstellen und Debuggen](#build-and-debug)
29 | - [Ausführen des Beispiels](#running-the-sample)
30 |
31 | ## Einführung
32 |
33 | Dieses Beispiel enthält ein Repository von Codeausschnitten, die zeigen, wie das Microsoft Graph-SDK zum Senden von E-Mails, Verwalten von Gruppen und Ausführen anderer Aktivitäten mit Office 365-Daten verwendet wird. Es verwendet das [Microsoft Graph-SDK für iOS](https://github.com/microsoftgraph/msgraph-sdk-ios), um mit Daten zu arbeiten, die von Microsoft Graph zurückgegeben werden.
34 |
35 | In diesem Repository wird gezeigt, wie Sie auf mehrere Ressourcen, einschließlich Microsoft Azure Active Directory (AD) und die Office 365-APIs, zugreifen, indem Sie HTTP-Anforderungen an die Microsoft Graph-API in einer iOS-App ausführen.
36 |
37 | Diese Ausschnitte sind einfach und eigenständig, und Sie können sie ggf. in Ihren eigenen Code kopieren und einfügen oder als Ressource verwenden, um zu lernen, wie das Microsoft Graph-SDK für iOS verwendet wird.
38 |
39 | **Hinweis:** Verwenden Sie dieses Beispiel, wenn möglich, mit einem persönlichen Konto oder einem Testkonto. Das Beispiel bereinigt nicht immer die erstellten Objekte in Ihrem Postfach und Kalender. Derzeit müssen Sie Beispiel-E-Mails und -Kalenderereignisse manuell entfernen. Beachten Sie auch, dass die Codeausschnitte, die Nachrichten abrufen und senden und Ereignisse abrufen, erstellen, aktualisieren und löschen, nicht mit allen persönlichen Konten funktionieren. Diese Vorgänge funktionieren dann, wenn diese Konten so aktualisiert werden, dass sie mit dem v2-Authentifizierungsendpunkt arbeiten.
40 |
41 | ## Anforderungen
42 |
43 | Für dieses Beispiel ist Folgendes erforderlich:
44 |
45 | - [Xcode](https://developer.apple.com/xcode/downloads/), Version 10.2.1
46 | - Installation von [CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html) als ein Abhängigkeits-Manager.
47 | - Ein geschäftliches oder persönliches Microsoft-E-Mail-Konto, z. B. Office 365 oder outlook.com, hotmail.com usw. Sie können sich für ein [Office 365-Entwicklerabonnement](https://aka.ms/devprogramsignup) registrieren. Dieses umfasst die Ressourcen, die Sie zum Erstellen von Office 365-Apps benötigen.
48 |
49 | ## Registrieren und Konfigurieren der App
50 |
51 | 1. Öffnen Sie einen Browser, und navigieren Sie zum [Azure Active Directory Admin Center](https://aad.portal.azure.com). Melden Sie sich mit einem **persönlichen Konto** (auch: Microsoft-Konto) bzw. einem **Geschäfts-, Schul- oder Unikonto** an.
52 |
53 | 1. Wählen Sie in der linken Navigationsleiste **Azure Active Directory** aus, und wählen Sie dann **App-Registrierungen** unter **Verwalten** aus.
54 |
55 | 1. Wählen Sie **Neue Registrierungen** aus. Legen Sie auf der Seite **Anwendung registrieren** die Werte wie folgt fest.
56 |
57 | - Legen Sie **Name** auf `Swift-Codeausschnittbeispiel` fest.
58 | - Legen Sie **Unterstützte Kontotypen** auf **Konten in allen Organisationsverzeichnissen und persönliche Microsoft-Konten** fest.
59 | - Ändern Sie unter **Umleitungs-URI** die Dropdownliste auf **Öffentlicher Client (mobil & Desktop)**, und legen Sie den Wert auf `msauth.com.microsoft.Graph-iOS-Swift-Snippets://auth` fest.
60 |
61 | 1. Wählen Sie **Registrieren** aus. Kopieren Sie auf der Seite **Swift-Codeausschnittbeispiel** den Wert von **Anwendungs-ID (Client-ID)**, und speichern Sie ihn. Sie benötigen ihn im nächsten Schritt.
62 |
63 | ## Erstellen und Debuggen
64 |
65 | 1. Klonen dieses Repositorys
66 |
67 | 1. Öffnen Sie ein **Terminal**, und navigieren Sie zum Stamm des Projekts. Führen Sie den folgenden Befehl aus, um Abhängigkeiten zu installieren.
68 |
69 | ```Shell
70 | pod install
71 | ```
72 |
73 | 1. Öffnen Sie **Graph-iOS-Swift-Snippets.xcworkspace** in Xcode.
74 |
75 | 1. Öffnen **Sie ApplicationConstants.swift**. Ersetzen Sie `ENTER_CLIENT_ID` durch die Anwendungs-ID, die Sie durch die Registrierung Ihrer APP erhalten haben.
76 |
77 | ```swift
78 | // You will set your application's clientId
79 | static let clientId = "ENTER_CLIENT_ID"
80 | ```
81 |
82 | 1. Führen Sie das Beispiel aus.
83 |
84 | ## Ausführen des Beispiels
85 |
86 | Nach dem Start wird in der App eine Liste allgemeiner Benutzeraufgaben angezeigt. Diese Aufgaben können basierend auf Kontotyp und Berechtigungsstufe ausgeführt werden und werden in Kommentaren notiert.
87 |
88 | - Aufgaben, die sowohl für Geschäfts- oder Schulkonten als auch für persönliche Konten gelten, z. B. das Abrufen und Seden von E-Mails, das Erstellen von Dateien usw.
89 | - Aufgaben, die nur für Geschäfts- oder Schulkonten gelten, z. B. das Abrufen eines Vorgesetzten eines Benutzers oder eines Kontofotos.
90 | - Aufgaben, die nur für Geschäfts- oder Schulkonten mit Administratorberechtigungen gelten, z. B. das Abrufen von Gruppenmitgliedern oder das Erstellen neuer Benutzerkonten.
91 |
92 | Wählen Sie die Aufgabe aus, die Sie ausführen möchten, und klicken Sie darauf, um sie auszuführen. Beachten Sie, dass die ausgewählten Aufgaben fehlschlagen, wenn Sie sich mit einem Konto anmelden, das nicht über die entsprechenden Berechtigungen für die Aufgaben verfügt. Wenn Sie beispielsweise versuchen, einen bestimmten Ausschnitt, z. B. das Abrufen aller Mandantengruppen, auf einem Konto auszuführen, das nicht über Administratorberechtigungen in der Organisation verfügt, schlägt der Vorgang fehl. Oder wenn Sie sich mit einem persönlichen Konto anmelden und versuchen, den Vorgesetzten des angemeldeten Benutzers abzurufen, schlägt dieser Vorgang fehl.
93 |
94 | ## Mitwirkung
95 |
96 | Wenn Sie einen Beitrag zu diesem Beispiel leisten möchten, finden Sie unter [CONTRIBUTING.MD](/CONTRIBUTING.md) weitere Informationen.
97 |
98 | In diesem Projekt wurden die [Microsoft Open Source-Verhaltensregeln](https://opensource.microsoft.com/codeofconduct/) übernommen. Weitere Informationen finden Sie unter [Häufig gestellte Fragen zu Verhaltensregeln](https://opensource.microsoft.com/codeofconduct/faq/), oder richten Sie Ihre Fragen oder Kommentare an [opencode@microsoft.com](mailto:opencode@microsoft.com).
99 |
100 | ## Copyright
101 |
102 | Copyright (c) 2016 Microsoft. Alle Rechte vorbehalten.
103 |
--------------------------------------------------------------------------------
/README-Localized/README-fr-fr.md:
--------------------------------------------------------------------------------
1 | ---
2 | page_type: sample
3 | products:
4 | - office-365
5 | - office-outlook
6 | - ms-graph
7 | languages:
8 | - swift
9 | extensions:
10 | contentType: samples
11 | technologies:
12 | - Microsoft Graph
13 | services:
14 | - Office 365
15 | - Outlook
16 | - Groups
17 | platforms:
18 | - iOS
19 | createdDate: 5/26/2016 8:08:35 AM
20 | ---
21 | # Exemple d’extraits de code Microsoft Graph iOS Swift
22 |
23 | ## Table des matières
24 |
25 | - [Introduction](#introduction)
26 | - [Conditions préalables](#prerequisites)
27 | - [Enregistrement et configuration de l’application](#register-and-configure-the-app)
28 | - [Création et débogage](#build-and-debug)
29 | - [Exécution de l’exemple](#running-the-sample)
30 |
31 | ## Introduction
32 |
33 | Cet exemple contient un référentiel des extraits de code qui illustrent l’utilisation du kit de développement Microsoft Graph pour envoyer des messages électroniques, gérer les groupes et effectuer d’autres activités avec les données d’Office 365. Il utilise le [kit de développement logiciel Microsoft Graph pour iOS](https://github.com/microsoftgraph/msgraph-sdk-ios) pour exploiter les données renvoyées par Microsoft Graph.
34 |
35 | Ce référentiel vous montre comment accéder à plusieurs ressources, notamment Microsoft Azure Active Directory (AD) et les API d’Office 365, en envoyant des requêtes HTTP à l’API Microsoft Graph dans une application iOS.
36 |
37 | Ces extraits sont simples et autonomes, et vous pouvez les copier-coller dans votre propre code, le cas échéant, ou les utiliser comme ressource d’apprentissage sur l’utilisation du kit de développement logiciel Microsoft Graph pour iOS.
38 |
39 | **Remarque :** Si possible, utilisez cet exemple avec un compte de test ou non professionnel. L’exemple ne nettoie pas toujours les objets créés dans votre boîte aux lettres et votre calendrier. À ce stade, vous devrez supprimer manuellement les exemples de messages électroniques et les événements de calendrier. Notez également que les extraits de code qui obtiennent et envoient des messages et qui obtiennent, créent, mettent à jour et suppriment des événements ne fonctionnent pas avec tous les comptes personnels. Ces opérations fonctionneront finalement lorsque ces comptes seront mis à jour pour fonctionner avec le point de terminaison d’authentification v2.
40 |
41 | ## Conditions préalables
42 |
43 | Cet exemple nécessite les éléments suivants :
44 |
45 | - [Xcode](https://developer.apple.com/xcode/downloads/) version 10.2.1
46 | - Installation de [CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html) comme gestionnaire de dépendances.
47 | - Un compte de messagerie professionnel ou personnel Microsoft comme Office 365 ou outlook.com, hotmail.com, etc. Vous pouvez vous inscrire à [Office 365 Developer](https://aka.ms/devprogramsignup) pour accéder aux ressources dont vous avez besoin pour commencer à créer des applications Office 365.
48 |
49 | ## Enregistrement et configuration de l’application
50 |
51 | 1. Ouvrez un navigateur, accédez au [Centre d’administration Azure Active Directory](https://aad.portal.azure.com) et connectez-vous à l’aide d’un **compte personnel** (ou compte Microsoft) ou d’un **compte professionnel ou scolaire**.
52 |
53 | 1. Sélectionnez **Azure Active Directory** dans le volet de navigation gauche, puis sélectionnez **Inscriptions d’applications** sous **Gérer**.
54 |
55 | 1. Sélectionnez **Nouvelle inscription**. Sur la page **Inscrire une application**, définissez les valeurs comme suit.
56 |
57 | - Définissez **Nom** sur `Exemple d'extraits de code Swift`.
58 | - Définissez **Types de comptes pris en charge** sur **Comptes figurant dans un annuaire organisationnel et comptes Microsoft personnels**.
59 | - Sous **URI de redirection**, remplacez la liste déroulante par **client public (mobile et bureau)** et définissez la valeur sur `msauth.com.microsoft.Graph-iOS-Swift-Snippets://auth`.
60 |
61 | 1. Choisissez **Inscrire**. Dans la page **Exemple d’extraits de code Swift**, copiez la valeur de **ID d’application (client)** et enregistrez-la, car vous en aurez besoin à l’étape suivante.
62 |
63 | ## Création et débogage
64 |
65 | 1. Cloner ce référentiel
66 |
67 | 1. Ouvrez **Terminal** et accédez au dossier racine du projet. Exécutez la commande suivante pour installer les dépendances.
68 |
69 | ```Shell
70 | pod install
71 | ```
72 |
73 | 1. Ouvrez **Graph-iOS-Swift-Snippets.xcworkspace** dans Xcode.
74 |
75 | 1. Ouvrez **ApplicationConstants.swift**. Remplacez `ENTER_CLIENT_ID` par l’ID d’application que vous avez obtenu de l’inscription de votre application.
76 |
77 | ```swift
78 | // You will set your application's clientId
79 | static let clientId = "ENTER_CLIENT_ID"
80 | ```
81 |
82 | 1. Exécutez l’exemple.
83 |
84 | ## Exécution de l’exemple
85 |
86 | Une fois lancée, l’application affiche une liste de tâches courantes de l’utilisateur. Ces tâches peuvent être exécutées en fonction du niveau d’autorisations et du type de compte et sont indiquées dans les commentaires :
87 |
88 | - Tâches qui s’appliquent à la fois aux comptes professionnels, scolaires et personnels, telles que l’obtention et l’envoi de messages électroniques, la création de fichiers, etc.
89 | - Tâches qui s’appliquent uniquement aux comptes professionnels ou scolaires, telles que l’obtention de la photo de compte ou du responsable d’un utilisateur.
90 | - Tâches qui s’appliquent uniquement aux comptes professionnels ou scolaires avec des autorisations administratives appropriées, telles que l’obtention de membres du groupe ou la création de comptes d’utilisateur.
91 |
92 | Sélectionnez la tâche que vous souhaitez effectuer et cliquez dessus pour l’exécuter. N’oubliez pas que si vous vous connectez avec un compte qui ne dispose pas des autorisations applicables pour les tâches sélectionnées, celles-ci échoueront. Par exemple si vous essayez d’exécuter un extrait spécifique, tel que l’obtention de tous les groupes du client, à partir d’un compte qui ne dispose pas de privilèges d’administrateur dans l’organigramme, l’opération échoue. Sinon, si vous vous connectez avec un compte personnel comme hotmail.com et essayez d’obtenir le responsable de l’utilisateur connecté, l’opération échoue.
93 |
94 | ## Contribution
95 |
96 | Si vous souhaitez contribuer à cet exemple, voir [CONTRIBUTING.MD](/CONTRIBUTING.md).
97 |
98 | Ce projet a adopté le [code de conduite Open Source de Microsoft](https://opensource.microsoft.com/codeofconduct/). Pour en savoir plus, reportez-vous à la [FAQ relative au code de conduite](https://opensource.microsoft.com/codeofconduct/faq/) ou contactez [opencode@microsoft.com](mailto:opencode@microsoft.com) pour toute question ou tout commentaire.
99 |
100 | ## Copyright
101 |
102 | Copyright (c) 2016 Microsoft. Tous droits réservés.
103 |
--------------------------------------------------------------------------------
/Graph-iOS-Swift-SnippetsTests/GroupsSnippetsTest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GroupsSnippetsTest.swift
3 | // Graph-iOS-Swift-Snippets
4 | //
5 | // Created by Jason Kim on 7/18/16.
6 | // Copyright © 2016 Jason Kim. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | @testable import Graph_iOS_Swift_Snippets
12 |
13 | class GroupsSnippetsTest: XCTestCase {
14 |
15 | var authProvider: testAuthProvider!
16 | var graphClient: MSGraphClient!
17 |
18 | override func setUp() {
19 | super.setUp()
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | authProvider = testAuthProvider()
22 |
23 | MSGraphClient.setAuthenticationProvider(authProvider)
24 | graphClient = MSGraphClient.defaultClient()
25 | }
26 |
27 | override func tearDown() {
28 | // Put teardown code here. This method is called after the invocation of each test method in the class.
29 | super.tearDown()
30 | }
31 |
32 |
33 | func testCreateUser() {
34 |
35 | let userId = NSProcessInfo.processInfo().globallyUniqueString
36 | let domainName = authProvider.domainName
37 | let upn = userId + "@" + domainName
38 |
39 | let newUser = MSGraphUser()
40 | let passwordProfile = MSGraphPasswordProfile()
41 | passwordProfile.password = "!pass!word1"
42 |
43 | newUser.accountEnabled = true
44 | newUser.displayName = userId
45 | newUser.passwordProfile = passwordProfile
46 | newUser.mailNickname = userId
47 | newUser.userPrincipalName = upn
48 |
49 | var readyExpectation = expectationWithDescription("ready")
50 |
51 | var validCreatedUser: MSGraphUser!
52 |
53 | graphClient.users().request().addUser(newUser) { (createdUser: MSGraphUser?, error: NSError?) in
54 |
55 | XCTAssertNotNil(newUser)
56 | XCTAssertNil(error)
57 |
58 | validCreatedUser = createdUser
59 |
60 | readyExpectation.fulfill()
61 | }
62 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
63 | XCTAssertNil(error, "Timeout")
64 | return
65 | }
66 |
67 | readyExpectation = expectationWithDescription("ready")
68 |
69 |
70 | graphClient.users(validCreatedUser.entityId).request().deleteWithCompletion { (error: NSError?) in
71 | XCTAssertNil(error)
72 | readyExpectation.fulfill()
73 | }
74 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
75 | XCTAssertNil(error, "Timeout")
76 | return
77 | }
78 | }
79 |
80 |
81 | func testGetUserGroups() {
82 |
83 | let readyExpectation = expectationWithDescription("ready")
84 |
85 | graphClient.me().memberOf().request().getWithCompletion { (userGroupCollection: MSCollection?,
86 | nextRequest: MSGraphUserMemberOfCollectionWithReferencesRequest?,
87 | error: NSError?) in
88 |
89 | XCTAssertNotNil(userGroupCollection)
90 | XCTAssertNil(error)
91 |
92 | readyExpectation.fulfill()
93 | }
94 |
95 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
96 | XCTAssertNil(error, "Timeout")
97 | return
98 | }
99 | }
100 |
101 | func testGetAllGroups() {
102 |
103 | let readyExpectation = expectationWithDescription("ready")
104 |
105 | graphClient.groups().request().getWithCompletion { (allGroupsCollection: MSCollection?, nextRequest: MSGraphGroupsCollectionRequest?, error: NSError?) in
106 | XCTAssertNotNil(allGroupsCollection)
107 | XCTAssertNil(error)
108 |
109 | readyExpectation.fulfill()
110 | }
111 |
112 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
113 | XCTAssertNil(error, "Timeout")
114 | return
115 | }
116 | }
117 |
118 | func testGetSingleGroup() {
119 |
120 | var readyExpectation = expectationWithDescription("ready")
121 | var validGroupId: String?
122 |
123 | // get all groups first
124 | graphClient.groups().request().getWithCompletion { (allGroupsCollection: MSCollection?, nextRequest: MSGraphGroupsCollectionRequest?, error: NSError?) in
125 | XCTAssertNotNil(allGroupsCollection)
126 | XCTAssertNil(error)
127 |
128 | if let allGroups = allGroupsCollection {
129 | print((allGroups.value[0] as! MSGraphDirectoryObject).dictionaryFromItem()["id"])
130 |
131 | validGroupId = (allGroups.value[0] as! MSGraphDirectoryObject).dictionaryFromItem()["id"] as? String
132 | }
133 |
134 | readyExpectation.fulfill()
135 | }
136 |
137 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
138 | XCTAssertNil(error, "Timeout")
139 | return
140 | }
141 |
142 | XCTAssertNotNil(validGroupId)
143 |
144 |
145 | readyExpectation = expectationWithDescription("ready")
146 |
147 | graphClient.groups(validGroupId).request().getWithCompletion { (singleGroup: MSGraphGroup?, error: NSError?) in
148 |
149 | XCTAssertNotNil(singleGroup)
150 | XCTAssertNil(error)
151 |
152 | readyExpectation.fulfill()
153 | }
154 |
155 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
156 | XCTAssertNil(error, "Timeout")
157 | return
158 | }
159 |
160 | }
161 |
162 | func testGetMembers() {
163 |
164 | var readyExpectation = expectationWithDescription("ready")
165 | var validGroupId: String?
166 |
167 | // get all groups first
168 | graphClient.groups().request().getWithCompletion { (allGroupsCollection: MSCollection?, nextRequest: MSGraphGroupsCollectionRequest?, error: NSError?) in
169 | XCTAssertNotNil(allGroupsCollection)
170 | XCTAssertNil(error)
171 |
172 | if let allGroups = allGroupsCollection {
173 | print((allGroups.value[0] as! MSGraphDirectoryObject).dictionaryFromItem()["id"])
174 |
175 | validGroupId = (allGroups.value[0] as! MSGraphDirectoryObject).dictionaryFromItem()["id"] as? String
176 | }
177 |
178 | readyExpectation.fulfill()
179 | }
180 |
181 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
182 | XCTAssertNil(error, "Timeout")
183 | return
184 | }
185 |
186 | XCTAssertNotNil(validGroupId)
187 |
188 |
189 | readyExpectation = expectationWithDescription("ready")
190 |
191 | graphClient.groups(validGroupId).members().request().getWithCompletion { (memberCollection: MSCollection?, nextRequest: MSGraphGroupMembersCollectionWithReferencesRequest?, error: NSError?) in
192 |
193 | XCTAssertNotNil(memberCollection)
194 | XCTAssertNil(error)
195 |
196 | readyExpectation.fulfill()
197 | }
198 |
199 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
200 | XCTAssertNil(error, "Timeout")
201 | return
202 | }
203 |
204 |
205 | }
206 |
207 | func testGetOwners() {
208 |
209 | var readyExpectation = expectationWithDescription("ready")
210 | var validGroupId: String?
211 |
212 | // get all groups first
213 | graphClient.groups().request().getWithCompletion { (allGroupsCollection: MSCollection?, nextRequest: MSGraphGroupsCollectionRequest?, error: NSError?) in
214 | XCTAssertNotNil(allGroupsCollection)
215 | XCTAssertNil(error)
216 |
217 | if let allGroups = allGroupsCollection {
218 | print((allGroups.value[0] as! MSGraphDirectoryObject).dictionaryFromItem()["id"])
219 |
220 | validGroupId = (allGroups.value[0] as! MSGraphDirectoryObject).dictionaryFromItem()["id"] as? String
221 | }
222 |
223 | readyExpectation.fulfill()
224 | }
225 |
226 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
227 | XCTAssertNil(error, "Timeout")
228 | return
229 | }
230 |
231 | XCTAssertNotNil(validGroupId)
232 |
233 |
234 | readyExpectation = expectationWithDescription("ready")
235 |
236 | graphClient.groups(validGroupId).owners().request().getWithCompletion { (memberCollection: MSCollection?, nextRequest: MSGraphGroupOwnersCollectionWithReferencesRequest?, error: NSError?) in
237 |
238 | XCTAssertNotNil(memberCollection)
239 | XCTAssertNil(error)
240 |
241 | readyExpectation.fulfill()
242 | }
243 |
244 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
245 | XCTAssertNil(error, "Timeout")
246 | return
247 | }
248 |
249 |
250 | }
251 |
252 | func testGroupOperations() {
253 |
254 | var validGroup: MSGraphGroup?
255 | var readyExpectation = expectationWithDescription("ready")
256 |
257 | // create group
258 |
259 | let group = Snippets.createGroupObject()
260 | graphClient.groups().request().addGroup(group) { (addedGroup: MSGraphGroup?, error: NSError?) in
261 |
262 | XCTAssertNotNil(addedGroup)
263 | XCTAssertNil(error)
264 |
265 | validGroup = addedGroup
266 |
267 | readyExpectation.fulfill()
268 | }
269 |
270 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
271 | XCTAssertNil(error, "Timeout")
272 | return
273 | }
274 |
275 |
276 | // update group
277 |
278 | guard let singleGroup = validGroup else {
279 | XCTAssertTrue(true)
280 | return
281 | }
282 |
283 | singleGroup.displayName = "Update namexxx"
284 |
285 |
286 | print("id", singleGroup.entityId)
287 | print("name", singleGroup.displayName)
288 | print("singleGroup", singleGroup)
289 |
290 | readyExpectation = expectationWithDescription("ready")
291 |
292 | graphClient.groups(singleGroup.entityId).request().update(singleGroup) { (updatedGroup: MSGraphGroup?, error: NSError?) in
293 | print(updatedGroup)
294 | print(error)
295 |
296 | XCTAssertNil(error)
297 |
298 | readyExpectation.fulfill()
299 | }
300 |
301 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
302 | XCTAssertNil(error, "Timeout")
303 | return
304 | }
305 | // delete group
306 | readyExpectation = expectationWithDescription("ready")
307 |
308 | graphClient.groups(validGroup!.entityId).request().deleteWithCompletion { (error: NSError?) in
309 | XCTAssertNil(error)
310 | readyExpectation.fulfill()
311 | }
312 |
313 |
314 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
315 | XCTAssertNil(error, "Timeout")
316 | return
317 | }
318 | }
319 |
320 |
321 | }
322 |
--------------------------------------------------------------------------------
/Graph-iOS-Swift-Snippets/GroupsSnippets.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 | import Foundation
7 | import MSGraphSDK
8 |
9 | // MARK: - Admin
10 | // Applicable to work accounts with admin rights
11 |
12 | // Creates a new user in the tenant.
13 | struct CreateUser: Snippet
14 | {
15 | let name = "Create user"
16 | let needAdminAccess: Bool = true
17 |
18 | func execute(with completion: @escaping (_ result: Result) -> Void)
19 | {
20 | let userId = ProcessInfo.processInfo.globallyUniqueString
21 | let domainName = "ENTER_DOMAIN_NAME"
22 | let upn = userId + "@" + domainName
23 |
24 | let newUser = MSGraphUser()
25 | let passwordProfile = MSGraphPasswordProfile()
26 | passwordProfile.password = "!pass!word1"
27 |
28 | newUser.accountEnabled = true
29 | newUser.displayName = userId
30 | newUser.passwordProfile = passwordProfile
31 | newUser.mailNickname = userId
32 | newUser.userPrincipalName = upn
33 |
34 | Snippets.graphClient.users().request()?.add(newUser, withCompletion: { (createdUser, error) in
35 | if let nsError = error as NSError? {
36 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
37 | return
38 | } else {
39 | guard let displayName = createdUser?.displayName else {
40 | completion(.Success(displayText: "User created - no user display name"))
41 | return
42 | }
43 | completion(.Success(displayText: "User created: \(displayName)"))
44 | }
45 | })
46 | }
47 | }
48 |
49 | // Gets a collection of groups that the signed-in user is a member of.
50 | struct GetUserGroups: Snippet
51 | {
52 | let name = "Get user groups"
53 | let needAdminAccess: Bool = true
54 |
55 | func execute(with completion: @escaping (_ result: Result) -> Void)
56 | {
57 | Snippets.graphClient.me().memberOf().request()?.getWithCompletion({ (userGroupCollection, nextRequest, error) in
58 | if let nsError = error as NSError? {
59 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
60 | return
61 | }
62 |
63 | var displayString = "List of groups: \n"
64 |
65 | if let userGroups = userGroupCollection {
66 | for userGroup: MSGraphDirectoryObject in userGroups.value as! [MSGraphDirectoryObject] {
67 | guard let name = userGroup.dictionaryFromItem()["displayName"] else {
68 | completion(.Failure(error: MSGraphError.UnexpectecError(errorString: "Display name not found")))
69 | return
70 | }
71 | displayString += "\(name)\n"
72 | }
73 | }
74 | if let _ = nextRequest {
75 | displayString += "Next request available for more groups"
76 | }
77 |
78 | completion(.Success(displayText: displayString))
79 | })
80 | }
81 | }
82 |
83 | // Returns all of the groups in your tenant's directory.
84 | struct GetAllGroups: Snippet
85 | {
86 | let name = "Get all groups"
87 | let needAdminAccess: Bool = true
88 |
89 | func execute(with completion: @escaping (_ result: Result) -> Void)
90 | {
91 | Snippets.graphClient.groups().request()?.getWithCompletion({ (allGroupsCollection, nextRequest, error) in
92 | if let nsError = error as NSError? {
93 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
94 | return
95 | }
96 |
97 | var displayString = "List of all groups: \n"
98 |
99 | if let allGroups = allGroupsCollection {
100 | for group: MSGraphDirectoryObject in allGroups.value as! [MSGraphDirectoryObject] {
101 |
102 | guard let name = group.dictionaryFromItem()["displayName"] else {
103 | completion(.Failure(error: MSGraphError.UnexpectecError(errorString: "Display name not found")))
104 | return
105 | }
106 | displayString += "\(name)\n "
107 | }
108 | }
109 | if let _ = nextRequest {
110 | displayString += "Next request available for more groups"
111 | }
112 |
113 | completion(.Success(displayText: displayString))
114 | })
115 | }
116 | }
117 |
118 | // Gets a specified group.
119 | struct GetSingleGroup: Snippet
120 | {
121 | let name = "Get single group"
122 | let needAdminAccess: Bool = true
123 |
124 | func execute(with completion: @escaping (_ result: Result) -> Void)
125 | {
126 | // Enter a valid group ID,
127 | // This can be found from getting list of groups or creating a new group
128 | let groupId: String = "ENTER_GROUP_ID"
129 |
130 | Snippets.graphClient.groups(groupId).request().getWithCompletion({ (singleGroup, error) in
131 | if let nsError = error as NSError? {
132 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
133 | return
134 | } else {
135 | completion(.Success(displayText: "Retrieved group: \(singleGroup!)"))
136 | }
137 | })
138 | }
139 | }
140 |
141 | //Gets a specific group's members.
142 | struct GetMembers: Snippet
143 | {
144 | let name = "Get members"
145 | let needAdminAccess: Bool = true
146 |
147 | func execute(with completion: @escaping (_ result: Result) -> Void)
148 | {
149 | // Enter a valid group ID,
150 | // This can be found from getting list of groups or creating a new group
151 | let groupId: String = "ENTER_GROUP_ID"
152 |
153 | Snippets.graphClient.groups(groupId).members().request().getWithCompletion({ (memberCollection, nextRequest, error) in
154 | if let nsError = error as NSError? {
155 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
156 | return
157 | } else {
158 | var displayString = "List of members:\n"
159 |
160 | for member: MSGraphDirectoryObject in memberCollection!.value as! [MSGraphDirectoryObject] {
161 | guard let name = member.dictionaryFromItem()["displayName"] else {
162 | completion(.Failure(error: MSGraphError.UnexpectecError(errorString: "Display name not found")))
163 | return
164 | }
165 | displayString += name as! String + "\n"
166 | }
167 |
168 | if let _ = nextRequest {
169 | displayString += "Next request available for more members"
170 | }
171 |
172 | completion(.Success(displayText: "List of members:\n\(displayString)"))
173 | }
174 | })
175 | }
176 | }
177 |
178 | // Gets a specific group's owners.
179 | struct GetOwners: Snippet
180 | {
181 | let name = "Get owners"
182 | let needAdminAccess: Bool = true
183 |
184 | func execute(with completion: @escaping (_ result: Result) -> Void)
185 | {
186 | // Enter a valid group ID,
187 | // This can be found from getting list of groups or creating a new group
188 | let groupId: String = "ENTER_GROUP_ID" //"047dc3cc-88ce-4f55-82f3-f8fe8c79f393"
189 |
190 | Snippets.graphClient.groups(groupId).owners().request().getWithCompletion({ (memberCollection, nextRequest, error) in
191 | if let nsError = error as NSError? {
192 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
193 | return
194 | } else {
195 | var displayString = "List of owners:\n"
196 |
197 | for member: MSGraphDirectoryObject in memberCollection!.value as! [MSGraphDirectoryObject] {
198 | guard let name = member.dictionaryFromItem()["displayName"] else {
199 | completion(.Failure(error: MSGraphError.UnexpectecError(errorString: "Display name not found")))
200 | return
201 | }
202 | displayString += name as! String + "\n"
203 | }
204 |
205 | if let _ = nextRequest {
206 | displayString += "Next request available for more members"
207 | }
208 |
209 | completion(.Success(displayText: "List of owners:\n\(displayString)"))
210 | }
211 | })
212 | }
213 | }
214 |
215 | // Creates a group in user's account.
216 | struct CreateGroup: Snippet
217 | {
218 | let name = "Create group"
219 | let needAdminAccess: Bool = true
220 |
221 | func execute(with completion: @escaping (_ result: Result) -> Void)
222 | {
223 | let group = Snippets.createGroupObject()
224 |
225 | Snippets.graphClient.groups().request().add(group) { (addedGroup, error) in
226 | if let nsError = error as NSError? {
227 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
228 | return
229 | } else {
230 | guard let _ = addedGroup else {
231 | completion(.Failure(error: MSGraphError.UnexpectecError(errorString: "Group ID not returned")))
232 | return
233 | }
234 | print("id", addedGroup!.entityId)
235 | let displayName = addedGroup?.displayName ?? ""
236 | completion(.Success(displayText: "Group \(displayName) was added"))
237 | }
238 | }
239 | }
240 | }
241 |
242 | // Creates and updates a group in user's account.
243 | struct UpdateGroup: Snippet
244 | {
245 | let name = "Update group"
246 | let needAdminAccess: Bool = true
247 | func execute(with completion: @escaping (_ result: Result) -> Void) {
248 |
249 | // Enter a valid group ID,
250 | // This can be found from getting list of groups or creating a new group
251 | let groupId: String = "070fcdec-b187-498e-8c1e-663e3e7fb418" //"047dc3cc-88ce-4f55-82f3-f8fe8c79f393"
252 |
253 | Snippets.graphClient.groups(groupId).request().getWithCompletion { (group, error) in
254 | if let nsError = error as NSError? {
255 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
256 | return
257 | } else {
258 | guard let validGroup = group else {
259 | completion(.Failure(error: MSGraphError.UnexpectecError(errorString: "Group ID not returned")))
260 | return
261 | }
262 |
263 | validGroup.displayName = "Updated group display name"
264 | Snippets.graphClient.groups(validGroup.entityId).request().update(validGroup, withCompletion: { (group, error) in
265 | if let nsError = error as NSError? {
266 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
267 | return
268 | } else {
269 | let displayName = group?.displayName ?? ""
270 | completion(.Success(displayText: "Group \(displayName) updated"))
271 | }
272 | })
273 | }
274 | }
275 | }
276 | }
277 |
278 | // Creates and deletes a group in user's account.
279 | struct DeleteGroup: Snippet
280 | {
281 | let name = "Delete group"
282 | let needAdminAccess: Bool = true
283 |
284 | func execute(with completion: @escaping (_ result: Result) -> Void) {
285 |
286 | // Enter a valid group ID,
287 | // This can be found from getting list of groups or creating a new group
288 | let groupId: String = "ENTER_GROUP_ID" //"047dc3cc-88ce-4f55-82f3-f8fe8c79f393"
289 |
290 | Snippets.graphClient.groups(groupId).request().delete(completion: { (error) in
291 | if let nsError = error as NSError? {
292 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
293 | return
294 | } else {
295 | completion(.Success(displayText: "Group has been deleted"))
296 | }
297 | })
298 | }
299 | }
300 |
301 | // MARK: - Helper methods
302 |
303 | extension Snippets {
304 |
305 | static func createGroupObject() -> MSGraphGroup {
306 | let group = MSGraphGroup()
307 | group.displayName = "New sample group"
308 | group.mailEnabled = true
309 | group.mailNickname = "samplemailnickname"
310 | group.securityEnabled = false
311 | group.groupTypes = ["Unified"]
312 |
313 | return group
314 | }
315 | }
316 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | Contribute to this documentation
2 |
3 | Thank you for your interest in our documentation!
4 |
5 | * [Ways to contribute](#ways-to-contribute)
6 | * [Contribute using GitHub](#contribute-using-github)
7 | * [Contribute using Git](#contribute-using-git)
8 | * [How to use Markdown to format your topic](#how-to-use-markdown-to-format-your-topic)
9 | * [FAQ](#faq)
10 | * [More resources](#more-resources)
11 |
12 | ## Ways to contribute
13 |
14 | Here are some ways you can contribute to this documentation:
15 |
16 | * To make small changes to an article, [Contribute using GitHub](#contribute-using-github).
17 | * To make large changes, or changes that involve code, [Contribute using Git](#contribute-using-git).
18 | * Report documentation bugs via GitHub Issues
19 | * Request new documentation at the [Office Developer Platform UserVoice](http://officespdev.uservoice.com) site.
20 |
21 | ## Contribute using GitHub
22 |
23 | Use GitHub to contribute to this documentation without having to clone the repo to your desktop. This is the easiest way to create a pull request in this repository. Use this method to make a minor change that doesn't involve code changes.
24 |
25 | **Note** Using this method allows you to contribute to one article at a time.
26 |
27 | ### To Contribute using GitHub
28 |
29 | 1. Find the article you want to contribute to on GitHub.
30 |
31 | If the article is in MSDN, choose the **suggest and submit changes** link in the **Contribute to this content** section and you'll be taken to the same article on GitHub.
32 | 2. Once you are on the article in GitHub, sign in to GitHub (get a free account [Join GitHub](https://github.com/join).
33 | 3. Choose the **pencil icon** (edit the file in your fork of this project) and make your changes in the **<>Edit file** window.
34 | 4. Scroll to the bottom and enter a description.
35 | 5. Choose **Propose file change**>**Create pull request**.
36 |
37 | You now have successfully submitted a pull request. Pull requests are typically reviewed within 10 business days.
38 |
39 |
40 | ## Contribute using Git
41 |
42 | Use Git to contribute substantive changes, such as:
43 |
44 | * Contributing code.
45 | * Contributing changes that affect meaning.
46 | * Contributing large changes to text.
47 | * Adding new topics.
48 |
49 | ### To Contribute using Git
50 |
51 | 1. If you don't have a GitHub account, set one up at [GitHub](https://github.com/join).
52 | 2. After you have an account, install Git on your computer. Follow the steps in [Setting up Git Tutorial](https://help.github.com/articles/set-up-git/).
53 | 3. To submit a pull request using Git, follow the steps in [Use GitHub, Git, and this repository](#use-github-git-and-this-repository).
54 | 4. You will be asked to sign the Contributor's License Agreement if you are:
55 |
56 | * A member of the Microsoft Open Technologies group.
57 | * A contributors who doesn't work for Microsoft.
58 |
59 | As a community member, you must sign the Contribution License Agreement (CLA) before you can contribute large submissions to a project. You only need to complete and submit the documentation once. Carefully review the document. You may be required to have your employer sign the document.
60 |
61 | Signing the CLA does not grant you rights to commit to the main repository, but it does mean that the Office Developer and Office Developer Content Publishing teams will be able to review and approve your contributions. You will be credited for your submissions.
62 |
63 | Pull requests are typically reviewed within 10 business days.
64 |
65 | ## Use GitHub, Git, and this repository
66 |
67 | **Note:** Most of the information in this section can be found in [GitHub Help] articles. If you're familiar with Git and GitHub, skip to the **Contribute and edit content** section for the specifics of the code/content flow of this repository.
68 |
69 | ### To set up your fork of the repository
70 |
71 | 1. Set up a GitHub account so you can contribute to this project. If you haven't done this, go to [GitHub](https://github.com/join) and do it now.
72 | 2. Install Git on your computer. Follow the steps in the [Setting up Git Tutorial] [Set Up Git].
73 | 3. Create your own fork of this repository. To do this, at the top of the page, choose the **Fork** button.
74 | 4. Copy your fork to your computer. To do this, open Git Bash. At the command prompt enter:
75 |
76 | git clone https://github.com//.git
77 |
78 | Next, create a reference to the root repository by entering these commands:
79 |
80 | cd
81 | git remote add upstream https://github.com/microsoftgraph/.git
82 | git fetch upstream
83 |
84 | Congratulations! You've now set up your repository. You won't need to repeat these steps again.
85 |
86 | ### Contribute and edit content
87 |
88 | To make the contribution process as seamless as possible, follow these steps.
89 |
90 | #### To contribute and edit content
91 |
92 | 1. Create a new branch.
93 | 2. Add new content or edit existing content.
94 | 3. Submit a pull request to the main repository.
95 | 4. Delete the branch.
96 |
97 | **Important** Limit each branch to a single concept/article to streamline the work flow and reduce the chance of merge conflicts. Content appropriate for a new branch includes:
98 |
99 | * A new article.
100 | * Spelling and grammar edits.
101 | * Applying a single formatting change across a large set of articles (for example, applying a new copyright footer).
102 |
103 | #### To create a new branch
104 |
105 | 1. Open Git Bash.
106 | 2. At the Git Bash command prompt, type `git pull upstream master:`. This creates a new branch locally that is copied from the latest MicrosoftGraph master branch.
107 | 3. At the Git Bash command prompt, type `git push origin `. This alerts GitHub to the new branch. You should now see the new branch in your fork of the repository on GitHub.
108 | 4. At the Git Bash command prompt, type `git checkout ` to switch to your new branch.
109 |
110 | #### Add new content or edit existing content
111 |
112 | You navigate to the repository on your computer by using File Explorer. The repository files are in `C:\Users\\`.
113 |
114 | To edit files, open them in an editor of your choice and modify them. To create a new file, use the editor of your choice and save the new file in the appropriate location in your local copy of the repository. While working, save your work frequently.
115 |
116 | The files in `C:\Users\\` are a working copy of the new branch that you created in your local repository. Changing anything in this folder doesn't affect the local repository until you commit a change. To commit a change to the local repository, type the following commands in GitBash:
117 |
118 | git add .
119 | git commit -v -a -m ""
120 |
121 | The `add` command adds your changes to a staging area in preparation for committing them to the repository. The period after the `add` command specifies that you want to stage all of the files that you added or modified, checking subfolders recursively. (If you don't want to commit all of the changes, you can add specific files. You can also undo a commit. For help, type `git add -help` or `git status`.)
122 |
123 | The `commit` command applies the staged changes to the repository. The switch `-m` means you are providing the commit comment in the command line. The -v and -a switches can be omitted. The -v switch is for verbose output from the command, and -a does what you already did with the add command.
124 |
125 | You can commit multiple times while you are doing your work, or you can commit once when you're done.
126 |
127 | #### Submit a pull request to the main repository
128 |
129 | When you're finished with your work and are ready to have it merged into the main repository, follow these steps.
130 |
131 | #### To submit a pull request to the main repository
132 |
133 | 1. In the Git Bash command prompt, type `git push origin `. In your local repository, `origin` refers to your GitHub repository that you cloned the local repository from. This command pushes the current state of your new branch, including all commits made in the previous steps, to your GitHub fork.
134 | 2. On the GitHub site, navigate in your fork to the new branch.
135 | 3. Choose the **Pull Request** button at the top of the page.
136 | 4. Verify the Base branch is `microsoftgraph/@master` and the Head branch is `/@`.
137 | 5. Choose the **Update Commit Range** button.
138 | 6. Add a title to your pull request, and describe all the changes you're making.
139 | 7. Submit the pull request.
140 |
141 | One of the site administrators will process your pull request. Your pull request will surface on the microsoftgraph/ site under Issues. When the pull request is accepted, the issue will be resolved.
142 |
143 | #### Create a new branch after merge
144 |
145 | After a branch is successfully merged (that is, your pull request is accepted), don't continue working in that local branch. This can lead to merge conflicts if you submit another pull request. To do another update, create a new local branch from the successfully merged upstream branch, and then delete your initial local branch.
146 |
147 | For example, if your local branch X was successfully merged into the OfficeDev/microsoft-graph-docs master branch and you want to make additional updates to the content that was merged. Create a new local branch, X2, from the OfficeDev/microsoft-graph-docs master branch. To do this, open GitBash and execute the following commands:
148 |
149 | cd microsoft-graph-docs
150 | git pull upstream master:X2
151 | git push origin X2
152 |
153 | You now have local copies (in a new local branch) of the work that you submitted in branch X. The X2 branch also contains all the work other writers have merged, so if your work depends on others' work (for example, shared images), it is available in the new branch. You can verify that your previous work (and others' work) is in the branch by checking out the new branch...
154 |
155 | git checkout X2
156 |
157 | ...and verifying the content. (The `checkout` command updates the files in `C:\Users\\microsoft-graph-docs` to the current state of the X2 branch.) Once you check out the new branch, you can make updates to the content and commit them as usual. However, to avoid working in the merged branch (X) by mistake, it's best to delete it (see the following **Delete a branch** section).
158 |
159 | #### Delete a branch
160 |
161 | Once your changes are successfully merged into the main repository, delete the branch you used because you no longer need it. Any additional work should be done in a new branch.
162 |
163 | #### To delete a branch
164 |
165 | 1. In the Git Bash command prompt, type `git checkout master`. This ensures that you aren't in the branch to be deleted (which isn't allowed).
166 | 2. Next, at the command prompt, type `git branch -d `. This deletes the branch on your computer only if it has been successfully merged to the upstream repository. (You can override this behavior with the `–D` flag, but first be sure you want to do this.)
167 | 3. Finally, type `git push origin :` at the command prompt (a space before the colon and no space after it). This will delete the branch on your github fork.
168 |
169 | Congratulations, you have successfully contributed to the project!
170 |
171 | ## How to use Markdown to format your topic
172 |
173 | ### Article template
174 |
175 | The [markdown template](/articles/0-markdown-template-for-new-articles.md) contains the basic Markdown for a topic that includes a table of contents, sections with subheadings, links to other Office developer topics, links to other sites, bold text, italic text, numbered and bulleted lists, code snippets, and images.
176 |
177 |
178 | ### Standard Markdown
179 |
180 | All of the articles in this repository use Markdown. A complete introduction (and listing of all the syntax) can be found at [Markdown Home] [].
181 |
182 | ## FAQ
183 |
184 | ### How do I get a GitHub account?
185 |
186 | Fill out the form at [Join GitHub](https://github.com/join) to open a free GitHub account.
187 |
188 | ### Where do I get a Contributor's License Agreement?
189 |
190 | You will automatically be sent a notice that you need to sign the Contributor's License Agreement (CLA) if your pull request requires one.
191 |
192 | As a community member, **you must sign the Contribution License Agreement (CLA) before you can contribute large submissions to this project**. You only need complete and submit the documentation once. Carefully review the document. You may be required to have your employer sign the document.
193 |
194 | ### What happens with my contributions?
195 |
196 | When you submit your changes, via a pull request, our team will be notified and will review your pull request. You will receive notifications about your pull request from GitHub; you may also be notified by someone from our team if we need more information. We reserve the right to edit your submission for legal, style, clarity, or other issues.
197 |
198 | ### Can I become an approver for this repository's GitHub pull requests?
199 |
200 | Currently, we are not allowing external contributors to approve pull requests in this repository.
201 |
202 | ### How soon will I get a response about my change request or issue?
203 |
204 | We typically review pull requests and respond to issues within 10 business days.
205 |
206 | ## More resources
207 |
208 | * To learn more about Markdown, go to the Git creator's site [Daring Fireball].
209 | * To learn more about using Git and GitHub, first check out the [GitHub Help section] [GitHub Help].
210 |
211 | [GitHub Home]: http://github.com
212 | [GitHub Help]: http://help.github.com/
213 | [Set Up Git]: http://help.github.com/win-set-up-git/
214 | [Markdown Home]: http://daringfireball.net/projects/markdown/
215 | [Daring Fireball]: http://daringfireball.net/
216 |
--------------------------------------------------------------------------------
/Graph-iOS-Swift-SnippetsTests/UserSnippetsTest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UserSnippetsTest.swift
3 | // Graph-iOS-Swift-Snippets
4 | //
5 | // Created by Jason Kim on 7/11/16.
6 | // Copyright © 2016 Jason Kim. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | @testable import Graph_iOS_Swift_Snippets
12 |
13 | class UserSnippetsTest: XCTestCase {
14 |
15 | var authProvider: testAuthProvider!
16 | var graphClient: MSGraphClient!
17 |
18 | override func setUp() {
19 | super.setUp()
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | authProvider = testAuthProvider()
22 |
23 | MSGraphClient.setAuthenticationProvider(authProvider)
24 | graphClient = MSGraphClient.defaultClient()
25 | }
26 |
27 | // check for getting user information: GET ME
28 | func testGetMe() {
29 | let readyExpectation = expectationWithDescription("ready")
30 | graphClient.me().request().getWithCompletion({ (user: MSGraphUser?, error: NSError?) in
31 | XCTAssertNotNil(user, "User data should not be nil")
32 | XCTAssertNil(error, "Error should be nil")
33 |
34 | readyExpectation.fulfill()
35 | })
36 |
37 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
38 | XCTAssertNil(error, "Timeout")
39 | return
40 | }
41 | }
42 |
43 |
44 | func testUsers() {
45 | let readyExpectation = expectationWithDescription("ready")
46 | graphClient.users().request().getWithCompletion {
47 | (userCollection: MSCollection?, nextRequest: MSGraphUsersCollectionRequest?, error: NSError?) in
48 | XCTAssertNotNil(userCollection, "Users data should not be nil")
49 | XCTAssertNil(error, "Error should be nil")
50 |
51 | readyExpectation.fulfill()
52 | }
53 |
54 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
55 | XCTAssertNil(error, "Timeout")
56 | return
57 | }
58 | }
59 |
60 | func testDrive() {
61 | let readyExpectation = expectationWithDescription("ready")
62 | graphClient.me().drive().request().getWithCompletion {
63 | (drive: MSGraphDrive?, error: NSError?) in
64 | XCTAssertNil(error, "Error should be nil")
65 | XCTAssertNotNil(drive)
66 | readyExpectation.fulfill()
67 | }
68 |
69 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
70 | XCTAssertNil(error, "Timeout")
71 | return
72 | }
73 | }
74 |
75 |
76 |
77 | func testEvent() {
78 |
79 | var readyExpectation = expectationWithDescription("ready")
80 |
81 | // Create event
82 | var event = Snippets.createEventObject(isSeries: false)
83 |
84 | graphClient.me().calendar().events().request().addEvent(event) { (newEvent: MSGraphEvent?, error: NSError?) in
85 | XCTAssertNotNil(newEvent)
86 | XCTAssertNil(error)
87 |
88 | event = newEvent!
89 | readyExpectation.fulfill()
90 | }
91 |
92 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
93 | XCTAssertNil(error, "Timeout")
94 | return
95 | }
96 | XCTAssertNotNil(event)
97 |
98 | // Update event
99 | readyExpectation = expectationWithDescription("ready")
100 | event.subject = "NEW NAME"
101 | graphClient.me().events(event.entityId).request().update(event) { (newEvent: MSGraphEvent?, error: NSError?) in
102 | XCTAssertNotNil(newEvent)
103 | XCTAssertNil(error)
104 |
105 | readyExpectation.fulfill()
106 | }
107 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
108 | XCTAssertNil(error, "Timeout")
109 | return
110 | }
111 | XCTAssertNotNil(event)
112 |
113 | // Delete event
114 | readyExpectation = expectationWithDescription("ready")
115 | event.subject = "NEW NAME"
116 | graphClient.me().events(event.entityId).request().deleteWithCompletion({ (error: NSError?) in
117 | XCTAssertNil(error)
118 |
119 | readyExpectation.fulfill()
120 | })
121 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
122 | XCTAssertNil(error, "Timeout")
123 | return
124 | }
125 |
126 | }
127 |
128 |
129 | func testGetMessage() {
130 |
131 | let readyExpectation = expectationWithDescription("ready")
132 |
133 | graphClient.me().messages().request().getWithCompletion { (collection: MSCollection?, nextRequest: MSGraphUserMessagesCollectionRequest?, error: NSError?) in
134 | XCTAssertNil(error)
135 | XCTAssertNotNil(collection)
136 |
137 | readyExpectation.fulfill()
138 | }
139 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
140 | XCTAssertNil(error, "Timeout")
141 | return
142 | }
143 | }
144 |
145 |
146 | func testSendMessage() {
147 |
148 | // set message
149 | let message = MSGraphMessage()
150 |
151 | let toRecipient = MSGraphRecipient()
152 | let msEmailAddress = MSGraphEmailAddress()
153 | msEmailAddress.address = authProvider.userEmail
154 | toRecipient.emailAddress = msEmailAddress
155 | let toRecipientList = [toRecipient]
156 | message.toRecipients = toRecipientList
157 | message.subject = "Test mail from unit testing"
158 | let messageBody = MSGraphItemBody()
159 | messageBody.contentType = MSGraphBodyType.text()
160 | messageBody.content = "Mail received from the Office 365 iOS Microsoft Graph Snippets unit testing"
161 | message.body = messageBody
162 |
163 | // send message
164 | let readyExpectation = expectationWithDescription("ready")
165 |
166 | let mailRequest = graphClient.me().sendMailWithMessage(message, saveToSentItems: true).request()
167 | mailRequest.executeWithCompletion { (response: [NSObject : AnyObject]?, error: NSError?) in
168 | print(response?.keys)
169 | XCTAssertNotNil(response)
170 | XCTAssertNil(error)
171 | readyExpectation.fulfill()
172 |
173 | }
174 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
175 | XCTAssertNil(error, "Timeout")
176 | return
177 | }
178 | }
179 |
180 |
181 | func testGetUserFiles() {
182 | let readyExpectation: XCTestExpectation = expectationWithDescription("ready")
183 |
184 |
185 | graphClient.me().drive().root().children().request().getWithCompletion { (collection: MSCollection?, next: MSGraphDriveItemChildrenCollectionRequest?, error: NSError?) in
186 | XCTAssertNotNil(collection)
187 | XCTAssertNil(error)
188 |
189 | readyExpectation.fulfill()
190 | }
191 |
192 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
193 | XCTAssertNil(error, "Timeout")
194 | return
195 | }
196 | }
197 |
198 | func testFolderOperations() {
199 | var readyExpectation: XCTestExpectation
200 |
201 | // Create folder
202 | readyExpectation = expectationWithDescription("ready")
203 |
204 | // bug on conflictBehavior
205 | // https://github.com/OneDrive/onedrive-api-docs/issues/391
206 | var driveItem = MSGraphDriveItem(dictionary: [MSNameConflict.rename().key: MSNameConflict.rename().value])
207 | driveItem.name = "TestFolder"
208 | driveItem.folder = MSGraphFolder()
209 |
210 | graphClient.me().drive().root().children().request().addDriveItem(driveItem) { (item: MSGraphDriveItem?, error: NSError?) in
211 | XCTAssertNotNil(item)
212 | XCTAssertNil(error)
213 |
214 | driveItem = item
215 |
216 | readyExpectation.fulfill()
217 | }
218 |
219 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
220 | XCTAssertNil(error, "Timeout")
221 | return
222 | }
223 |
224 |
225 | // Delete folder
226 | readyExpectation = expectationWithDescription("ready")
227 |
228 | graphClient.me().drive().items(driveItem.entityId).request().deleteWithCompletion { (error :NSError?) in
229 | XCTAssertNil(error)
230 | readyExpectation.fulfill()
231 |
232 | }
233 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
234 | XCTAssertNil(error, "Timeout")
235 | return
236 | }
237 | }
238 |
239 | func testFileOperations() {
240 | var readyExpectation: XCTestExpectation
241 | var driveItem: MSGraphDriveItem!
242 |
243 | // Create file
244 | readyExpectation = expectationWithDescription("ready")
245 |
246 | let uploadData = "Test".dataUsingEncoding(NSUTF8StringEncoding)
247 |
248 | graphClient.me().drive().root().itemByPath("/testFile.txt").contentRequest().uploadFromData(uploadData) { (item: MSGraphDriveItem?, error: NSError?) in
249 | XCTAssertNotNil(item)
250 | XCTAssertNil(error)
251 |
252 | driveItem = item!
253 |
254 | readyExpectation.fulfill()
255 | }
256 |
257 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
258 | XCTAssertNil(error, "Timeout")
259 | return
260 | }
261 |
262 | // rename file
263 | readyExpectation = expectationWithDescription("ready")
264 |
265 | driveItem.name = "testFile2.txt"
266 | graphClient.me().drive().items(driveItem.entityId).request().update(driveItem) { (item: MSGraphDriveItem?, error: NSError?) in
267 | XCTAssertNotNil(item)
268 | XCTAssertNil(error)
269 |
270 | XCTAssertTrue(item!.name == "testFile2.txt")
271 |
272 | driveItem = item!
273 |
274 | readyExpectation.fulfill()
275 | }
276 |
277 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
278 | XCTAssertNil(error, "Timeout")
279 | return
280 | }
281 |
282 |
283 | // download file
284 | readyExpectation = expectationWithDescription("ready")
285 |
286 | graphClient.me().drive().items(driveItem.entityId).contentRequest().downloadWithCompletion { (url: NSURL?, response: NSURLResponse?, error: NSError?) in
287 | XCTAssertNotNil(url)
288 | XCTAssertNil(error)
289 |
290 | do {
291 | try NSFileManager.defaultManager().removeItemAtURL(url!)
292 | } catch let error as NSError {
293 | XCTAssertNil(error, "Timeout")
294 | }
295 |
296 | readyExpectation.fulfill()
297 | }
298 |
299 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
300 | XCTAssertNil(error, "Timeout")
301 | return
302 | }
303 |
304 |
305 | // delete file
306 | readyExpectation = expectationWithDescription("ready")
307 |
308 | graphClient.me().drive().items(driveItem.entityId).request().deleteWithCompletion { (error :NSError?) in
309 | XCTAssertNil(error)
310 | readyExpectation.fulfill()
311 | }
312 |
313 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
314 | XCTAssertNil(error, "Timeout")
315 | return
316 | }
317 |
318 | }
319 |
320 | func testGetManager() {
321 | let readyExpectation: XCTestExpectation = expectationWithDescription("ready")
322 |
323 | graphClient.me().manager().request().getWithCompletion { (directoryObject: MSGraphDirectoryObject?, error: NSError?) in
324 | XCTAssertNotNil(directoryObject)
325 | XCTAssertNil(error)
326 |
327 | readyExpectation.fulfill()
328 |
329 | }
330 |
331 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
332 | XCTAssertNil(error, "Timeout")
333 | return
334 | }
335 | }
336 |
337 | func testGetDirects() {
338 | let readyExpectation: XCTestExpectation = expectationWithDescription("ready")
339 |
340 |
341 | graphClient.me().directReports().request().getWithCompletion { (directCollection: MSCollection?, nextRequest: MSGraphUserDirectReportsCollectionWithReferencesRequest?, error: NSError?) in
342 | XCTAssertNotNil(directCollection)
343 | XCTAssertNil(error)
344 |
345 | readyExpectation.fulfill()
346 | }
347 |
348 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
349 | XCTAssertNil(error, "Timeout")
350 | return
351 | }
352 | }
353 |
354 | func testGetPhoto() {
355 | let readyExpectation: XCTestExpectation = expectationWithDescription("ready")
356 |
357 |
358 | graphClient.me().photo().request().getWithCompletion { (photo: MSGraphProfilePhoto?, error: NSError?) in
359 | XCTAssertNotNil(photo)
360 | XCTAssertNil(error)
361 |
362 | readyExpectation.fulfill()
363 | }
364 |
365 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
366 | XCTAssertNil(error, "Timeout")
367 | return
368 | }
369 | }
370 |
371 | func testGetPhotoValue() {
372 | let readyExpectation: XCTestExpectation = expectationWithDescription("ready")
373 |
374 |
375 | graphClient.me().photoValue().downloadWithCompletion { (url: NSURL?, response: NSURLResponse?, error: NSError?) in
376 | XCTAssertNotNil(url)
377 | XCTAssertNil(error)
378 |
379 | do {
380 | try NSFileManager.defaultManager().removeItemAtURL(url!)
381 | } catch let error as NSError {
382 | XCTAssertNil(error, "Timeout")
383 | }
384 |
385 | readyExpectation.fulfill()
386 | }
387 |
388 | waitForExpectationsWithTimeout(10) { (error: NSError?) in
389 | XCTAssertNil(error, "Timeout")
390 | return
391 | }
392 |
393 | }
394 |
395 |
396 |
397 |
398 | }
399 |
--------------------------------------------------------------------------------
/Graph-iOS-Swift-Snippets.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 960EBA121CEA8472007B8171 /* ConnectViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 960EBA111CEA8472007B8171 /* ConnectViewController.swift */; };
11 | 9682B8C31CEA92B500EEA064 /* AuthenticationProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9682B8C21CEA92B500EEA064 /* AuthenticationProvider.swift */; };
12 | 96B34CD41CE548C500B6F4E8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96B34CD31CE548C500B6F4E8 /* AppDelegate.swift */; };
13 | 96B34CD61CE548C500B6F4E8 /* MasterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96B34CD51CE548C500B6F4E8 /* MasterViewController.swift */; };
14 | 96B34CD81CE548C500B6F4E8 /* DetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96B34CD71CE548C500B6F4E8 /* DetailViewController.swift */; };
15 | 96B34CDB1CE548C500B6F4E8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 96B34CD91CE548C500B6F4E8 /* Main.storyboard */; };
16 | 96B34CDD1CE548C500B6F4E8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 96B34CDC1CE548C500B6F4E8 /* Assets.xcassets */; };
17 | 96B34CE01CE548C500B6F4E8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 96B34CDE1CE548C500B6F4E8 /* LaunchScreen.storyboard */; };
18 | 96B34CE81CE54D1000B6F4E8 /* Snippets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96B34CE71CE54D1000B6F4E8 /* Snippets.swift */; };
19 | 96C4ED931CF6165A00B97245 /* SampleImage.png in Resources */ = {isa = PBXBuildFile; fileRef = 96C4ED921CF6165A00B97245 /* SampleImage.png */; };
20 | 96C4ED971CF6707600B97245 /* UserSnippets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96C4ED961CF6707600B97245 /* UserSnippets.swift */; };
21 | 96C4ED991CF6709D00B97245 /* GroupsSnippets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96C4ED981CF6709D00B97245 /* GroupsSnippets.swift */; };
22 | 96C80A781CEA93AA005D8FC4 /* ApplicationConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96C80A771CEA93AA005D8FC4 /* ApplicationConstants.swift */; };
23 | 96E8E3761CF3D5CE00E3795C /* EmailBody.html in Resources */ = {isa = PBXBuildFile; fileRef = 96E8E3751CF3D5CE00E3795C /* EmailBody.html */; };
24 | BDBB226ADB67255D4C8ED655 /* Pods_Graph_iOS_Swift_Snippets.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7636C72C1EBF480F90E6E63E /* Pods_Graph_iOS_Swift_Snippets.framework */; };
25 | /* End PBXBuildFile section */
26 |
27 | /* Begin PBXFileReference section */
28 | 1A6FD9F3B470B571895415AF /* Pods-Graph-iOS-Swift-Snippets.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Graph-iOS-Swift-Snippets.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Graph-iOS-Swift-Snippets/Pods-Graph-iOS-Swift-Snippets.debug.xcconfig"; sourceTree = ""; };
29 | 238BA009227BB16D00A5BACD /* Graph-iOS-Swift-Snippets.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Graph-iOS-Swift-Snippets.entitlements"; sourceTree = ""; };
30 | 7636C72C1EBF480F90E6E63E /* Pods_Graph_iOS_Swift_Snippets.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Graph_iOS_Swift_Snippets.framework; sourceTree = BUILT_PRODUCTS_DIR; };
31 | 88338EAC202F86B11BFC9413 /* Pods-Graph-iOS-Swift-Snippets.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Graph-iOS-Swift-Snippets.release.xcconfig"; path = "Pods/Target Support Files/Pods-Graph-iOS-Swift-Snippets/Pods-Graph-iOS-Swift-Snippets.release.xcconfig"; sourceTree = ""; };
32 | 960EBA111CEA8472007B8171 /* ConnectViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectViewController.swift; sourceTree = ""; };
33 | 9682B8C21CEA92B500EEA064 /* AuthenticationProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthenticationProvider.swift; sourceTree = ""; };
34 | 96B34CD01CE548C500B6F4E8 /* Graph-iOS-Swift-Snippets.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Graph-iOS-Swift-Snippets.app"; sourceTree = BUILT_PRODUCTS_DIR; };
35 | 96B34CD31CE548C500B6F4E8 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
36 | 96B34CD51CE548C500B6F4E8 /* MasterViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterViewController.swift; sourceTree = ""; };
37 | 96B34CD71CE548C500B6F4E8 /* DetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailViewController.swift; sourceTree = ""; };
38 | 96B34CDA1CE548C500B6F4E8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
39 | 96B34CDC1CE548C500B6F4E8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
40 | 96B34CDF1CE548C500B6F4E8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
41 | 96B34CE11CE548C500B6F4E8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
42 | 96B34CE71CE54D1000B6F4E8 /* Snippets.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Snippets.swift; sourceTree = ""; };
43 | 96C4ED921CF6165A00B97245 /* SampleImage.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = SampleImage.png; sourceTree = ""; };
44 | 96C4ED961CF6707600B97245 /* UserSnippets.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserSnippets.swift; sourceTree = ""; };
45 | 96C4ED981CF6709D00B97245 /* GroupsSnippets.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GroupsSnippets.swift; sourceTree = ""; };
46 | 96C80A771CEA93AA005D8FC4 /* ApplicationConstants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplicationConstants.swift; sourceTree = ""; };
47 | 96E8E3751CF3D5CE00E3795C /* EmailBody.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = EmailBody.html; sourceTree = ""; };
48 | /* End PBXFileReference section */
49 |
50 | /* Begin PBXFrameworksBuildPhase section */
51 | 96B34CCD1CE548C500B6F4E8 /* Frameworks */ = {
52 | isa = PBXFrameworksBuildPhase;
53 | buildActionMask = 2147483647;
54 | files = (
55 | BDBB226ADB67255D4C8ED655 /* Pods_Graph_iOS_Swift_Snippets.framework in Frameworks */,
56 | );
57 | runOnlyForDeploymentPostprocessing = 0;
58 | };
59 | /* End PBXFrameworksBuildPhase section */
60 |
61 | /* Begin PBXGroup section */
62 | 7C1FBF706E7B6E2D09FCBD79 /* Pods */ = {
63 | isa = PBXGroup;
64 | children = (
65 | 1A6FD9F3B470B571895415AF /* Pods-Graph-iOS-Swift-Snippets.debug.xcconfig */,
66 | 88338EAC202F86B11BFC9413 /* Pods-Graph-iOS-Swift-Snippets.release.xcconfig */,
67 | );
68 | name = Pods;
69 | sourceTree = "";
70 | };
71 | 96B34CC71CE548C500B6F4E8 = {
72 | isa = PBXGroup;
73 | children = (
74 | 96B34CD21CE548C500B6F4E8 /* Graph-iOS-Swift-Snippets */,
75 | 96B34CD11CE548C500B6F4E8 /* Products */,
76 | 7C1FBF706E7B6E2D09FCBD79 /* Pods */,
77 | 9F04E14C6BD42E60D6DC42D4 /* Frameworks */,
78 | );
79 | sourceTree = "";
80 | };
81 | 96B34CD11CE548C500B6F4E8 /* Products */ = {
82 | isa = PBXGroup;
83 | children = (
84 | 96B34CD01CE548C500B6F4E8 /* Graph-iOS-Swift-Snippets.app */,
85 | );
86 | name = Products;
87 | sourceTree = "";
88 | };
89 | 96B34CD21CE548C500B6F4E8 /* Graph-iOS-Swift-Snippets */ = {
90 | isa = PBXGroup;
91 | children = (
92 | 238BA009227BB16D00A5BACD /* Graph-iOS-Swift-Snippets.entitlements */,
93 | 96C4ED9D1CF6716D00B97245 /* Application */,
94 | 96C4ED9C1CF6715600B97245 /* Views */,
95 | 96C4ED9B1CF6713300B97245 /* Authentication */,
96 | 96C4ED9A1CF6712200B97245 /* Controllers */,
97 | 96C4ED951CF6705D00B97245 /* Snippets */,
98 | 96C4ED941CF66BFD00B97245 /* Resources */,
99 | );
100 | path = "Graph-iOS-Swift-Snippets";
101 | sourceTree = "";
102 | };
103 | 96C4ED941CF66BFD00B97245 /* Resources */ = {
104 | isa = PBXGroup;
105 | children = (
106 | 96B34CE11CE548C500B6F4E8 /* Info.plist */,
107 | 96B34CDC1CE548C500B6F4E8 /* Assets.xcassets */,
108 | 96C4ED921CF6165A00B97245 /* SampleImage.png */,
109 | 96E8E3751CF3D5CE00E3795C /* EmailBody.html */,
110 | );
111 | name = Resources;
112 | sourceTree = "";
113 | };
114 | 96C4ED951CF6705D00B97245 /* Snippets */ = {
115 | isa = PBXGroup;
116 | children = (
117 | 96B34CE71CE54D1000B6F4E8 /* Snippets.swift */,
118 | 96C4ED961CF6707600B97245 /* UserSnippets.swift */,
119 | 96C4ED981CF6709D00B97245 /* GroupsSnippets.swift */,
120 | );
121 | name = Snippets;
122 | sourceTree = "";
123 | };
124 | 96C4ED9A1CF6712200B97245 /* Controllers */ = {
125 | isa = PBXGroup;
126 | children = (
127 | 96B34CD31CE548C500B6F4E8 /* AppDelegate.swift */,
128 | 960EBA111CEA8472007B8171 /* ConnectViewController.swift */,
129 | 96B34CD51CE548C500B6F4E8 /* MasterViewController.swift */,
130 | 96B34CD71CE548C500B6F4E8 /* DetailViewController.swift */,
131 | );
132 | name = Controllers;
133 | sourceTree = "";
134 | };
135 | 96C4ED9B1CF6713300B97245 /* Authentication */ = {
136 | isa = PBXGroup;
137 | children = (
138 | 9682B8C21CEA92B500EEA064 /* AuthenticationProvider.swift */,
139 | );
140 | name = Authentication;
141 | sourceTree = "";
142 | };
143 | 96C4ED9C1CF6715600B97245 /* Views */ = {
144 | isa = PBXGroup;
145 | children = (
146 | 96B34CD91CE548C500B6F4E8 /* Main.storyboard */,
147 | 96B34CDE1CE548C500B6F4E8 /* LaunchScreen.storyboard */,
148 | );
149 | name = Views;
150 | sourceTree = "";
151 | };
152 | 96C4ED9D1CF6716D00B97245 /* Application */ = {
153 | isa = PBXGroup;
154 | children = (
155 | 96C80A771CEA93AA005D8FC4 /* ApplicationConstants.swift */,
156 | );
157 | name = Application;
158 | sourceTree = "";
159 | };
160 | 9F04E14C6BD42E60D6DC42D4 /* Frameworks */ = {
161 | isa = PBXGroup;
162 | children = (
163 | 7636C72C1EBF480F90E6E63E /* Pods_Graph_iOS_Swift_Snippets.framework */,
164 | );
165 | name = Frameworks;
166 | sourceTree = "";
167 | };
168 | /* End PBXGroup section */
169 |
170 | /* Begin PBXNativeTarget section */
171 | 96B34CCF1CE548C500B6F4E8 /* Graph-iOS-Swift-Snippets */ = {
172 | isa = PBXNativeTarget;
173 | buildConfigurationList = 96B34CE41CE548C500B6F4E8 /* Build configuration list for PBXNativeTarget "Graph-iOS-Swift-Snippets" */;
174 | buildPhases = (
175 | 8548920E38D8B76ACEB030AB /* [CP] Check Pods Manifest.lock */,
176 | 96B34CCC1CE548C500B6F4E8 /* Sources */,
177 | 96B34CCD1CE548C500B6F4E8 /* Frameworks */,
178 | 96B34CCE1CE548C500B6F4E8 /* Resources */,
179 | 47FD35A13F916C6982C087C5 /* [CP] Embed Pods Frameworks */,
180 | );
181 | buildRules = (
182 | );
183 | dependencies = (
184 | );
185 | name = "Graph-iOS-Swift-Snippets";
186 | productName = "Graph-iOS-Swift-Snippets";
187 | productReference = 96B34CD01CE548C500B6F4E8 /* Graph-iOS-Swift-Snippets.app */;
188 | productType = "com.apple.product-type.application";
189 | };
190 | /* End PBXNativeTarget section */
191 |
192 | /* Begin PBXProject section */
193 | 96B34CC81CE548C500B6F4E8 /* Project object */ = {
194 | isa = PBXProject;
195 | attributes = {
196 | LastSwiftUpdateCheck = 0730;
197 | LastUpgradeCheck = 1020;
198 | ORGANIZATIONNAME = "Jason Kim";
199 | TargetAttributes = {
200 | 96B34CCF1CE548C500B6F4E8 = {
201 | CreatedOnToolsVersion = 7.3.1;
202 | SystemCapabilities = {
203 | com.apple.Keychain = {
204 | enabled = 1;
205 | };
206 | };
207 | };
208 | };
209 | };
210 | buildConfigurationList = 96B34CCB1CE548C500B6F4E8 /* Build configuration list for PBXProject "Graph-iOS-Swift-Snippets" */;
211 | compatibilityVersion = "Xcode 3.2";
212 | developmentRegion = en;
213 | hasScannedForEncodings = 0;
214 | knownRegions = (
215 | en,
216 | Base,
217 | );
218 | mainGroup = 96B34CC71CE548C500B6F4E8;
219 | productRefGroup = 96B34CD11CE548C500B6F4E8 /* Products */;
220 | projectDirPath = "";
221 | projectRoot = "";
222 | targets = (
223 | 96B34CCF1CE548C500B6F4E8 /* Graph-iOS-Swift-Snippets */,
224 | );
225 | };
226 | /* End PBXProject section */
227 |
228 | /* Begin PBXResourcesBuildPhase section */
229 | 96B34CCE1CE548C500B6F4E8 /* Resources */ = {
230 | isa = PBXResourcesBuildPhase;
231 | buildActionMask = 2147483647;
232 | files = (
233 | 96B34CE01CE548C500B6F4E8 /* LaunchScreen.storyboard in Resources */,
234 | 96C4ED931CF6165A00B97245 /* SampleImage.png in Resources */,
235 | 96B34CDD1CE548C500B6F4E8 /* Assets.xcassets in Resources */,
236 | 96B34CDB1CE548C500B6F4E8 /* Main.storyboard in Resources */,
237 | 96E8E3761CF3D5CE00E3795C /* EmailBody.html in Resources */,
238 | );
239 | runOnlyForDeploymentPostprocessing = 0;
240 | };
241 | /* End PBXResourcesBuildPhase section */
242 |
243 | /* Begin PBXShellScriptBuildPhase section */
244 | 47FD35A13F916C6982C087C5 /* [CP] Embed Pods Frameworks */ = {
245 | isa = PBXShellScriptBuildPhase;
246 | buildActionMask = 2147483647;
247 | files = (
248 | );
249 | inputFileListPaths = (
250 | );
251 | inputPaths = (
252 | "${PODS_ROOT}/Target Support Files/Pods-Graph-iOS-Swift-Snippets/Pods-Graph-iOS-Swift-Snippets-frameworks.sh",
253 | "${BUILT_PRODUCTS_DIR}/MSAL/MSAL.framework",
254 | "${BUILT_PRODUCTS_DIR}/MSGraphSDK/MSGraphSDK.framework",
255 | );
256 | name = "[CP] Embed Pods Frameworks";
257 | outputFileListPaths = (
258 | );
259 | outputPaths = (
260 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MSAL.framework",
261 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MSGraphSDK.framework",
262 | );
263 | runOnlyForDeploymentPostprocessing = 0;
264 | shellPath = /bin/sh;
265 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Graph-iOS-Swift-Snippets/Pods-Graph-iOS-Swift-Snippets-frameworks.sh\"\n";
266 | showEnvVarsInLog = 0;
267 | };
268 | 8548920E38D8B76ACEB030AB /* [CP] Check Pods Manifest.lock */ = {
269 | isa = PBXShellScriptBuildPhase;
270 | buildActionMask = 2147483647;
271 | files = (
272 | );
273 | inputPaths = (
274 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
275 | "${PODS_ROOT}/Manifest.lock",
276 | );
277 | name = "[CP] Check Pods Manifest.lock";
278 | outputPaths = (
279 | "$(DERIVED_FILE_DIR)/Pods-Graph-iOS-Swift-Snippets-checkManifestLockResult.txt",
280 | );
281 | runOnlyForDeploymentPostprocessing = 0;
282 | shellPath = /bin/sh;
283 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
284 | showEnvVarsInLog = 0;
285 | };
286 | /* End PBXShellScriptBuildPhase section */
287 |
288 | /* Begin PBXSourcesBuildPhase section */
289 | 96B34CCC1CE548C500B6F4E8 /* Sources */ = {
290 | isa = PBXSourcesBuildPhase;
291 | buildActionMask = 2147483647;
292 | files = (
293 | 960EBA121CEA8472007B8171 /* ConnectViewController.swift in Sources */,
294 | 96B34CD81CE548C500B6F4E8 /* DetailViewController.swift in Sources */,
295 | 96C4ED971CF6707600B97245 /* UserSnippets.swift in Sources */,
296 | 96B34CD61CE548C500B6F4E8 /* MasterViewController.swift in Sources */,
297 | 96C4ED991CF6709D00B97245 /* GroupsSnippets.swift in Sources */,
298 | 96B34CD41CE548C500B6F4E8 /* AppDelegate.swift in Sources */,
299 | 96B34CE81CE54D1000B6F4E8 /* Snippets.swift in Sources */,
300 | 9682B8C31CEA92B500EEA064 /* AuthenticationProvider.swift in Sources */,
301 | 96C80A781CEA93AA005D8FC4 /* ApplicationConstants.swift in Sources */,
302 | );
303 | runOnlyForDeploymentPostprocessing = 0;
304 | };
305 | /* End PBXSourcesBuildPhase section */
306 |
307 | /* Begin PBXVariantGroup section */
308 | 96B34CD91CE548C500B6F4E8 /* Main.storyboard */ = {
309 | isa = PBXVariantGroup;
310 | children = (
311 | 96B34CDA1CE548C500B6F4E8 /* Base */,
312 | );
313 | name = Main.storyboard;
314 | sourceTree = "";
315 | };
316 | 96B34CDE1CE548C500B6F4E8 /* LaunchScreen.storyboard */ = {
317 | isa = PBXVariantGroup;
318 | children = (
319 | 96B34CDF1CE548C500B6F4E8 /* Base */,
320 | );
321 | name = LaunchScreen.storyboard;
322 | sourceTree = "";
323 | };
324 | /* End PBXVariantGroup section */
325 |
326 | /* Begin XCBuildConfiguration section */
327 | 96B34CE21CE548C500B6F4E8 /* Debug */ = {
328 | isa = XCBuildConfiguration;
329 | buildSettings = {
330 | ALWAYS_SEARCH_USER_PATHS = NO;
331 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
332 | CLANG_ANALYZER_NONNULL = YES;
333 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
334 | CLANG_CXX_LIBRARY = "libc++";
335 | CLANG_ENABLE_MODULES = YES;
336 | CLANG_ENABLE_OBJC_ARC = YES;
337 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
338 | CLANG_WARN_BOOL_CONVERSION = YES;
339 | CLANG_WARN_COMMA = YES;
340 | CLANG_WARN_CONSTANT_CONVERSION = YES;
341 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
342 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
343 | CLANG_WARN_EMPTY_BODY = YES;
344 | CLANG_WARN_ENUM_CONVERSION = YES;
345 | CLANG_WARN_INFINITE_RECURSION = YES;
346 | CLANG_WARN_INT_CONVERSION = YES;
347 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
348 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
349 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
350 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
351 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
352 | CLANG_WARN_STRICT_PROTOTYPES = YES;
353 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
354 | CLANG_WARN_UNREACHABLE_CODE = YES;
355 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
356 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
357 | COPY_PHASE_STRIP = NO;
358 | DEBUG_INFORMATION_FORMAT = dwarf;
359 | ENABLE_STRICT_OBJC_MSGSEND = YES;
360 | ENABLE_TESTABILITY = YES;
361 | GCC_C_LANGUAGE_STANDARD = gnu99;
362 | GCC_DYNAMIC_NO_PIC = NO;
363 | GCC_NO_COMMON_BLOCKS = YES;
364 | GCC_OPTIMIZATION_LEVEL = 0;
365 | GCC_PREPROCESSOR_DEFINITIONS = (
366 | "DEBUG=1",
367 | "$(inherited)",
368 | );
369 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
370 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
371 | GCC_WARN_UNDECLARED_SELECTOR = YES;
372 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
373 | GCC_WARN_UNUSED_FUNCTION = YES;
374 | GCC_WARN_UNUSED_VARIABLE = YES;
375 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
376 | MTL_ENABLE_DEBUG_INFO = YES;
377 | ONLY_ACTIVE_ARCH = YES;
378 | SDKROOT = iphoneos;
379 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
380 | };
381 | name = Debug;
382 | };
383 | 96B34CE31CE548C500B6F4E8 /* Release */ = {
384 | isa = XCBuildConfiguration;
385 | buildSettings = {
386 | ALWAYS_SEARCH_USER_PATHS = NO;
387 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
388 | CLANG_ANALYZER_NONNULL = YES;
389 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
390 | CLANG_CXX_LIBRARY = "libc++";
391 | CLANG_ENABLE_MODULES = YES;
392 | CLANG_ENABLE_OBJC_ARC = YES;
393 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
394 | CLANG_WARN_BOOL_CONVERSION = YES;
395 | CLANG_WARN_COMMA = YES;
396 | CLANG_WARN_CONSTANT_CONVERSION = YES;
397 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
398 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
399 | CLANG_WARN_EMPTY_BODY = YES;
400 | CLANG_WARN_ENUM_CONVERSION = YES;
401 | CLANG_WARN_INFINITE_RECURSION = YES;
402 | CLANG_WARN_INT_CONVERSION = YES;
403 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
404 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
405 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
406 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
407 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
408 | CLANG_WARN_STRICT_PROTOTYPES = YES;
409 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
410 | CLANG_WARN_UNREACHABLE_CODE = YES;
411 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
412 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
413 | COPY_PHASE_STRIP = NO;
414 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
415 | ENABLE_NS_ASSERTIONS = NO;
416 | ENABLE_STRICT_OBJC_MSGSEND = YES;
417 | GCC_C_LANGUAGE_STANDARD = gnu99;
418 | GCC_NO_COMMON_BLOCKS = YES;
419 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
420 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
421 | GCC_WARN_UNDECLARED_SELECTOR = YES;
422 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
423 | GCC_WARN_UNUSED_FUNCTION = YES;
424 | GCC_WARN_UNUSED_VARIABLE = YES;
425 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
426 | MTL_ENABLE_DEBUG_INFO = NO;
427 | SDKROOT = iphoneos;
428 | SWIFT_COMPILATION_MODE = wholemodule;
429 | VALIDATE_PRODUCT = YES;
430 | };
431 | name = Release;
432 | };
433 | 96B34CE51CE548C500B6F4E8 /* Debug */ = {
434 | isa = XCBuildConfiguration;
435 | baseConfigurationReference = 1A6FD9F3B470B571895415AF /* Pods-Graph-iOS-Swift-Snippets.debug.xcconfig */;
436 | buildSettings = {
437 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
438 | CLANG_ENABLE_MODULES = YES;
439 | CODE_SIGN_ENTITLEMENTS = "Graph-iOS-Swift-Snippets/Graph-iOS-Swift-Snippets.entitlements";
440 | DEVELOPMENT_TEAM = "";
441 | INFOPLIST_FILE = "Graph-iOS-Swift-Snippets/Info.plist";
442 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
443 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
444 | PRODUCT_BUNDLE_IDENTIFIER = "com.microsoft.Graph-iOS-Swift-Snippets";
445 | PRODUCT_NAME = "$(TARGET_NAME)";
446 | SWIFT_OBJC_BRIDGING_HEADER = "";
447 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
448 | SWIFT_VERSION = 4.2;
449 | TARGETED_DEVICE_FAMILY = "1,2";
450 | };
451 | name = Debug;
452 | };
453 | 96B34CE61CE548C500B6F4E8 /* Release */ = {
454 | isa = XCBuildConfiguration;
455 | baseConfigurationReference = 88338EAC202F86B11BFC9413 /* Pods-Graph-iOS-Swift-Snippets.release.xcconfig */;
456 | buildSettings = {
457 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
458 | CLANG_ENABLE_MODULES = YES;
459 | CODE_SIGN_ENTITLEMENTS = "Graph-iOS-Swift-Snippets/Graph-iOS-Swift-Snippets.entitlements";
460 | DEVELOPMENT_TEAM = "";
461 | INFOPLIST_FILE = "Graph-iOS-Swift-Snippets/Info.plist";
462 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
463 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
464 | PRODUCT_BUNDLE_IDENTIFIER = "com.microsoft.Graph-iOS-Swift-Snippets";
465 | PRODUCT_NAME = "$(TARGET_NAME)";
466 | SWIFT_OBJC_BRIDGING_HEADER = "";
467 | SWIFT_VERSION = 4.2;
468 | TARGETED_DEVICE_FAMILY = "1,2";
469 | };
470 | name = Release;
471 | };
472 | /* End XCBuildConfiguration section */
473 |
474 | /* Begin XCConfigurationList section */
475 | 96B34CCB1CE548C500B6F4E8 /* Build configuration list for PBXProject "Graph-iOS-Swift-Snippets" */ = {
476 | isa = XCConfigurationList;
477 | buildConfigurations = (
478 | 96B34CE21CE548C500B6F4E8 /* Debug */,
479 | 96B34CE31CE548C500B6F4E8 /* Release */,
480 | );
481 | defaultConfigurationIsVisible = 0;
482 | defaultConfigurationName = Release;
483 | };
484 | 96B34CE41CE548C500B6F4E8 /* Build configuration list for PBXNativeTarget "Graph-iOS-Swift-Snippets" */ = {
485 | isa = XCConfigurationList;
486 | buildConfigurations = (
487 | 96B34CE51CE548C500B6F4E8 /* Debug */,
488 | 96B34CE61CE548C500B6F4E8 /* Release */,
489 | );
490 | defaultConfigurationIsVisible = 0;
491 | defaultConfigurationName = Release;
492 | };
493 | /* End XCConfigurationList section */
494 | };
495 | rootObject = 96B34CC81CE548C500B6F4E8 /* Project object */;
496 | }
497 |
--------------------------------------------------------------------------------
/Graph-iOS-Swift-Snippets/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
--------------------------------------------------------------------------------
/Graph-iOS-Swift-Snippets/UserSnippets.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 |
6 | import Foundation
7 | import MSGraphSDK
8 |
9 | // MARK: - User snippets
10 |
11 | // Returns select information about the signed-in user from Azure Active Directory. Applies to personal or work accounts
12 | struct GetMe: Snippet
13 | {
14 | let name = "Get me"
15 | let needAdminAccess: Bool = false
16 |
17 | func execute(with completion: @escaping (_ result: Result) -> Void)
18 | {
19 | Snippets.graphClient.me().request()?.getWithCompletion({ (user, error) in
20 | if let nsError = error as NSError? {
21 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
22 | }
23 | else {
24 | let displayName = user?.displayName ?? ""
25 | let displayString = "Retrieval of user account information succeeded for \(displayName)"
26 | completion(.Success(displayText: displayString))
27 | }
28 | })
29 |
30 | }
31 | }
32 |
33 | // Returns all of the users in your tenant's directory.
34 | // Applies to personal or work accounts.
35 | // nextRequest is a subsequent request if there are more users to be loaded.
36 | struct GetUsers: Snippet
37 | {
38 | let name = "Get users"
39 | let needAdminAccess: Bool = false
40 |
41 | func execute(with completion: @escaping (_ result: Result) -> Void)
42 | {
43 | Snippets.graphClient.users().request()?.getWithCompletion({ (userCollection, nextRequest, error) in
44 | if let nsError = error as NSError? {
45 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
46 | }
47 | else {
48 | var displayString = "List of users:\n"
49 | if let users = userCollection {
50 |
51 | for user: MSGraphUser in users.value as! [MSGraphUser] {
52 | displayString += user.displayName + "\n"
53 | }
54 | }
55 |
56 | if let _ = nextRequest {
57 | displayString += "Next request available for more users"
58 | }
59 | completion(.Success(displayText: displayString))
60 | }
61 | })
62 | }
63 | }
64 |
65 | // Gets the signed-in user's drive from OneDrive.
66 | // Applies to personal or work accounts
67 | struct GetDrive: Snippet
68 | {
69 | let name = "Get drive"
70 | let needAdminAccess: Bool = false
71 |
72 | func execute(with completion: @escaping (_ result: Result) -> Void)
73 | {
74 | Snippets.graphClient.me().drive().request()?.getWithCompletion({ (drive, error) in
75 | if let nsError = error as NSError? {
76 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
77 | }
78 | else {
79 | var displayString = "Drive information:\n"
80 | if let userDrive = drive {
81 | displayString += "Drive type is " + userDrive.driveType + "\n"
82 | displayString += "Total Quote is " + String(userDrive.quota.total)
83 | }
84 | completion(.Success(displayText: displayString))
85 | }
86 | })
87 | }
88 |
89 | }
90 |
91 | // Gets the signed-in user's events.
92 | // Applies to personal or work accounts
93 | struct GetEvents: Snippet
94 | {
95 | let name = "Get events"
96 | let needAdminAccess: Bool = false
97 |
98 | func execute(with completion: @escaping (_ result: Result) -> Void)
99 | {
100 | Snippets.graphClient.me().events().request()?.getWithCompletion({ (eventCollection, nextRequest, error) in
101 | if let nsError = error as NSError? {
102 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
103 | }
104 | else {
105 | var displayString = "List of events (subjects):\n"
106 | if let events = eventCollection {
107 | for event: MSGraphEvent in events.value as! [MSGraphEvent] {
108 | displayString += event.subject + "\n\n"
109 | }
110 | }
111 |
112 | if let _ = nextRequest {
113 | displayString += "Next request available for more users"
114 | }
115 |
116 | completion(.Success(displayText: displayString))
117 | }
118 | })
119 | }
120 | }
121 |
122 |
123 | // Create an event in the signed in user's calendar.
124 | // Applies to personal or work accounts
125 | struct CreateEvent: Snippet
126 | {
127 | let name = "Create event"
128 | let needAdminAccess: Bool = false
129 |
130 | func execute(with completion: @escaping (_ result: Result) -> Void)
131 | {
132 | let event = Snippets.createEventObject(isSeries: false)
133 |
134 | Snippets.graphClient.me().calendar().events()?.request()?.add(event, withCompletion: { (event, error) in
135 | if let nsError = error as NSError? {
136 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
137 | } else {
138 | let entityId = event?.entityId ?? ""
139 | let displayString = "Event created with id \(entityId)"
140 | completion(.Success(displayText: displayString))
141 | }
142 | })
143 | }
144 | }
145 |
146 | //
147 | // Updates an event in the signed in user's calendar.
148 | // Applies to personal or work accounts
149 | struct UpdateEvent: Snippet
150 | {
151 | let name = "Update event"
152 | let needAdminAccess: Bool = false
153 |
154 | func execute(with completion: @escaping (_ result: Result) -> Void)
155 | {
156 | // Enter a valid event id
157 | let eventId = "ENTER_VALID_EVENT_ID"
158 |
159 | // Get an event and then update
160 |
161 | Snippets.graphClient.me().events(eventId).request()?.getWithCompletion({ (event, error) in
162 | if let nsError = error as NSError? {
163 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
164 | }
165 | else {
166 | guard let validEvent = event else {
167 | completion(.Failure(error: MSGraphError.UnexpectecError(errorString: "Event ID not returned")))
168 | return
169 | }
170 | validEvent.subject = "New Name"
171 |
172 | Snippets.graphClient.me().events(validEvent.entityId).request()?.update(validEvent, withCompletion: { (updatedEvent, error) in
173 | if let nsError = error as NSError? {
174 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
175 | }
176 | else {
177 | let displayString = "Event updated with a new subject"
178 | completion(.Success(displayText: displayString))
179 | }
180 | })
181 | }
182 | })
183 | }
184 | }
185 |
186 |
187 | // Deletes an event in the signed in user's calendar.
188 | // Applies to personal or work accounts
189 | struct DeleteEevnt: Snippet
190 | {
191 | let name = "Delete event"
192 | let needAdminAccess: Bool = false
193 |
194 | func execute(with completion: @escaping (_ result: Result) -> Void)
195 | {
196 | // Enter a valid event id
197 | let eventId = "ENTER_VALID_EVENT_ID"
198 |
199 | Snippets.graphClient.me().events(eventId)?.request()?.delete(completion: { (error) in
200 | if let nsError = error as NSError? {
201 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
202 | }
203 | else {
204 | completion(.Success(displayText: "Deleted calendar event id: \(eventId)"))
205 | }
206 | })
207 | }
208 | }
209 |
210 |
211 | // Gets the signed-in user's messages.
212 | // Applies to personal or work accounts
213 | struct GetMessages: Snippet
214 | {
215 | let name = "Get messages"
216 | let needAdminAccess: Bool = false
217 |
218 | func execute(with completion: @escaping (_ result: Result) -> Void)
219 | {
220 | Snippets.graphClient.me().messages().request()?.getWithCompletion({ (messageCollection, nextRequest, error) in
221 | if let nsError = error as NSError? {
222 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
223 | }
224 | else {
225 | var displayString = "List of messages:\n"
226 | if let messages = messageCollection {
227 |
228 | for message: MSGraphMessage in messages.value as! [MSGraphMessage] {
229 | displayString += message.subject + "\n\n"
230 | }
231 | }
232 |
233 | if let _ = nextRequest {
234 | displayString += "Next request available for more messages"
235 | }
236 |
237 | completion(.Success(displayText: displayString))
238 | }
239 | })
240 |
241 | }
242 | }
243 |
244 |
245 | // Create and send a message as the signed-in user.
246 | // Applies to personal or work accounts
247 | struct SendMessage: Snippet
248 | {
249 | let name = "Send mail"
250 | let needAdminAccess: Bool = false
251 |
252 | func execute(with completion: @escaping (_ result: Result) -> Void)
253 | {
254 | // ENTER EMAIL ADDRESS
255 | let recipientEmailAddress = "ENTER_EMAIL_ADDRESS"
256 |
257 | // ===================================================================
258 | // Set message
259 | // ===================================================================
260 | let message = MSGraphMessage()
261 |
262 | // Set recipients
263 | let toRecipient = MSGraphRecipient()
264 | let msEmailAddress = MSGraphEmailAddress()
265 | msEmailAddress.address = recipientEmailAddress
266 | toRecipient.emailAddress = msEmailAddress
267 | let toRecipientList = [toRecipient]
268 | message.toRecipients = toRecipientList
269 |
270 | // Subject
271 | message.subject = "Mail received from the Office 365 iOS Microsoft Graph Snippets Sample"
272 |
273 | // Body
274 | let messageBody = MSGraphItemBody()
275 | messageBody.contentType = MSGraphBodyType.text()
276 | messageBody.content = "Mail received from the Office 365 iOS Microsoft Graph Snippets Sample"
277 |
278 | message.body = messageBody
279 |
280 | // ===================================================================
281 | // Send message
282 | // ===================================================================
283 |
284 | guard let mailRequest = Snippets.graphClient.me()?.sendMail(with: message, saveToSentItems: true)?.request() else { return }
285 | mailRequest.execute { (response, error) in
286 | if let nsError = error as NSError? {
287 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
288 | }
289 | else {
290 | completion(.Success(displayText: "Message sent"))
291 | }
292 | }
293 | }
294 | }
295 |
296 |
297 | // Create and send a message as the signed-in user.
298 | // This one uses HTML message.
299 | // Applies to personal or work accounts
300 | struct SendMessageHTML: Snippet
301 | {
302 | let name = "Send HTML mail"
303 | let needAdminAccess: Bool = false
304 | func execute(with completion: @escaping (_ result: Result) -> Void)
305 | {
306 | // ENTER EMAIL ADDRESS
307 | let recipientEmailAddress = "ENTER_EMAIL_ADDRESS"
308 |
309 | // ===================================================================
310 | // Set message
311 | // ===================================================================
312 | let message = MSGraphMessage()
313 |
314 | // Set recipients
315 | let toRecipient = MSGraphRecipient()
316 | let msEmailAddress = MSGraphEmailAddress()
317 | msEmailAddress.address = recipientEmailAddress
318 | toRecipient.emailAddress = msEmailAddress
319 | let toRecipientList = [toRecipient]
320 | message.toRecipients = toRecipientList
321 |
322 | // Subject
323 | message.subject = "Mail received from the Office 365 iOS Microsoft Graph Snippets Sample"
324 |
325 | // Body
326 | let messageBody = MSGraphItemBody()
327 | messageBody.contentType = MSGraphBodyType.html()
328 |
329 | guard let emailBodyFilePath = Bundle.main.path(forResource: "EmailBody", ofType: "html") else {
330 | completion(.Failure(error: MSGraphError.UnexpectecError(errorString: "EmailBody.html not found in resources")))
331 | return
332 | }
333 | messageBody.content = try! String(contentsOfFile: emailBodyFilePath, encoding: String.Encoding.utf8)
334 | message.body = messageBody
335 |
336 | // ===================================================================
337 | // Send message
338 | // ===================================================================
339 | let mailRequest = Snippets.graphClient.me().sendMail(with: message, saveToSentItems: true).request()
340 | mailRequest?.execute(completion: { (response, error) in
341 | if let nsError = error as NSError? {
342 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
343 | }
344 | else {
345 | completion(.Success(displayText: "Message sent"))
346 | }
347 | })
348 | }
349 | }
350 |
351 | // Returns all of the user's files.
352 | // Applies to personal or work accounts
353 | struct GetUserFiles: Snippet
354 | {
355 | let name = "Get user files"
356 | let needAdminAccess: Bool = false
357 |
358 | func execute(with completion: @escaping (_ result: Result) -> Void)
359 | {
360 | Snippets.graphClient.me().drive().root().children()?.request()?.getWithCompletion({ (fileCollection, nextRequest, error) in
361 | if let nsError = error as NSError? {
362 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
363 | } else {
364 | var displayString = "List of files: \n"
365 | if let files = fileCollection {
366 |
367 | for file: MSGraphDriveItem in files.value as! [MSGraphDriveItem] {
368 | let name = file.name ?? ""
369 | displayString += "\(name): \(file.size) \n"
370 | }
371 | }
372 |
373 | if let _ = nextRequest {
374 | displayString += "Next request available for more files"
375 | }
376 |
377 | completion(.Success(displayText: displayString))
378 | }
379 | })
380 | }
381 | }
382 |
383 | // Create a text file in the signed in user's OneDrive account.
384 | // If a file already exists it will be overwritten.
385 | // Applies to personal or work accounts
386 | struct CreateTextFile: Snippet
387 | {
388 | let name = "Create text file"
389 | let needAdminAccess: Bool = false
390 | func execute(with completion: @escaping (_ result: Result) -> Void)
391 | {
392 | let uploadData = "Test".data(using: String.Encoding.utf8)
393 |
394 | Snippets.graphClient.me().drive().root().item(byPath: "Test Folder/testTextfile.text").contentRequest()?.upload(from: uploadData, completion: { (item, error) in
395 | if let nsError = error as NSError? {
396 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
397 | } else {
398 | completion(.Success(displayText: "File created at Test Folder/testTextfile.text"))
399 | }
400 | })
401 | }
402 | }
403 |
404 | // Upload an image file in the signed in user's OneDrive account.
405 | // Applies to personal or work accounts
406 | struct UploadFile: Snippet
407 | {
408 | let name = "Upload image file"
409 | let needAdminAccess: Bool = false
410 | func execute(with completion: @escaping (_ result: Result) -> Void)
411 | {
412 | let urlpath = Bundle.main.path(forResource: "SampleImage", ofType: "png")
413 | let url = NSURL.fileURL(withPath: urlpath!)
414 |
415 | Snippets.graphClient.me().drive().root().item(byPath: "sampleImage.png").contentRequest()?.upload(fromFile: url, completion: { (item, error) in
416 | if let nsError = error as NSError? {
417 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
418 | } else {
419 | completion(.Success(displayText: "File uploaded (sampleImage.png)"))
420 | }
421 | })
422 | }
423 | }
424 |
425 | // Creates a new folder in the signed in user's OneDrive account.
426 | // Applies to personal or work accounts
427 | struct CreateFolder: Snippet
428 | {
429 | let name = "Create folder"
430 | let needAdminAccess: Bool = false
431 | func execute(with completion: @escaping (_ result: Result) -> Void)
432 | {
433 | let driveItem = MSGraphDriveItem(dictionary: [MSNameConflict.rename().key: MSNameConflict.rename().value])
434 | driveItem?.name = "TestFolder"
435 | driveItem?.folder = MSGraphFolder()
436 |
437 | // Use itemByPath as below to create a subfolder under an existing folder
438 | // Snippets.graphClient.me().drive().root().itemByPath("existingFolder").request().getWithCompletion(
439 | Snippets.graphClient.me().drive().root().request()?.getWithCompletion({ (item, error) in
440 | if let nsError = error as NSError? {
441 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
442 | }
443 |
444 | guard let validItem = item else {
445 | completion(.Failure(error: MSGraphError.UnexpectecError(errorString: "Valid item not returned for a path")))
446 | return
447 | }
448 |
449 | Snippets.graphClient.me().drive().items(validItem.entityId).children().request()?.add(driveItem, withCompletion: { (item, error) in
450 | if let nsError = error as NSError? {
451 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
452 | } else {
453 | let name = item?.name ?? ""
454 | completion(.Success(displayText: "Created a folder \(name)"))
455 | }
456 | })
457 | })
458 | }
459 | }
460 |
461 |
462 | // Downloads a file into the signed in user's OneDrive account.
463 | // Applies to personal or work accounts
464 | struct DownloadFile: Snippet
465 | {
466 | let name = "Download file"
467 | let needAdminAccess: Bool = false
468 | func execute(with completion: @escaping (_ result: Result) -> Void) {
469 |
470 | // Enter a valid event id
471 | let fileId = "ENTER_VALID_ID"
472 |
473 | Snippets.graphClient.me().drive().items(fileId).contentRequest()?.download(completion: { (url, response, error) in
474 | if let nsError = error as NSError? {
475 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
476 | } else {
477 | guard let downloadedUrl = url else {
478 | completion(.Failure(error: MSGraphError.UnexpectecError(errorString: "Downloaded URL not found")))
479 | return
480 | }
481 | completion(.Success(displayText: "Downloaded file at \(downloadedUrl.absoluteString)"))
482 | }
483 | })
484 | }
485 | }
486 |
487 | // Uploads a file in the signed in user's OneDrive account.
488 | // Applies to personal or work accounts
489 | struct UpdateFile: Snippet
490 | {
491 | let name = "Update file"
492 | let needAdminAccess: Bool = false
493 | func execute(with completion: @escaping (_ result: Result) -> Void) {
494 |
495 | // Enter a valid event id
496 | let fileId = "ENTER_VALID_ID"
497 |
498 | let uploadData = "newTextValue".data(using: String.Encoding.utf8)
499 | Snippets.graphClient.me().drive().items(fileId).contentRequest()?.upload(from: uploadData, completion: { (updatedItem, error) in
500 | if let nsError = error as NSError? {
501 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
502 | } else {
503 | let name = updatedItem?.name ?? ""
504 | completion(.Success(displayText: "File \(name) contents updated"))
505 | }
506 | })
507 | }
508 | }
509 |
510 | // Renames a file in the signed in user's OneDrive account.
511 | // Applies to personal or work accounts
512 | struct RenameFile: Snippet
513 | {
514 | let name = "Rename file"
515 | let needAdminAccess: Bool = false
516 | func execute(with completion: @escaping (_ result: Result) -> Void) {
517 |
518 | // Enter a valid event id
519 | let fileId = "ENTER_VALID_ID"
520 |
521 | Snippets.graphClient.me().drive().items(fileId).request()?.getWithCompletion({ (file, error) in
522 | if let nsError = error as NSError? {
523 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
524 | }
525 | else {
526 | guard let validFile = file else {
527 | completion(.Failure(error: MSGraphError.UnexpectecError(errorString: "Valid file not returned")))
528 | return
529 | }
530 |
531 | validFile.name = "NewTextFileName"
532 | Snippets.graphClient.me().drive().items(validFile.entityId).request()?.update(validFile, withCompletion: { (updateItem, error) in
533 | if let nsError = error as NSError? {
534 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
535 | } else {
536 | let name = updateItem?.name ?? ""
537 | completion(.Success(displayText: "New name is \(name)"))
538 | }
539 | })
540 | }
541 | })
542 | }
543 | }
544 |
545 |
546 | // Deletes a file in the signed in user's OneDrive account.
547 | // Applies to personal or work accounts
548 | struct DeleteFile: Snippet
549 | {
550 | let name = "Delete file"
551 | let needAdminAccess: Bool = false
552 | func execute(with completion: @escaping (_ result: Result) -> Void) {
553 |
554 | // Enter a valid event id
555 | let fileId = "ENTER_VALID_ID"
556 |
557 | Snippets.graphClient.me().drive().items(fileId).request()?.delete(completion: { (error) in
558 | if let nsError = error as NSError? {
559 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
560 | } else {
561 | completion(.Success(displayText: "File deleted"))
562 | }
563 | })
564 | }
565 | }
566 |
567 |
568 | // Get user's manager if they have one.
569 | // Applies to work accounts only
570 | struct GetManager: Snippet
571 | {
572 | let name = "Get manager"
573 | let needAdminAccess: Bool = false
574 | func execute(with completion: @escaping (_ result: Result) -> Void)
575 | {
576 | Snippets.graphClient.me().manager().request()?.getWithCompletion({ (directoryObject, error) in
577 | if let nsError = error as NSError? {
578 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
579 | } else {
580 | var displayString: String = "Manager information: \n"
581 |
582 | if let manager = directoryObject {
583 | if let managerName = manager.dictionaryFromItem()["displayName"] {
584 | displayString += "Manager is \(managerName)\n\n"
585 | }
586 | else {
587 | displayString += "No manager"
588 | }
589 | displayString += "Full object is\n\(manager)"
590 | }
591 | completion(.Success(displayText: "\(displayString)"))
592 | }
593 | })
594 | }
595 | }
596 |
597 |
598 | // Get user's direct reports
599 | // Applies to work accounts only
600 | struct GetDirects: Snippet
601 | {
602 | let name = "Get directs"
603 | let needAdminAccess: Bool = false
604 | func execute(with completion: @escaping (_ result: Result) -> Void)
605 | {
606 | Snippets.graphClient.me().directReports().request()?.getWithCompletion({ (directCollection, nextRequest, error) in
607 | if let nsError = error as NSError? {
608 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
609 | } else {
610 | var displayString = "List of directs: \n"
611 | if let directs = directCollection {
612 |
613 | for direct: MSGraphDirectoryObject in directs.value as! [MSGraphDirectoryObject] {
614 | guard let name = direct.dictionaryFromItem()["displayName"] else {
615 | completion(.Failure(error: MSGraphError.UnexpectecError(errorString: "Display name not found")))
616 | return
617 | }
618 | displayString += "\(name)\n"
619 | }
620 | }
621 |
622 | if let _ = nextRequest {
623 | displayString += "Next request available for more users"
624 | }
625 |
626 | completion(.Success(displayText: "\(displayString)"))
627 | }
628 | })
629 | }
630 | }
631 |
632 | // Gets the signed-in user's photo data if they have a photo.
633 | // This snippet will return metadata for the user photo.
634 | // Applies to work accounts only
635 | struct GetPhoto: Snippet
636 | {
637 | let name = "Get photo"
638 | let needAdminAccess: Bool = false
639 | func execute(with completion: @escaping (_ result: Result) -> Void)
640 | {
641 | Snippets.graphClient.me().photo().request()?.getWithCompletion({ (photo, error) in
642 | if let nsError = error as NSError? {
643 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
644 | } else {
645 | guard let photoMetric = photo else {
646 | completion(.Failure(error: MSGraphError.UnexpectecError(errorString: "Photo width and height not found")))
647 | return
648 | }
649 | let displayString = "Photo size is \(photoMetric.height) x \(photoMetric.width)"
650 | completion(.Success(displayText: "\(displayString)"))
651 | }
652 | })
653 | }
654 | }
655 |
656 | // Creates a new user in the tenant.
657 | // Applicable to work accounts with admin rights
658 | struct GetPhotoValue: Snippet
659 | {
660 | let name = "Get photo value"
661 | let needAdminAccess: Bool = false
662 | func execute(with completion: @escaping (_ result: Result) -> Void)
663 | {
664 | Snippets.graphClient.me().photoValue()?.download(completion: { (url, response, error) in
665 | if let nsError = error as NSError? {
666 | completion(.Failure(error: MSGraphError.NSErrorType(error: nsError)))
667 | return
668 | }
669 |
670 | guard let picUrl = url else {
671 | completion(.Failure(error: MSGraphError.UnexpectecError(errorString: "No downloaded URL")))
672 | return
673 | }
674 |
675 | let picData = try! Data(contentsOf: picUrl)
676 | let picImage = UIImage(data: picData)
677 |
678 | completion(.SuccessDownloadImage(displayImage: picImage))
679 | })
680 | }
681 | }
682 |
683 | // MARK: - Helper methods
684 |
685 | extension Snippets
686 | {
687 | // Helper for creating a event object.
688 | // Set series to true to create a recurring event.
689 | static func createEventObject(isSeries series: Bool) -> MSGraphEvent
690 | {
691 | let event = MSGraphEvent()
692 | event.subject = "Event Subject"
693 | event.body = MSGraphItemBody()
694 | event.body.contentType = MSGraphBodyType.text()
695 | event.body.content = "Sample event body"
696 | event.importance = MSGraphImportance.normal()
697 |
698 | let startDate: Date = Date(timeInterval: 30 * 60, since: Date())
699 | let endDate: Date = Date(timeInterval: 30 * 60, since: startDate)
700 |
701 | let dateFormatter = DateFormatter()
702 | dateFormatter.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss"
703 |
704 | event.start = MSGraphDateTimeTimeZone()
705 | event.start.dateTime = dateFormatter.string(from: startDate)
706 |
707 | // For more timezone settings, visit this link
708 | // http://graph.microsoft.io/en-us/docs/api-reference/v1.0/resources/datetimetimezone
709 | event.start.timeZone = "Pacific/Honolulu"
710 |
711 | event.end = MSGraphDateTimeTimeZone()
712 | event.end.dateTime = dateFormatter.string(from: endDate)
713 | event.end.timeZone = "Pacific/Honolulu"
714 |
715 | if !series {
716 | event.type = MSGraphEventType.singleInstance()
717 | }
718 | else {
719 | event.type = MSGraphEventType.seriesMaster()
720 |
721 | event.recurrence = MSGraphPatternedRecurrence()
722 | event.recurrence.pattern = MSGraphRecurrencePattern()
723 | event.recurrence.pattern.interval = 1
724 | event.recurrence.pattern.type = MSGraphRecurrencePatternType.weekly()
725 | event.recurrence.pattern.daysOfWeek = [MSGraphDayOfWeek.friday()]
726 | event.recurrence.range = MSGraphRecurrenceRange()
727 | event.recurrence.range.type = MSGraphRecurrenceRangeType.noEnd()
728 | event.recurrence.range.startDate = MSDate(nsDate: startDate)
729 | }
730 | return event
731 | }
732 | }
733 |
--------------------------------------------------------------------------------