Schreiben einer iOS-App zum Abrufen von Outlook-Mail, -Kalender und -KontaktenWrite an iOS app to get Outlook mail, calendar, and contacts

In diesem Leitfaden werden Sie schrittweise durch den Prozess des Erstellens einer einfachen Swift-App zum Abrufen von Nachrichten in Office 365 oder Outlook.com geführt. Wenn Sie die hier beschriebenen Schritte ausführen, sollte der Quellcode in diesem Repository das Ergebnis sein.The purpose of this guide is to walk through the process of creating a simple Swift app that retrieves messages in Office 365 or Outlook.com. The source code in this repository is what you should end up with if you follow the steps outlined here.

In diesem Leitfaden wird Microsoft Graph zum Zugriff auf Outlook-Mail verwendet.This guide will use Microsoft Graph to access Outlook mail. Microsoft empfiehlt die Verwendung von Microsoft Graph für den Zugriff auf Outlook-Mail, -Kalender und -Kontakte.Microsoft recommends using Microsoft Graph to access Outlook mail, calendar, and contacts. Verwenden Sie die Outlook-APIs nur dann direkt (über https://outlook.office.com/api), wenn Sie ein Feature benötigen, das in den Graph-Endpunkten nicht verfügbar ist.This guide will use the Microsoft Graph to access Outlook mail. Microsoft recommends using the Microsoft Graph to access Outlook mail, calendar, and contacts. You should use the Outlook APIs directly (via https://outlook.office.com/api) only if you require a feature that is not available on the Graph endpoints.

In diesem Leitfaden wird davon ausgegangen, dass Sie Xcode bereits installiert haben und zusammen mit CocoaPods Version 1.2 auf Ihrem Entwicklungscomputer ausführen.This guide assumes that you already have Xcode installed and working on your development machine, along with CocoaPods version 1.2 or later.

Erstellen der AppCreate the app

Lassen Sie uns direkt loslegen. Öffnen Sie Xcode, und wählen Sie im Menü File die Option New und dann Project aus. Wählen Sie im linken Bereich Application unter iOS aus, und wählen Sie dann Tabbed Application. Klicken Sie auf Next.Let's dive right in! Open Xcode, and on the File menu, choose New then Project. In the left-hand pane, choose Application under iOS, then choose Tabbed Application. Click Next.

Wählen Sie die Vorlage „Single View Application“ aus.

Geben Sie swift-tutorial in das Feld Product Name, Swift für Language und Universal für Devices ein, klicken Sie dann auf Next.Enter swift-tutorial for Product Name, Swift for Language, and Universal for Devices, then click Next.

Wählen Sie Optionen für Ihr neues Projekt aus.

Wählen Sie einen Speicherort für das Projekt, und klicken Sie auf Create. Sobald Xcode die Erstellung des Projekts abgeschlossen hat, schließen Sie Xcode.Choose a location for the project and click Create. Once Xcode finishes creating the project, close Xcode.

Verwenden Sie als Nächstes CocoaPods zum Installieren von Abhängigkeiten. In diesem Lernprogramm benötigen wir Folgendes:Next, use CocoaPods to install dependencies. For this tutorial, we will need the following:

Öffnen Sie Terminal, und wechseln Sie in das Verzeichnis, in dem Ihr swift-tutorial-Projekt gespeichert ist. Führen Sie den folgenden Befehl aus, um eine Podfile-Datei für das Projekt zu initialisieren.Open Terminal and change the directory to the location of your swift-tutorial project. Run the following command to initialize a Podfile for the project.

pod init

Öffnen Sie dann die Podfile-Datei mit dem folgenden Befehl.Next, open the Podfile using the following command.

open Podfile

Ersetzen Sie den gesamten Inhalt der Datei durch Folgendes:Replace the entire contents of the file with:

Inhalt der Podfile-DateiContents of the Podfile file

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'swift-tutorial' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for swift-tutorial
  pod 'p2.OAuth2'
  pod 'SwiftyJSON'

  target 'swift-tutorialTests' do
    inherit! :search_paths
    # Pods for testing
  end

end

Schließen Sie die Podfile-Datei, und führen Sie dann den folgenden Befehl aus, um die Abhängigkeiten zu installieren:Close the Podfile, then run the following command to install the dependencies.

pod install

Sobald dieser Befehl abgeschlossen ist, öffnen Sie die neu erstellte Datei swift-tutorial.xcworkspace in Xcode.Once that command finishes, open the newly created swift-tutorial.xcworkspace file in Xcode.

Entwerfen der AppDesigning the app

Die App selbst ist ziemlich einfach. Wir ändern den Zweck des generierten FirstViewController so, dass er den Posteingang des Benutzers anzeigt.The app itself will be fairly simple. We'll repurpose the generated FirstViewController to show the user's inbox.

  1. Erweitern Sie im Project Navigator swift-tutorial->swift-tutorial, und wählen Sie dann FirstViewController.swift aus. Ersetzen Sie alle Instanzen von FirstViewController durch MailViewController.In the Project navigator, expand swift-tutorial->swift-tutorial, then select FirstViewController.swift. Replace all instances of FirstViewController with MailViewController.
  2. Öffnen Sie den File Inspector, und ändern Sie den Dateinamen in MailViewController.swift.Open the File inspector and change the file name to MailViewController.swift.
  3. Wählen Sie Main.storyboard aus. Erweitern Sie in der Dokumentgliederung First Scene, und wählen Sie dann First aus.Select Main.storyboard. In the document outline, expand First Scene, then select First.

    Auswählen des Ansichtscontrollers in der Dokumentgliederung.

  4. Öffnen Sie den Attributes Inspector, und ändern Sie den Wert für Title in Mail.Open the Attributes inspector and change the Title to Mail.
  5. Öffnen Sie den Identity Inspector, und ändern Sie den Wert für Class in MailViewController.Open the Identity inspector and change the Class to MailViewController.
  6. Erweitern Sie View, und löschen Sie die Beschriftungen First View und Loaded by FirstViewController.Expand View and delete the First View and Loaded by FirstViewController labels.
  7. Wählen Sie das Balkenelement First am unteren Rand der Ansicht aus. Ändern Sie im Attributes Inspector den Wert für Title in Mail. Vergewissern Sie sich, dass für Image der Wert first angegeben ist.Select the First bar item at the bottom of the view. On the Attributes inspector, change the Title to Mail. Make sure the Image value is first.

Jetzt fügen wir eine Anmeldeschaltfläche hinzu. Suchen Sie in der Object Library (untere rechte Ecke) nach Button. Ziehen Sie Button in die visuelle Darstellung der Ansicht. Doppelklicken Sie auf die Schaltfläche, und legen Sie den Text auf Log In fest.Now let's add a login button. In the Object Library (bottom-right corner), find Button. Drag Button onto the visual representation of the view. Double-click the button and set the text to Log In.

Hinzufügen einer Anmeldeschaltfläche.

Wählen Sie jetzt MailViewController.swift im Project Navigator aus. Fügen Sie eine neue Eigenschaft zur MailViewController-Klasse hinzu, direkt vor der viewDidLoad-Funktion:Now select MailViewController.swift in the Project navigator. Add a new property to the MailViewController class, right before the viewDidLoad function:

@IBOutlet var logInButton: UIButton!

Fügen Sie dann eine neue Methode zur Klasse hinzu:Then add a new method to the class:

logInButtonTapped-Funktion in MailViewController.swiftlogInButtonTapped function in MailViewController.swift

@IBAction func logInButtonTapped(sender: AnyObject) {
    NSLog("Hello World")
}

Wählen Sie in Main.storyboard die Option Mail in der Dokumentgliederung aus. Wählen Sie die Registerkarte Connections Inspector auf der rechten Seite aus.In Main.storyboard, select Mail in the document outline. Select the Connections inspector tab on the right-hand side.

Auswählen des Connections Inspector.

Unter Outlets sollte die Eigenschaft loginButton angezeigt werden, die wir zuvor zum Ansichtscontroller hinzugefügt haben. Ziehen Sie den kleinen Kreis neben dieser Eigenschaft auf die Schaltfläche in der Ansicht.Under Outlets, you should see the loginButton property we added to the view controller earlier. Drag the small circle next to this property onto the button on the view.

Unter Received Actions sollte logInButtonTappedWithSender angezeigt werden. Ziehen Sie den kleinen Kreis neben dieser Methode auf die Schaltfläche in der Ansicht. Wählen Sie im angezeigten Popupmenü Touch Up Inside aus. Anschließend sollte der Abschnitt Connections Inspector wie folgt aussehen.Under Received Actions, you should see logInButtonTappedWithSender. Drag the small circle next to this method onto the button on the view. In the pop up menu that appears, select Touch Up Inside. The Connections inspector section should look like this once you are done.

Connections Inspector mit der verbundenen Anmeldeschaltfläche unter „Outlets“.

An diesem Punkt sollte die App erstellt und ausgeführt werden. Beim Tippen auf die Schaltfläche Log in sollte die loginButtonTapped-Methode aufgerufen werden, die Hello World in der Xcode-Ausgabe zurückgeben sollte.At this point the app should build and run. Tapping the Log in button should call the loginButtonTapped method, which should print Hello World to the output in Xcode.

Registrieren der AppRegister the app

Wichtig

Neue App-Registrierungen sollten im Anwendungsregistrierungsportal erstellt und verwaltet werden, damit sie mit Outlook.com kompatibel sind. Erstellen Sie neue App-Registrierungen nur dann im Azure-Verwaltungsportal Folgendes auf Ihre App zutrifft:New app registrations should be created and managed in the new Application Registration Portal to be compatible with Outlook.com. Only create new app registrations in the Azure Management Portal if your app:

  • Sie verwendet den OAuth2 Client Credentials Grant-Fluss oderUses the OAuth2 Client Credentials Grant Flow, or
  • Sie muss neben Outlook auf andere Office 365-Arbeitslasten zugreifen (z. B. OneDrive for Business oder SharePoint)Needs to access other Office 365 workloads besides Outlook (such as OneDrive for Business or SharePoint)

Beachten Sie, dass mithilfe des Azure-Verwaltungsportals registrierte Apps nicht mit Outlook.com kompatibel sind und dass Berechtigungsbereiche nicht dynamisch angefordert werden können.Bear in mind that apps registered using the Azure Management Portal will not be compatible with Outlook.com, and will not be able to dynamically request permissions scopes. Vorhandene App-Registrierungen, die im Azure-Verwaltungsportal erstellt wurden, funktionieren weiterhin nur für Office 365.Existing app registrations that were created in the Azure Management Portal will continue to work for Office 365 only. Diese Registrierungen werden nicht im Anwendungsregistrierungsportal angezeigt und müssen im Azure-Verwaltungsportal verwaltet werden.These registrations do not show up in the Application Registration Portal and must be managed in the Azure Management Portal.

KontoanforderungenAccount requirements

Um das Anwendungsregistrierungsportal zu verwenden, benötigen Sie entweder ein Office 365-Geschäfts- oder Schulkonto oder ein Microsoft-Konto. Wenn Sie nicht über eines dieser Konten verfügen, haben Sie verschiedene Möglichkeiten:In order to use the Application Registration Portal, you need either an Office 365 work or school account, or a Microsoft account. If you don't have either of these, you have a number of options:

  • Registrieren Sie sich hier für ein neues Microsoft-Konto.Sign up for a new Microsoft account here.
  • Sie haben mehrere Möglichkeiten, ein Office 365-Abonnement zu erhalten:You can obtain an Office 365 subscription in a couple of different ways:

REST-API-VerfügbarkeitREST API availability

Die REST-API ist derzeit auf allen Office 365-Konten, die über Exchange Online verfügen, sowie auf allen Outlook.com-Konten aktiviert.The REST API is currently enabled on all Office 365 accounts that have Exchange Online, and all Outlook.com accounts.

Wechseln Sie zum App-Registrierungsportal, um schnell eine App-ID zu erhalten.Head over to the Application Registration Portal to quickly get an application ID.

  1. Melden Sie sich über den Link Anmelden mit Ihrem Microsoft-Konto (Outlook.com) oder Ihrem Geschäfts-, Schul- oder Unikonto (Office 365) an.Using the Sign in link, sign in with either your Microsoft account (Outlook.com), or your work or school account (Office 365).
  2. Klicken Sie auf die Schaltfläche App hinzufügen. Geben Sie swift-tutorial für den Namen ein, und klicken Sie auf Erstellen.Click the Add an app button. Enter swift-tutorial for the name and click Create.
  3. Suchen Sie den Abschnitt Plattformen, und klicken Sie auf Plattform hinzufügen. Wählen Sie Native Anwendung aus.Locate the Platforms section, and click Add Platform. Choose Native application.
  4. Ersetzen Sie den Wert für Benutzerdefinierte Umleitungs-URIs durch swift-tutorial://oauth2/callback.Replace the value for Custom Redirect URIs with swift-tutorial://oauth2/callback.
  5. Klicken Sie auf Speichern, um die Registrierung abzuschließen. Kopieren Sie die Anwendungs-ID, und speichern Sie sie. Wir benötigen sie bald.Click Save to complete the registration. Copy the Application Id and save it. We'll need it soon.

So sollten die Details Ihrer App-Registrierung aussehen, wenn Sie fertig sind.Here's what the details of your app registration should look like when you are done.

Screenshot der abgeschlossenen App-Registrierung im App-Registrierungsportal

Implementieren von OAuth2Implementing OAuth2

Unser Ziel in diesem Abschnitt ist, die Schaltfläche Log in so zu konfigurieren, dass sie OAuth2 zum Abrufen eines Zugriffstokens verwendet, das wir mit der Mail-API verwenden können. Wir verwenden das p2.OAuth2-Framework.Our goal in this section is to make the Log in button use OAuth2 to obtain an access token that we can use with the Mail API. We'll use the p2 OAuth2 framework.

Zunächst erstellen wir eine Singleton-Klasse, die Authentifizierung und API-Aufrufe verwaltet. Klicken Sie bei gedrückter STRG-TASTE auf den Ordner swift-tutorial im Project Navigator, und wählen Sie New File. Wählen Sie Swift file als Vorlage aus, und klicken Sie auf Next. Geben Sie OutlookService in das Feld Save As ein, und klicken Sie auf Create.Let's start by creating a singleton class that will manage authentication and making API calls. CTRL + Click the swift-tutorial folder in Project navigator and select New File. Select Swift file as the template and click Next. Enter OutlookService in the Save As field and click Create.

Öffnen Sie die Datei OutlookService.swift, und ersetzen Sie ihren Inhalt durch Folgendes.Open the OutlookService.swift file and replace its contents with the following.

Inhalt der Datei OutlookService.swiftContents of the OutlookService.swift file

import Foundation
import p2_OAuth2

class OutlookService {
    // Configure the OAuth2 framework for Azure
    private static let oauth2Settings = [
        "client_id" : "YOUR APP ID HERE",
        "authorize_uri": "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
        "token_uri": "https://login.microsoftonline.com/common/oauth2/v2.0/token",
        "scope": "openid profile offline_access User.Read Mail.Read",
        "redirect_uris": ["swift-tutorial://oauth2/callback"],
        "verbose": true,
        ] as OAuth2JSON

    private static var sharedService: OutlookService = {
        let service = OutlookService()
        return service
    }()

    private let oauth2: OAuth2CodeGrant

    private init() {
        oauth2 = OAuth2CodeGrant(settings: OutlookService.oauth2Settings)
        oauth2.authConfig.authorizeEmbedded = true
    }

    class func shared() -> OutlookService {
        return sharedService
    }

    var isLoggedIn: Bool {
        get {
            return oauth2.hasUnexpiredAccessToken() || oauth2.refreshToken != nil
        }
    }

    func handleOAuthCallback(url: URL) -> Void {
        oauth2.handleRedirectURL(url)
    }

    func login(from: AnyObject, callback: @escaping (String? ) -> Void) -> Void {
        oauth2.authorizeEmbedded(from: from) {
            result, error in
            if let unwrappedError = error {
                callback(unwrappedError.description)
            } else {
                if let unwrappedResult = result, let token = unwrappedResult["access_token"] as? String {
                    // Print the access token to debug log
                    NSLog("Access token: \(token)")
                    callback(nil)
                }
            }
        }
    }

    func logout() -> Void {
        oauth2.forgetTokens()
    }
}

Ersetzen Sie den Wert clientId durch die Anwendungs-ID, die Sie im App-Registrierungsportal generiert haben.Replace the value of clientId with the application ID you generated in the Application Registration Portal.

Öffnen Sie AppDelegate.swift, und fügen Sie der AppDelegate-Klasse eine neue Funktion hinzu.Open AppDelegate.swift and add a new function to the AppDelegate class. Diese Funktion wird die Aktivierung der App ausführen, wenn sie während der Anmeldung vom benutzerdefinierten Umleitungs-URI aktiviert wird.This function will handle activation of the app when it is activated by the custom redirect URI during sign in.

application-Funktion in AppDelegate.swiftapplication function in AppDelegate.swift

func application(_ app: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
    if url.scheme == "swift-tutorial" {
        let service = OutlookService.shared()
        service.handleOAuthCallback(url: url)
        return true
    }
    else {
        return false
    }
}

Jetzt müssen wir das benutzerdefinierte URI-Schema swift-tutorial registrieren, damit unsere App aufgerufen wird.Now we need to register the custom URI scheme swift-tutorial so that our app will be invoked.

  1. Klicken Sie bei gedrückter STRG-TASTE auf die Datei Info.plist, und wählen Sie Öffnen als und dann Quellcode aus.Control-click the Info.plist file and choose Open As, then Source Code.
  2. Navigieren Sie zum Ende der Datei, und fügen Sie den folgenden Code direkt hinter der letzten </array>-Zeile der Datei hinzu:Go to the end of the file, and add the following code just after the last </array> line in the file:

    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>swift-tutorial</string>
            </array>
        </dict>
    </array>
    

Wechseln Sie zurück zu MailViewController.swift. Fügen Sie der MailViewController-Klasse einen Member hinzu, der die freigegebene Instanz der OutlookService-Klasse enthalten soll.Switch back to MailViewController.swift. Add a member to the MailViewController class to hold the shared instance of the OutlookService class.

let service = OutlookService.shared()

Fügen Sie der MailViewController-Klasse eine Funktion hinzu, um die Beschriftung der Anmeldeschaltfläche basierend auf dem aktuellen Anmeldestatus zu ändern.Add a function to the MailViewController class to change the label on the login button based on the current login state.

setLogInState-Funktion in MailViewController.swiftsetLogInState function in MailViewController.swift

func setLogInState(loggedIn: Bool) {
    if (loggedIn) {
        loginButton.setTitle("Log Out", for: UIControlState.normal)
    }
    else {
        loginButton.setTitle("Log In", for: UIControlState.normal)
    }
}

Fügen Sie der viewDidLoad-Funktion nun Code hinzu, um den Anmeldestatus zu überprüfen und den Text der Schaltfläche entsprechend festzulegen. Der Grund hierfür ist, dass das p2.OAuth2-Framework Token in der Keychain des Benutzers speichert. Wenn die Ansicht geladen wird, enthält die Keychain möglicherweise bereits ein gültiges Token, sodass der Benutzer sich nicht erneut anmelden muss. Fügen Sie den folgenden Code nach der Zeile super.viewDidLoad() hinzu:Now add code to the viewDidLoad function to check the login state and set the button text appropriately. The reason for this is that the p2 OAuth2 framework stores tokens in the user's keychain. When the view loads, there may already be a valid token in the keychain, so the user doesn't have to login again. Add the following after the super.viewDidLoad() line.

setLogInState(loggedIn: service.isLoggedIn)

Abschließend aktualisieren wir die logInButtonTapped-Funktion zum Durchführen der Anmeldung. Ersetzen Sie die vorhandene Funktion durch diese neue.Finally, let's update the logInButtonTapped function to do the login. Replace the existing function with this new one.

Aktualisierte loginButtonTapped-Funktion in MailViewController.swiftUpdated loginButtonTapped function in MailViewController.swift

@IBAction func loginButtonTapped(sender: AnyObject) {
    if (service.isLoggedIn) {
        // Logout
        service.logout()
        setLogInState(loggedIn: false)
    } else {
        // Login
        service.login(from: self) {
            error in
            if let unwrappedError = error {
                NSLog("Error logging in: \(unwrappedError)")
            } else {
                NSLog("Successfully logged in.")
                setLogInState(loggedIn: true)
            }
        }
    }
}

Führen Sie die App aus. Nachdem die App im iOS Simulator geladen wurde, tippen Sie auf die Schaltfläche Log in, um sich anzumelden. Nach der Anmeldung sollte ein Token im Ausgabefenster angezeigt werden, und die Schaltfläche sollte nun die Beschriftung Log out haben.Run the app. Once the app loads in the iOS Simulator, tap the Log in button to login. After logging in, you should see a token printed to the output window, and the button should now say Log out.

Das Zugriffstoken, das in Xcode im Ausgabefenster angezeigt wird.

Kopieren Sie den vollständigen Wert des Tokens, und wechseln Sie zu https://jwt.io/.Copy the entire value of the token and head over to https://jwt.io/. Wenn Sie diesen Wert einfügen, sollte eine JSON-Darstellung eines Zugriffstokens angezeigt werden.If you paste that value in, you should see a JSON representation of an access token. Details und alternative Parser finden Sie unter Validating your Office 365 Access Token.For details and alternative parsers, see Validating your Office 365 Access Token.

Wenn Sie überzeugt sind, dass das Token den Anforderungen entspricht, machen wir mit der Mail-API weiter.Once you're convinced that the token is what it should be, let's move on to using the Mail API.

Verwenden der Mail-APIUsing the Mail API

Wir beginnen mit der Erstellung einer Funktion, die eine API-Anforderung sendet und die Antwort zurückgibt. Wechseln Sie zurück zur Datei OutlookService.swift, und importieren Sie die SwiftyJSON-Bibliothek.Let's start by creating a function that will send an API request and return the response. Switch back to OutlookService.swift file and import the SwiftyJSON library.

import SwiftyJSON

Wir verwenden diese Bibliothek, um die Ergebnisse der API-Aufrufe zu umschließen, sodass ein wenig einfacher darauf zugegriffen werden kann. Fügen Sie als Nächstes einen Member zur OutlookService-Klasse hinzu, der die E-Mail-Adresse des Benutzers enthalten soll.We'll use this library to wrap the results of API calls, making them a little easier to access. Next, add a member to the OutlookService class to hold the user's email address.

private var userEmail: String

Es muss sichergestellt sein, dass dies in der init-Funktion initialisiert wird. Fügen Sie der init-Funktion die folgende Zeile hinzu.We should make sure that we initialize this in the init function. Add the following line to the init function:

userEmail = ""

Fügen Sie nun eine neue makeApiCall-Funktion hinzu.Now add a new function makeApiCall.

makeApiCall-Funktion in OutlookService.swiftmakeApiCall function in OutlookService.swift

func makeApiCall(api: String, params: [String: String]? = nil, callback: @escaping (JSON?) -> Void) -> Void {
    // Build the request URL
    var urlBuilder = URLComponents(string: "https://graph.microsoft.com")!
    urlBuilder.path = api

    if let unwrappedParams = params {
        // Add query parameters to URL
        urlBuilder.queryItems = [URLQueryItem]()
        for (paramName, paramValue) in unwrappedParams {
            urlBuilder.queryItems?.append(
                URLQueryItem(name: paramName, value: paramValue))
        }
    }

    let apiUrl = urlBuilder.url!
    NSLog("Making request to \(apiUrl)")

    var req = oauth2.request(forURL: apiUrl)
    req.addValue("application/json", forHTTPHeaderField: "Accept")

    let loader = OAuth2DataLoader(oauth2: oauth2)

    // Uncomment this line to get verbose request/response info in 
    // Xcode output window
    //loader.logger = OAuth2DebugLogger(.trace)

    loader.perform(request: req) {
        response in
        do {
            let dict = try response.responseJSON()
            DispatchQueue.main.async {
                let result = JSON(dict)
                callback(result)
            }
        }
        catch let error {
            DispatchQueue.main.async {
                let result = JSON(error)
                callback(result)
            }
        }
    }
}

Sehen wir uns die Arbeit dieser Funktion an.Let's look at what this function does.

  • Sie erstellt die API-Anforderungs-URL, die als Basis https://graph.microsoft.com verwendet und die übergebene API-Zeichenfolge hinzufügt (z. B. /v1.0/me).It builds the API request URL, starting with a base of https://graph.microsoft.com, and adding whatever API string is passed in (e.g. /v1.0/me).
  • Wenn Abfrageparameter übergeben werden, werden diese ebenfalls an die URL angehängt (z. B. Parameter $top oder $select).If any query parameters are passed in, it appends those to the URL as well (e.g. $top or $select parameters).
  • Es wird ein OAuth2DataLoader-Objekt zum Senden der Anforderung mit Authentifizierung erstellt. Diese Vorgehensweise hat den Vorteil, dass das OAuth2DataLoader-Objekt das Hinzufügen des Zugriffstokens zur Anforderung übernimmt und das Token bei Bedarf automatisch aktualisiert.It creates an OAuth2DataLoader object to handle sending the request with authentication. The benefit to doing this is that the OAuth2DataLoader object will handle adding the access token to the request, and will automatically handle refreshing the token if needed.
  • Es umschließt die Antwort unter Verwendung der SwiftyJSON-Bibliothek und ruft die Rückruffunktion auf.It wraps the response using the SwiftyJSON library and calls the callback function.

Jetzt fügen wir eine Funktion hinzu, um die E-Mail-Adresse des Benutzers abzurufen. Hierzu senden wir einen API-Aufruf an den /v1.0/me-Endpunkt und rufen die mail-Eigenschaft vom Benutzerobjekt ab. Fügen Sie die folgende Funktion zur OutlookService-Klasse hinzu:Now let's add a function to get the user's email address. To do that, we'll make an API call to the /v1.0/me endpoint, and get the mail property from the user object. Add the following function to the OutlookService class.

getUserEmail-Funktion in OutlookService.swiftgetUserEmail function in OutlookService.swift

func getUserEmail(callback: @escaping (String?) -> Void) -> Void {
    // If we don't have the user's email, get it from
    // the API
    if (userEmail.isEmpty) {
        makeApiCall(api: "/v1.0/me") {
            result in
            if let unwrappedResult = result {
                let email = unwrappedResult["mail"].stringValue
                self.userEmail = email
                callback(email)
            } else {
                callback(nil)
            }
        }
    } else {
        callback(userEmail)
    }
}

Und nun testen wir das. Erstellen Sie eine neue Funktion in MailViewController.swift, um Benutzerdaten zu laden.Let's test it out! Create a new function in MailViewController.swift to load user data.

loadUserData-Funktion in MailViewController.swiftloadUserData function in MailViewController.swift

func loadUserData() {
    service.getUserEmail() {
        email in
        if let unwrappedEmail = email {
            NSLog("Hello \(unwrappedEmail)")
        }
    }
}

Aktualisieren Sie die loginButtonTapped-Funktion so, dass sie nach einer erfolgreichen Anmeldung loadUserData aufruft.Update the loginButtonTapped function to call loadUserData after a successful login.

Aktualisierte loginButtonTapped-Funktion in MailViewController.swiftUpdated loginButtonTapped function in MailViewController.swift

@IBAction func loginButtonTapped(sender: AnyObject) {
    if (service.isLoggedIn) {
        // Logout
        service.logout()
        setLogInState(loggedIn: false)
    } else {
        // Login
        service.login(from: self) {
            error in
            if let unwrappedError = error {
                NSLog("Error logging in: \(unwrappedError)")
            } else {
                NSLog("Successfully logged in.")
                self.setLogInState(loggedIn: true)
                self.loadUserData()
            }
        }
    }
}

Aktualisieren Sie außerdem die viewDidLoad-Funktion so, dass loadUserData aufgerufen wird, wenn wir bereits angemeldet sind.Also update the viewDidLoad function to call loadUserData if we're already logged in.

Aktualisierte viewDidLoad-Funktion in MailViewController.swiftUpdated viewDidLoad function in MailViewController.swift

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    setLogInState(loggedIn: service.isLoggedIn)
    if (service.isLoggedIn) {
        loadUserData()
    }
}

