在 Swift 中获取 Google 日历

Kal*_*ell 3 xcode google-calendar-api swift

我正在尝试编写一个执行以下操作的应用程序:

  • 检索 Google 日历事件
  • 在 google 事件中使用 Location 并将其存储在本地

我已经设法将 GoogleAPi 设置为我的项目并启用了相关的 APi。但是,我不完全确定如何获取上述信息。

任何指导或材料链接都将非常有帮助

Au *_*Ris 7

尽管 Google 有很好的 API 文档,但 Swift 中几乎没有示例,尤其是在 Calendar API 方面。所以我理解你的沮丧。

首先,你很幸运,因为库是可用的,而且你不必手动实现登录和日历 API 的网络调用。如果您使用 Cocoapods(我强烈推荐)添加以下 pod:

target 'YourApp' do
    pod 'GoogleAPIClientForREST/Calendar'
    pod 'GoogleSignIn'
end
Run Code Online (Sandbox Code Playgroud)

如果你不使用 Cocoapods,你可以在 github 上找到它们。库的名称是不言自明的。GoogleAPIClientForREST/Calendar是用 Objective-C 编写的,至少在我的情况下,我必须使用以下导入创建一个桥接头文件:

#ifndef MyApp_Bridging_Header_h
#define MyApp_Bridging_Header_h

#import <GTMSessionFetcher/GTMSessionFetcher.h>
#import <GTMSessionFetcher/GTMSessionFetcherService.h>

#endif 
Run Code Online (Sandbox Code Playgroud)

为了让日历库获取日历、事件等,您需要有一个登录用户。所以首先你需要实现登录。确保正确配置 Google 登录服务。不要忘记设置范围。

import GoogleSignIn

func initGoogle() {
    // Initialize sign-in
    var configureError: NSError?
    GGLContext.sharedInstance().configureWithError(&configureError)
    assert(configureError == nil, "Error configuring Google services: \(String(describing: configureError))")
    GIDSignIn.sharedInstance().clientID = "your_client_id_string"
    GIDSignIn.sharedInstance().scopes = ["https://www.googleapis.com/auth/calendar"]
    GIDSignIn.sharedInstance().delegate = self
}
Run Code Online (Sandbox Code Playgroud)

实现GIDSignInDelegate方法并相应地处理它们的回调(因为您只能在用户登录时获取日历)。开始登录流程:

GIDSignIn.sharedInstance().signIn()
Run Code Online (Sandbox Code Playgroud)

假设所有配置都正确,您应该能够成功登录。

当你有一个谷歌会话时,然后获取日历数据。这是会发生很多逆向工程的地方,因为日历库没有很好的文档记录。查阅 API 参考以了解不同模型之间的关系:https : //developers.google.com/calendar/v3/reference/

但是在获取日历数据之前,您需要创建日历服务对象:

import GoogleAPIClientForREST
import GoogleSignIn

/// Creates calendar service with current authentication
fileprivate lazy var calendarService: GTLRCalendarService? = {
    let service = GTLRCalendarService()
    // Have the service object set tickets to fetch consecutive pages
    // of the feed so we do not need to manually fetch them
    service.shouldFetchNextPages = true
    // Have the service object set tickets to retry temporary error conditions
    // automatically
    service.isRetryEnabled = true
    service.maxRetryInterval = 15

    guard let currentUser = GIDSignIn.sharedInstance().currentUser,
        let authentication = currentUser.authentication else {
            return nil
    }

    service.authorizer = authentication.fetcherAuthorizer()
    return service
}()
Run Code Online (Sandbox Code Playgroud)

最后获取日历 ID 的事件:

// you will probably want to add a completion handler here
func getEvents(for calendarId: String) {
    guard let service = self.calendarService else {
        return
    }

    // You can pass start and end dates with function parameters
    let startDateTime = GTLRDateTime(date: Calendar.current.startOfDay(for: Date()))
    let endDateTime = GTLRDateTime(date: Date().addingTimeInterval(60*60*24))

    let eventsListQuery = GTLRCalendarQuery_EventsList.query(withCalendarId: calendarId)
    eventsListQuery.timeMin = startDateTime
    eventsListQuery.timeMax = endDateTime

    _ = service.executeQuery(eventsListQuery, completionHandler: { (ticket, result, error) in
        guard error == nil, let items = (result as? GTLRCalendar_Events)?.items else {
            return
        }

        if items.count > 0 {
            print(items)
            // Do stuff with your events
        } else {
            // No events
        }
    })
}
Run Code Online (Sandbox Code Playgroud)

GTLRCalendar_Event其中location有财产。

为了获取日历列表、忙/闲信息、创建事件等其他数据,您必须像我上面提到的那样进行一些逆向工程。