LoginSignup
8
8

More than 5 years have passed since last update.

Swift3でGoogle Calendarから予定の取得

Posted at

Swift3 で Google Calendar から予定を取得しようとした際に詰まったので、メモ程度にまとめます。
基本的には以下のサイトの通りです。

参考サイト
Google Developer iOS Quickstart

OAuth client ID の取得

Step1 の手順に従って OAuth client ID を取得します。

Podfileの作成

以下のように作成します。

Podfile
use_frameworks!

target 'App Name' do
  pod 'GoogleAPIClient/Calendar', '~> 1.0.2'
  pod 'GTMOAuth2', '~> 1.1.0'
end

Google Calendar から予定の取得

ほとんどサンプルコードからコンパイルエラーを修正していく感じですが、以下のように変更が必要です。

func fetchEvents() {
    let query = GTLQueryCalendar.queryForEventsList(withCalendarId: "primary")
    query?.maxResults = 10
    query?.timeMin = GTLDateTime(date: NSDate() as Date!, timeZone: NSTimeZone.local)
    query?.singleEvents = true
    query?.orderBy = kGTLCalendarOrderByStartTime
    service.executeQuery(
        query!,
        delegate: self,
-       didFinishSelector: "displayResultWithTicket:finishedWithObject:error:"
+       didFinish: #selector(ViewController.displayResultWithTicket(ticket:finishedWithObject: error:))
    )
}
private func createAuthController() -> GTMOAuth2ViewControllerTouch {
    let scopeString = scopes.joined(separator: " ")
    return GTMOAuth2ViewControllerTouch(
        scope: scopeString,
        clientID: kClientID,
        clientSecret: nil,
        keychainItemName: kKeychainItemName,
        delegate: self,
-       finishedSelector: "viewController:finishedWithAuth:error:"
+       finishedSelector: #selector(ViewController.viewController(vc: finishedWithAuth: error:))
    )
}

結果、こんな感じで予定を取得できます。

ViewController.swift は以下の通りです。

ViewController
import GoogleAPIClient
import GTMOAuth2
import UIKit

class ViewController: UIViewController {
    private let kKeychainItemName = "Google Calendar API"
    private let kClientID = "CLIENT ID"

    // If modifying these scopes, delete your previously saved credentials by
    // resetting the iOS simulator or uninstall the app.
    private let scopes = [kGTLAuthScopeCalendarReadonly]

    private let service = GTLServiceCalendar()
    let output = UITextView()

    // When the view loads, create necessary subviews
    // and initialize the Google Calendar API service
    override func viewDidLoad() {
        super.viewDidLoad()

        output.frame = view.bounds
        output.isEditable = false
        output.contentInset = UIEdgeInsets(top: 20, left: 0, bottom: 20, right: 0)
        output.autoresizingMask = [.flexibleHeight, .flexibleWidth]

        view.addSubview(output);

        if let auth = GTMOAuth2ViewControllerTouch.authForGoogleFromKeychain(
            forName: kKeychainItemName,
            clientID: kClientID,
            clientSecret: nil) {
            service.authorizer = auth
        }
    }

    // When the view appears, ensure that the Google Calendar API service is authorized
    // and perform API calls
    override func viewDidAppear(_ animated: Bool) {
        if let authorizer = service.authorizer,
            let canAuth = authorizer.canAuthorize , canAuth {
            fetchEvents()
        } else {
            present(
                createAuthController(),
                animated: true,
                completion: nil
            )
        }
    }

    // Construct a query and get a list of upcoming events from the user calendar
    func fetchEvents() {
        let query = GTLQueryCalendar.queryForEventsList(withCalendarId: "primary")
        query?.maxResults = 10
        query?.timeMin = GTLDateTime(date: NSDate() as Date!, timeZone: NSTimeZone.local)
        query?.singleEvents = true
        query?.orderBy = kGTLCalendarOrderByStartTime
        service.executeQuery(
            query!,
            delegate: self,
            didFinish: #selector(ViewController.displayResultWithTicket(ticket:finishedWithObject: error:))
        )
    }

    // Display the start dates and event summaries in the UITextView
    func displayResultWithTicket(ticket: GTLServiceTicket, finishedWithObject response : GTLCalendarEvents, error : NSError?) {

        if let error = error {
            showAlert(title: "Error", message: error.localizedDescription)
            return
        }

        var eventString = ""

        if let events = response.items() , !events.isEmpty {
            for event in events as! [GTLCalendarEvent] {
                let start : GTLDateTime! = event.start.dateTime ?? event.start.date
                let startString = DateFormatter.localizedString(
                    from: start.date,
                    dateStyle: .short,
                    timeStyle: .short
                )
                eventString += "\(startString) - \(event.summary)\n"
            }
        } else {
            eventString = "No upcoming events found."
        }

        output.text = eventString
    }


    // Creates the auth controller for authorizing access to Google Calendar API
    private func createAuthController() -> GTMOAuth2ViewControllerTouch {
        let scopeString = scopes.joined(separator: " ")
        return GTMOAuth2ViewControllerTouch(
            scope: scopeString,
            clientID: kClientID,
            clientSecret: nil,
            keychainItemName: kKeychainItemName,
            delegate: self,
            finishedSelector: #selector(ViewController.viewController(vc: finishedWithAuth: error:))
        )
    }

    // Handle completion of the authorization process, and update the Google Calendar API
    // with the new credentials.
    func viewController(vc : UIViewController, finishedWithAuth authResult : GTMOAuth2Authentication, error : NSError?) {

        if let error = error {
            service.authorizer = nil
            showAlert(title: "Authentication Error", message: error.localizedDescription)
            return
        }

        service.authorizer = authResult
        dismiss(animated: true, completion: nil)
    }

    // Helper for showing an alert
    func showAlert(title : String, message: String) {
        let alert = UIAlertController(
            title: title,
            message: message,
            preferredStyle: UIAlertControllerStyle.alert
        )
        let ok = UIAlertAction(
            title: "OK",
            style: UIAlertActionStyle.default,
            handler: nil
        )
        alert.addAction(ok)
        present(alert, animated: true, completion: nil)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}
8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8