Starten Sie die App neu. Nachdem Sie auf die Schaltfläche Log in getippt haben, sollten im Xcode-Ausgabefenster eine Nachricht mit der E-Mail-Adresse des Benutzers angezeigt werden.Restart the app. After you tap the Log in button, you should see a message in the Xcode output window with the user's email address.

Als Nächstes erstellen wir eine Funktion, um die Nachrichten im Posteingang des Benutzers abzurufen. Fügen Sie die folgende Funktion zur OutlookService-Klasse hinzu:Now let's create a function to get the user's inbox messages. Add the following function to the OutlookService class.

getInboxMessages-Funktion in OutlookService.swiftgetInboxMessages function in OutlookService.swift

func getInboxMessages(callback: @escaping (JSON?) -> Void) -> Void {
    let apiParams = [
        "$select": "subject,receivedDateTime,from",
        "$orderby": "receivedDateTime DESC",
        "$top": "10"
    ]

    makeApiCall(api: "/v1.0/me/mailfolders/inbox/messages", params: apiParams) {
        result in
        callback(result)
    }
}

Diese Funktion verwendet die gleiche makeApiCall-Funktion wie die getUserEmail-Funktion. Ein großer Unterschied ist der Benutzer des params-Parameters. Diese Parameter werden an die API-Anforderungs-URL angehängt und steuern das Verhalten der API. In diesem Fall verwenden wir:This function uses the same makeApiCall function as the getUserEmail function. One big difference is the user of the params parameter. These parameters get appended to the API request URL and control how the API behaves. In this case, we:

  • $select, um zu beschränken, welche Felder in der Antwort zurückgegeben werden. Die Antworten enthalten nur die Felder subject, receivedDateTime und from.Use $select to limit which fields are returned in the response. The responses will only contain the subject, receivedDateTime, and from fields.
  • $orderby, um die Ergebnisse in absteigender Reihenfolge nach receivedDateTime zu sortieren.Use $orderby to sort the results by receivedDateTime in descending order.
  • $top, um die Antwort auf maximal 10 Elemente zu beschränken.Use $top to limit the response to at most 10 items.

Aktualisieren Sie nun die loadUserData-Funktion in MailViewController.swift so, dass sie getInboxMessages aufruft, nachdem getUserEmail zurückgegeben wurde.Now update to the loadUserData function in MailViewController.swift to call getInboxMessages after getUserEmail returns.

Aktualisierte loadUserData-Funktion in OutlookService.swiftUpdated loadUserData function in OutlookService.swift

func loadUserData() {
    service.getUserEmail() {
        email in
        if let unwrappedEmail = email {
            NSLog("Hello \(unwrappedEmail)")

            self.service.getInboxMessages() {
                messages in
                if let unwrappedMessages = messages {
                    for (message) in unwrappedMessages["value"].arrayValue {
                        NSLog(message["subject"].stringValue)
                    }
                }
            }
        }
    }
}

Wenn Sie die App jetzt neu starten, sollte eine Liste von Nachrichtenbetreffzeilen im Xcode-Ausgabefenster angezeigt werden.Now if you restart the app, you should see a list of message subjects printed to the Xcode output window.

Anzeige von Nachrichtenbetreffzeilen im Xcode-Ausgabefenster.

Anzeigen der ErgebnisseDisplaying the results

Wir fügen unserer App nun eine Tabellenansicht hinzu, um die Liste der Nachrichten anzuzeigen. Wechseln Sie zu Main.storyboard. Suchen Sie in der Object Library nach Table View. Ziehen Sie Table View in die Szene Mail, direkt unter die Anmeldeschaltfläche. Klicken Sie dann auf die Schaltfläche Add New Constraints in der unteren rechten Ecke des Zeichenbereichs. Legen Sie den linken, rechten und unteren Einschränkungswert auf 0 fest, und klicken Sie auf Add 3 Constraints.Let's add a table view to our app to display the list of messages. Switch to Main.storyboard. In the Object library, locate Table View. Drag Table View onto the Mail scene, just below the login button. Then click the Add New Constraints button in the lower-right corner of the canvas. Set the left, right, and bottom constraint values to 0 and click Add 3 Constraints.

Fügen Sie eine Tabellenansicht zur Ansicht im Haupt-Storyboard hinzu.

Hierdurch wird die Tabellenansicht hinzugefügt und so konfiguriert, dass sie den gesamten Bildschirm füllt. Jetzt müssen wir das Layout der einzelnen Tabellenzellen festlegen. Klicken Sie bei ausgewählter Tabellenansicht auf den Attributes Inspector, und legen Sie den Wert von Prototype Cells auf 1 fest.That adds the table view and sets it to cover the entire screen. Now we need to layout how each cell of the table will appear. With the table view selected, click the Attributes inspector and set the value of Prototype Cells to 1.

Screenshot der Prototypzelle in der Tabellenansicht

Suchen Sie in der Object Library nach Label. Ziehen Sie Label in die Prototypzelle der Tabellenansicht, doppelklicken Sie darauf, und ändern Sie den Text in From. Fügen Sie zwei weitere Beschriftungen hinzu, eine mit dem Text Received und eine mit dem Text Subject.In the Object library, locate Label. Drag Label onto the prototype cell in the table view, then double-click it and change the text to From. Add two more labels, one with text Received and one with text Subject.

Screenshot der Prototypzelle mit hinzugefügten Beschriftungen

Nachdem Sie die Beschriftungen hinzugefügt haben, wählen Sie Mail in der Dokumentgliederung aus. Wählen Sie im Menü Editor die Option Resolve Auto Layout Issues, dann Add Missing Constraints gefolgt von Reset to Suggested Constraints aus.Once you have the labels added, select Mail in the Document outline. On the Editor menu, choose Resolve Auto Layout Issues, then Add Missing Constraints, followed by Reset to Suggested Constraints.

Nun fügen wir eine benutzerdefinierte Klasse für die Tabellenansichtszellen hinzu.Now, let's add a custom class for the table view cells.

  1. Klicken Sie im Project Navigator bei gedrückter STRG-TASTE auf den Ordner swift-tutorial, und wählen Sie New File. Wählen Sie Swift File (unter iOS/Source) aus, und klicken Sie auf Next. Geben Sie MessageCell in das Feld Save As ein, und klicken Sie auf Create.In the Project navigator, CTRL + click the swift-tutorial folder and choose New File. Select Swift File (under iOS/Source) and click Next. Enter MessageCell in the Save As field and click Create.
  2. Fügen Sie den folgenden Code hinzu, um eine einfache Struktur zur Darstellung einer Nachricht zu erstellen.Add the following code to create a simple structure to represent a message.

    import UIKit
    import SwiftyJSON
    
    struct Message {
        let from: String
        let received: String
        let subject: String
    }
    
  3. Fügen Sie nun den folgenden Code hinzu, um eine Klasse zu erstellen, die von UITableViewCell erbt.Now add the following code to create a class that inherits from UITableViewCell.

    class MessageCell: UITableViewCell {
        @IBOutlet weak var fromLabel: UILabel!
        @IBOutlet weak var receivedLabel: UILabel!
        @IBOutlet weak var subjectLabel: UILabel!
    
        var from: String? {
            didSet {
                fromLabel.text = from
            }
        }
    
        var received: String? {
            didSet {
                receivedLabel.text = received
            }
        }
    
        var subject: String? {
            didSet {
                subjectLabel.text = subject
            }
        }
    }
    
  4. Fügen Sie zum Schluss den folgenden Code hinzu, um eine Klasse zu erstellen, die als Datenquelle einer Tabellenansicht verwendet werden kann.Finally, add the following code to create a class that can be used as a table view's datasource.

    class MessagesDataSource: NSObject {
        let messages: [Message]
    
        init(messages: [JSON]?) {
            var msgArray = [Message]()
    
            if let unwrappedMessages = messages {
                for (message) in unwrappedMessages {
                    let newMsg = Message(
                            from: message["from"]["emailAddress"]["name"].stringValue,
                            received: Formatter.dateToString(date: message["receivedDateTime"]),
                            subject: message["subject"].stringValue)
    
                    msgArray.append(newMsg)
                }
            }
    
            self.messages = msgArray
        }
    }
    
    extension MessagesDataSource: UITableViewDataSource {
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return messages.count
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: MessageCell.self)) as! MessageCell
            let message = messages[indexPath.row]
            cell.from = message.from
            cell.received = message.received
            cell.subject = message.subject
            return cell
        }
    }
    

Dieser Code verwendet eine benutzerdefinierte Formatter-Klasse, um den von der API zurückgegebenen Datumswert in einem benutzerfreundlicheren Format zu formatieren. Diese Klasse werden wir nun implementieren.That code uses a custom Formatter class to format the date value returned from the API into a more human-friendly format. Let's implement that class.

  1. Klicken Sie im Project Navigator bei gedrückter STRG-TASTE auf den Ordner swift-tutorial, und wählen Sie New File. Wählen Sie Swift File (unter iOS/Source) aus, und klicken Sie auf Next. Geben Sie Formatter in das Feld Save As ein, und klicken Sie auf Create.In the Project navigator, CTRL + click the swift-tutorial folder and choose New File. Select Swift File (under iOS/Source) and click Next. Enter Formatter in the Save As field and click Create.
  2. Fügen Sie den folgenden Code hinzu.Add the following code.

    import SwiftyJSON
    
    class Formatter {
        class func dateToString(date: JSON) -> String {
            let graphDateString = date.stringValue
            if (graphDateString.isEmpty) {
                return ""
            }
    
            let toDateFormatter = DateFormatter()
            toDateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
    
            let dateObj = toDateFormatter.date(from: graphDateString)
            if (dateObj == nil) {
                return ""
            }
    
            let toStringFormatter = DateFormatter()
            toStringFormatter.dateStyle = DateFormatter.Style.medium
            toStringFormatter.timeStyle = DateFormatter.Style.short
            toStringFormatter.timeZone = TimeZone.current
    
            return toStringFormatter.string(from: dateObj!)
        }
    }
    

Nun ordnen wir diese Klasse der Ansicht zu und verbinden die Beschriftungen mit den IBOutlet-Variablen in der Klasse.Now let's associate this class with the view, and connect the labels to the IBOutlet variables in the class.

  1. Wechseln Sie zu Main.storyboard, und wählen Sie die Prototypzelle in der Tabellenansicht aus.Switch to Main.storyboard and select the prototype cell in the table view.
  2. Ändern Sie im Identity Inspector den Wert für Class in MessageCell.On the Identity inspector, change the Class value to MessageCell.
  3. Legen Sie im Attribute Inspector für Identifier den Wert MessageCell fest.On the Attribute inspector, set the Identifier to MessageCell.
  4. Im Connections Inspector sollten unter Outlets die Eigenschaften fromLabel, receivedLabel und subjectLabel aus der MessageCell-Klasse angezeigt werden. Ziehen Sie den kleinen Kreis neben den einzelnen Eigenschaften auf die entsprechende Beschriftung in der Ansicht.On the Connections inspector, under Outlets, you should see the fromLabel, receivedLabel, and subjectLabel properties from the MessageCell class. Drag the small circle next to each of these properties onto the corresponding label on the view.

    Screenshot des Connections Inspector für die Prototypzelle

Nun aktualisieren wir die MailViewController-Klasse, um die Ansicht zu aktualisieren.Now let's update the MailViewController class to update the view.

  1. Fügen Sie in MailViewController.swift die folgenden Member zur Klasse hinzu.In MailViewController.swift, add the following members to the class.

    @IBOutlet weak var tableView: UITableView!
    var dataSource: MessagesDataSource?
    
  2. Ersetzen Sie die vorhandene loadUserData-Funktion durch die folgende, die die for-in-Schleife durch Code zum Erstellen einer neuen MessagesDataSource ersetzt, und aktualisieren Sie die Tabelle.Replace the existing loadUserData with the following, which replaces the for-in loop with code to create a new MessagesDataSource and refresh the table.

    func loadUserData() {
        service.getUserEmail() {
            email in
            if let unwrappedEmail = email {
                NSLog("Hello \(unwrappedEmail)")
    
                self.service.getInboxMessages() {
                    messages in
                    if let unwrappedMessages = messages {
                        self.dataSource = MessagesDataSource(messages: unwrappedMessages["value"].arrayValue)
                        self.tableView.dataSource = self.dataSource
                        self.tableView.reloadData()
                    }
                }
            }
        }
    }
    
  3. Fügen Sie nach der Zeile super.viewDidLoad() die folgenden Zeilen zu viewDidLoad hinzu:Add the following lines to viewDidLoad, after the super.viewDidLoad() line.

    tableView.estimatedRowHeight = 90;
    tableView.rowHeight = UITableViewAutomaticDimension
    

Als Letztes müssen wir die IBOutlet-Variable, die wir dem Ansichtscontroller hinzugefügt haben, mit der Tabellenansicht verbinden. Wechseln Sie zu Main.storyboard, und wählen Sie Mail in der Dokumentgliederung aus. Im Connections Inspector sollte die Eigenschaft tableView angezeigt werden. Ziehen Sie den kleinen Kreis neben der Eigenschaft in die Tabellenansicht.The last thing we need to do is connect the IBOutlet we added to the view controller to the table view. Switch to Main.storyboard and select Mail in the Document outline. On the Connections inspector, you should see the tableView property. Drag the small circle next to it onto the table view.

Wenn Sie die App ausführen, sollten Sie jetzt eine Tabelle mit Nachrichten erhalten, durch die Sie scrollen können.Now if you run the app, you should get a table of messages that you can scroll through.

Die Beispiel-App, die Nachrichten anzeigt.

Hinzufügen von Kalender- und Kontakte-APIsAdding Calendar and Contacts APIs

Da Sie nun das Aufrufen von Outlook-Mail aus Graph gemeistert haben, dürfte es kein Problem mehr sein, das gleiche für Kalender- und Kontakte-APIs zu tun.Now that you've mastered getting Outlook Mail from the Graph, doing the same for Calendar and Contacts APIs is similar and easy.

Tipp

Wenn Sie die Schritte in diesem Lernprogramm befolgt haben, haben Sie wahrscheinlich ein Zugriffstoken in Ihrer Keychain gespeichert. Dieses Token ist nur für den Mail.Read-Bereich gültig. Um die Kalender- oder Kontakte-API aufzurufen, müssen wir neue Bereiche hinzufügen. Melden Sie sich unbedingt von der App ab, um die gespeicherten Token zu entfernen, damit Sie den Anmeldevorgang von vorne beginnen können, um ein neues Zugriffstoken zu erhalten.If you've followed along with the tutorial, you probably have an access token saved in your keychain. That token will only be valid for the Mail.Read scope. In order to call the Calendar or Contacts API, we will need to add new scopes. Be sure sign out of the app to get rid of the saved tokens so that you can start the login process from the beginning to get a new access token.

Für die Kalender-API:For Calendar API:

Hinzufügen einer Klasse zum Abrufen von EreignissenAdd a function to get events

  1. Wechseln Sie zu OutlookService.swift.Switch to OutlookService.swift.
  2. Aktualisieren Sie den Wert für scope im oauth2Settings-Wörterbuch, um den Calendars.Read-Bereich einzuschließen.Update the scope value in the oauth2Settings dictionary to include the Calendars.Read scope.

    "scope": "openid profile offline_access User.Read Mail.Read Calendars.Read",
    
  3. Fügen Sie die folgende Funktion zur OutlookService-Klasse hinzu:Add the following function to the OutlookService class.

    func getEvents(callback: @escaping (JSON?) -> Void) -> Void {
        let apiParams = [
            "$select": "subject,start,end",
            "$orderby": "start/dateTime ASC",
            "$top": "10"
        ]
    
        makeApiCall(api: "/v1.0/me/events", params: apiParams) {
            result in
            callback(result)
        }
    }
    

Hinzufügen eines Formatierers für die Start- und EndzeitenAdd a formatter for the start and end times

Die Eigenschaften start und end für ein Ereignis weisen den Typ dateTimeTimeZone auf, der ein wenig anders formatiert ist als andere Datumsangaben. Um dies zu berücksichtigen, fügen wir der Formatter-Klasse eine weitere Funktion hinzu.The start and end properties on an event are of type dateTimeTimeZone, which is formatted a little differently than other dates. Let's add another function to the Formatter class to handle this.

  1. Wechseln Sie zu Formatter.swift.Switch to Formatter.swift.
  2. Fügen Sie die folgende Funktion hinzu.Add the following function.

    class func dateTimeTimeZoneToString(date: JSON) -> String {
        let graphTimeZone = date["timeZone"].stringValue
        let graphDateString = date["dateTime"].stringValue
        if (graphDateString.isEmpty) {
            return ""
        }
    
        let toDateFormatter = DateFormatter()
        toDateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.sss"
        toDateFormatter.timeZone = TimeZone(identifier: graphTimeZone)
    
        let dateObj = toDateFormatter.date(from: graphDateString)
        if (dateObj == nil) {
            return ""
        }
    
        let toStringFormatter = DateFormatter()
        toStringFormatter.dateStyle = DateFormatter.Style.medium
        toStringFormatter.timeStyle = DateFormatter.Style.short
        toStringFormatter.timeZone = TimeZone.current
    
        return toStringFormatter.string(from: dateObj!)
    }
    

Hinzufügen der benutzerdefinierten Klasse „EventCell“.Add the Event table cell custom class

  1. Klicken Sie im Project Navigator bei gedrückter STRG-TASTE auf den Ordner swift-tutorial, und wählen Sie New File. Wählen Sie Swift File (unter iOS/Source) aus, und klicken Sie auf Next. Geben Sie EventCell in das Feld Save As ein, und klicken Sie auf Create.In the Project navigator, CTRL + click the swift-tutorial folder and choose New File. Select Swift File (under iOS/Source) and click Next. Enter EventCell in the Save As field and click Create.
  2. Fügen Sie den folgenden Code hinzu.Add the following code.

    import UIKit
    import SwiftyJSON
    
    struct Event {
        let subject: String
        let start: String
        let end: String
    }
    
    class EventCell: UITableViewCell {
        @IBOutlet weak var subjectLabel: UILabel!
        @IBOutlet weak var startLabel: UILabel!
        @IBOutlet weak var endLabel: UILabel!
    
        var subject: String? {
            didSet {
                subjectLabel.text = subject
            }
        }
    
        var start: String? {
            didSet {
                startLabel.text = start
            }
        }
    
        var end: String? {
            didSet {
                endLabel.text = end
            }
        }
    }
    
    class EventsDataSource: NSObject {
        let events: [Event]
    
        init(events: [JSON]?) {
            var evtArray = [Event]()
    
            if let unwrappedEvents = events {
                for (event) in unwrappedEvents {
                    let newEvent = Event(
                        subject: event["subject"].stringValue,
                        start: Formatter.dateTimeTimeZoneToString(date: event["start"]),
                        end: Formatter.dateTimeTimeZoneToString(date: event["end"]))
    
                    evtArray.append(newEvent)
                }
            }
    
            self.events = evtArray
        }
    }
    
    extension EventsDataSource: UITableViewDataSource {
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return events.count
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: EventCell.self)) as! EventCell
            let event = events[indexPath.row]
            cell.subject = event.subject
            cell.start = event.start
            cell.end = event.end
            return cell
        }
    }
    

Implementieren des AnsichtscontrollersImplement the view controller

  1. Erweitern Sie im Project Navigator swift-tutorial->swift-tutorial, und wählen Sie dann SecondViewController.swift aus.In the Project navigator, expand swift-tutorial->swift-tutorial, then select SecondViewController.swift.
  2. Öffnen Sie den File Inspector, und ändern Sie den Dateinamen in CalendarViewController.swift.Open the File inspector and change the file name to CalendarViewController.swift.
  3. Ersetzen Sie den Dateiinhalt durch Folgendes.Replace the file contents with the following.

    import UIKit
    
    class CalendarViewController: UIViewController {
    
        @IBOutlet weak var tableView: UITableView!
    
        var dataSource:EventsDataSource?
    
        let service = OutlookService.shared()
    
        func loadUserData() {
            service.getUserEmail() {
                email in
                if let unwrappedEmail = email {
                    NSLog("Hello \(unwrappedEmail)")
    
                    self.service.getEvents() {
                        events in
                        if let unwrappedEvents = events {
                            self.dataSource = EventsDataSource(events: unwrappedEvents["value"].arrayValue)
                            self.tableView.dataSource = self.dataSource
                            self.tableView.reloadData()
                        }
                    }
                }
            }
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            tableView.estimatedRowHeight = 90;
            tableView.rowHeight = UITableViewAutomaticDimension
    
            if (service.isLoggedIn) {
                loadUserData()
            }
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    }
    

Hinzufügen der Kalender-BenutzeroberflächeAdd the Calendar UI

  1. Wählen Sie Main.storyboard im Project Navigator aus. Erweitern Sie in der Dokumentgliederung Second Scene, und wählen Sie dann Second aus.Select Main.storyboard in the Project navigator. In the document outline, expand Second Scene, then select Second.
  2. Öffnen Sie den Attributes Inspector, und ändern Sie den Wert für Title in Calendar.Open the Attributes inspector and change the Title to Calendar.
  3. Öffnen Sie den Identity Inspector, und ändern Sie den Wert für Class in CalendarViewController.Open the Identity inspector and change the Class to CalendarViewController.
  4. Erweitern Sie View, und löschen Sie die Beschriftungen Second View und Loaded by SecondViewController.Expand View and delete the Second View and Loaded by SecondViewController labels.
  5. Wählen Sie das Balkenelement Second am unteren Rand der Ansicht aus. Ändern Sie im Attributes Inspector den Wert für Title in Calendar.Select the Second bar item at the bottom of the view. On the Attributes inspector, change the Title to Calendar.
  6. Suchen Sie in der Object Library nach Table View. Ziehen Sie Table View in die Szene Calendar. Klicken Sie dann auf die Schaltfläche Add New Constraints in der unteren rechten Ecke des Zeichenbereichs. Legen Sie den linken, rechten und unteren Einschränkungswert auf 0 fest, und klicken Sie auf Add 4 Constraints.In the Object library, locate Table View. Drag Table View onto the Calendar scene. Then click the Add New Constraints button in the lower-right corner of the canvas. Set the left, right, top, and bottom constraint values to 0 and click Add 4 Constraints.
  7. Klicken Sie bei ausgewählter Tabellenansicht auf den Attributes Inspector, und legen Sie den Wert von Prototype Cells auf 1 fest.With the table view selected, click the Attributes inspector and set the value of Prototype Cells to 1.
  8. Suchen Sie in der Object Library nach Label. Ziehen Sie Label in die Prototypzelle der Tabellenansicht, doppelklicken Sie darauf, und ändern Sie den Text in Subject. Fügen Sie zwei weitere Beschriftungen hinzu, eine mit dem Text Start und eine mit dem Text End.In the Object library, locate Label. Drag Label onto the prototype cell in the table view, then double-click it and change the text to Subject. Add two more labels, one with text Start and one with text End.
  9. Nachdem Sie die Beschriftungen hinzugefügt haben, wählen Sie Calendar in der Dokumentgliederung aus. Wählen Sie im Menü Editor die Option Resolve Auto Layout Issues, dann Add Missing Constraints gefolgt von Reset to Suggested Constraints aus.Once you have the labels added, select Calendar in the Document outline. On the Editor menu, choose Resolve Auto Layout Issues, then Add Missing Constraints, followed by Reset to Suggested Constraints.
  10. Wählen Sie Calendar in der Dokumentgliederung aus. Ziehen Sie im Connections Inspector den kleinen Kreis neben tableView (unter Outlets) in die Tabellenansicht im Storyboard.Select Calendar in the Document outline. On the Connections inspector, drag the small circle beside tableView (under Outlets) to the table view on the storyboard.
  11. Wählen Sie EventCell in der Dokumentgliederung aus. Ziehen Sie im Connections Inspector den kleinen Kreis neben subjectLabel, startLabel und endLabel (unter Outlets) auf die entsprechenden Beschriftungen im Storyboard.Select EventCell in the Document outline. On the Connections inspector, drag the small circle beside subjectLabel, startLabel, and endLabel (under Outlets) to their respective labels on the storyboard.

Führen Sie die App aus. Denken Sie daran, sich ab- und erneut anzumelden, um den neuen Bereich abzurufen.Run the app. Be sure to logout and log back in to acquire the new scope.

Für die Kontakte-API:For Contacts API:

Hinzufügen einer Funktion zum Abrufen von KontaktenAdd a function to get contacts

  1. Wechseln Sie zu OutlookService.swift.Switch to OutlookService.swift.
  2. Aktualisieren Sie den Wert für scope im oauth2Settings-Wörterbuch, um den Contacts.Read-Bereich einzuschließen.Update the scope value in the oauth2Settings dictionary to include the Contacts.Read scope.

    "scope": "openid profile offline_access User.Read Mail.Read Contacts.Read",
    
  3. Fügen Sie die folgende Funktion zur OutlookService-Klasse hinzu:Add the following function to the OutlookService class.

    func getContacts(callback: @escaping (JSON?) -> Void) -> Void {
        let apiParams = [
            "$select": "givenName,surname,emailAddresses",
            "$orderby": "givenName ASC",
            "$top": "10"
        ]
    
        makeApiCall(api: "/v1.0/me/contacts", params: apiParams) {
            result in
            callback(result)
        }
    }
    

Hinzufügen der benutzerdefinierten Klasse „ContactCell“.Add the Contact table cell custom class

  1. Klicken Sie im Project Navigator bei gedrückter STRG-TASTE auf den Ordner swift-tutorial, und wählen Sie New File. Wählen Sie Swift File (unter iOS/Source) aus, und klicken Sie auf Next. Geben Sie ContactCell in das Feld Save As ein, und klicken Sie auf Create.In the Project navigator, CTRL + click the swift-tutorial folder and choose New File. Select Swift File (under iOS/Source) and click Next. Enter ContactCell in the Save As field and click Create.
  2. Fügen Sie den folgenden Code hinzu.Add the following code.

    import UIKit
    import SwiftyJSON
    
    struct Contact {
        let givenName: String
        let surname: String
        let email: String
    }
    
    class ContactCell: UITableViewCell {
        @IBOutlet weak var nameLabel: UILabel!
        @IBOutlet weak var emailLabel: UILabel!
    
        var givenName: String? {
            didSet {
                nameLabel.text = givenName! + " " + (surname ?? "")
            }
        }
    
        var surname: String? {
            didSet {
                nameLabel.text = (givenName ?? "") + " " + surname!
            }
        }
    
        var email: String? {
            didSet {
                emailLabel.text = email
            }
        }
    }
    
    class ContactsDataSource: NSObject {
        let contacts: [Contact]
    
        init(contacts: [JSON]?) {
            var ctctArray = [Contact]()
    
            if let unwrappedContacts = contacts {
                for (contact) in unwrappedContacts {
                    let newContact = Contact(
                        givenName: contact["givenName"].stringValue,
                        surname: contact["surname"].stringValue,
                        email: contact["emailAddresses"][0]["address"].stringValue)
    
                    ctctArray.append(newContact)
                }
            }
    
            self.contacts = ctctArray
        }
    }
    
    extension ContactsDataSource: UITableViewDataSource {
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return contacts.count
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: ContactCell.self)) as! ContactCell
            let contact = contacts[indexPath.row]
            cell.givenName = contact.givenName
            cell.surname = contact.surname
            cell.email = contact.email
            return cell
        }
    }
    

Implementieren des AnsichtscontrollersImplement the view controller

  1. Erweitern Sie im Project Navigator swift-tutorial->swift-tutorial, und wählen Sie dann SecondViewController.swift aus.In the Project navigator, expand swift-tutorial->swift-tutorial, then select SecondViewController.swift.
  2. Öffnen Sie den File Inspector, und ändern Sie den Dateinamen in ContactsViewController.swift.Open the File inspector and change the file name to ContactsViewController.swift.
  3. Ersetzen Sie den Dateiinhalt durch Folgendes.Replace the file contents with the following.

    import UIKit
    
    class ContactsViewController: UIViewController {
    
        @IBOutlet weak var tableView: UITableView!
    
        var dataSource: ContactsDataSource?
    
        let service = OutlookService.shared()
    
        func loadUserData() {
            service.getUserEmail() {
                email in
                if let unwrappedEmail = email {
                    NSLog("Hello \(unwrappedEmail)")
    
                    self.service.getContacts() {
                        contacts in
                        if let unwrappedContacts = contacts {
                            self.dataSource = ContactsDataSource(contacts: unwrappedContacts["value"].arrayValue)
                            self.tableView.dataSource = self.dataSource
                            self.tableView.reloadData()
                        }
                    }
                }
            }
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            tableView.estimatedRowHeight = 90;
            tableView.rowHeight = UITableViewAutomaticDimension
    
            if (service.isLoggedIn) {
                loadUserData()
            }
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    }
    

Hinzufügen der Kalender-BenutzeroberflächeAdd the Calendar UI

  1. Wählen Sie Main.storyboard im Project Navigator aus. Erweitern Sie in der Dokumentgliederung Second Scene, und wählen Sie dann Second aus.Select Main.storyboard in the Project navigator. In the document outline, expand Second Scene, then select Second.
  2. Öffnen Sie den Attributes Inspector, und ändern Sie den Wert für Title in Contacts.Open the Attributes inspector and change the Title to Contacts.
  3. Öffnen Sie den Identity Inspector, und ändern Sie den Wert für Class in ContactsViewController.Open the Identity inspector and change the Class to ContactsViewController.
  4. Erweitern Sie View, und löschen Sie die Beschriftungen Second View und Loaded by SecondViewController.Expand View and delete the Second View and Loaded by SecondViewController labels.
  5. Wählen Sie das Balkenelement Second am unteren Rand der Ansicht aus. Ändern Sie im Attributes Inspector den Wert für Title in Contacts.Select the Second bar item at the bottom of the view. On the Attributes inspector, change the Title to Contacts.
  6. Suchen Sie in der Object Library nach Table View. Ziehen Sie Table View in die Szene Contacts. Klicken Sie dann auf die Schaltfläche Add New Constraints in der unteren rechten Ecke des Zeichenbereichs. Legen Sie den linken, rechten und unteren Einschränkungswert auf 0 fest, und klicken Sie auf Add 4 Constraints.In the Object library, locate Table View. Drag Table View onto the Contacts scene. Then click the Add New Constraints button in the lower-right corner of the canvas. Set the left, right, top, and bottom constraint values to 0 and click Add 4 Constraints.
  7. Klicken Sie bei ausgewählter Tabellenansicht auf den Attributes Inspector, und legen Sie den Wert von Prototype Cells auf 1 fest.With the table view selected, click the Attributes inspector and set the value of Prototype Cells to 1.
  8. Suchen Sie in der Object Library nach Label. Ziehen Sie Label in die Prototypzelle der Tabellenansicht, doppelklicken Sie darauf, und ändern Sie den Text in Name. Fügen Sie eine weitere Beschriftung mit dem Text Email hinzu.In the Object library, locate Label. Drag Label onto the prototype cell in the table view, then double-click it and change the text to Name. Add another label with text Email.
  9. Nachdem Sie die Beschriftungen hinzugefügt haben, wählen Sie Contacts in der Dokumentgliederung aus. Wählen Sie im Menü Editor die Option Resolve Auto Layout Issues, dann Add Missing Constraints gefolgt von Reset to Suggested Constraints aus.Once you have the labels added, select Contacts in the Document outline. On the Editor menu, choose Resolve Auto Layout Issues, then Add Missing Constraints, followed by Reset to Suggested Constraints.
  10. Wählen Sie Contacts in der Dokumentgliederung aus. Ziehen Sie im Connections Inspector den kleinen Kreis neben tableView (unter Outlets) in die Tabellenansicht im Storyboard.Select Contacts in the Document outline. On the Connections inspector, drag the small circle beside tableView (under Outlets) to the table view on the storyboard.
  11. Wählen Sie ContactCell in der Dokumentgliederung aus. Ziehen Sie im Connections Inspector den kleinen Kreis neben nameLabel und emailLabel (unter Outlets) auf die entsprechenden Beschriftungen im Storyboard.Select ContactCell in the Document outline. On the Connections inspector, drag the small circle beside nameLabel and emailLabel (under Outlets) to their respective labels on the storyboard.

Führen Sie die App aus. Denken Sie daran, sich ab- und erneut anzumelden, um den neuen Bereich abzurufen.Run the app. Be sure to logout and log back in to acquire the new scope.