我尝试导入GoogleAPIClient或GoogleAPIClientForREST

时间:2017-01-04 00:20:03

标签: swift3 google-api ios10 xcode8-beta2

我尝试关注Google's tutorial制作QuickStart应用,了解如何使用Swift进行API调用。我完全遵循了教程,最后得到了这段代码

import GoogleAPIClient
import GTMOAuth2
import UIKit

class ViewController: UIViewController {

    private let kKeychainItemName = "Drive API"
    private let kClientID = "592019061169-nmjle7sfv8i8eahplae3cvto2rsj4gev.apps.googleusercontent.com"

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

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

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

        output.frame = view.bounds
        output.editable = false
        output.contentInset = UIEdgeInsets(top: 20, left: 0, bottom: 20, right: 0)
        output.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]

        view.addSubview(output);

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

    }

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

    // Construct a query to get names and IDs of 10 files using the Google Drive API
    func fetchFiles() {
        output.text = "Getting files..."
        let query = GTLQueryDrive.queryForFilesList()
        query.pageSize = 10
        query.fields = "nextPageToken, files(id, name)"
        service.executeQuery(
            query,
            delegate: self,
            didFinishSelector: "displayResultWithTicket:finishedWithObject:error:"
        )
    }

    // Parse results and display
    func displayResultWithTicket(ticket : GTLServiceTicket,
                                 finishedWithObject response : GTLDriveFileList,
                                 error : NSError?) {

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

        var filesString = ""

        if let files = response.files(), !files.isEmpty {
            filesString += "Files:\n"
            for file in files as! [GTLDriveFile] {
                filesString += "\(file.name) (\(file.identifier))\n"
            }
        } else {
            filesString = "No files found."
        }

        output.text = filesString
    }


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

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

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

        service.authorizer = authResult
        dismissViewControllerAnimated(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)
        presentViewController(alert, animated: true, completion: nil)
    }

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

}

我的问题是

import GoogleAPIClient

我收到错误" 没有这样的模块GoogleAPIClient ",这对我来说似乎很奇怪,因为GTMOAuth2没有收到错误,即使它没有我认为是同一个Pod的一部分(我对此很新,所以我可能会对术语进行屠宰)。

通过研究问题,我发现GoogleAPIClientForREST应该替代GoogleAPIClient。 This document on GitHub说只是在代码中使用GoogleAPIClientForREST而不是GoogleAPIClient,但我也会遇到相同的错误。

然后我想也许我可以通过对Google教程的一些更改来重新安装pod。在本教程中,它说要在终端

中执行此代码
$ cat << EOF > Podfile &&
> platform :ios, '7.0'
> use_frameworks!
> target 'QuickstartApp' do
>     pod 'GoogleAPIClient/Drive', '~> 1.0.2'
>     pod 'GTMOAuth2', '~> 1.1.0'
> end
> EOF
> pod install &&
> open QuickstartApp.xcworkspace

所以我想也许我可以在终端代码中替换GoogleAPIClient for GoogleAPIClientForREST,但这给我带来了同样的错误

enter image description here

正如您在屏幕截图中看到的那样,框架位于左侧,但我仍然得到了#34;没有这样的模块&#34;错误。

嵌入式二进制文件和链接框架

enter image description here

搜索路径

enter image description here

enter image description here

我还发现了一些我试图遵循的建议here,但我并没有完全理解这些解释。不过,我试过了,并且这样做了(如果我做错了请告诉我): enter image description here

所以我试图让GoogleAPIClient或GoogleAPIClientForREST工作。谢谢你的帮助

4 个答案:

答案 0 :(得分:1)

将此用于您的Podfile:

platform :ios, '7.0'
use_frameworks!
target 'QuickstartApp' do
    pod 'GoogleAPIClientForREST/Drive', '~> 1.1.1'
    pod 'GTMOAuth2', '~> 1.1.0'
end

将导入更改为

import GoogleAPIClientForREST

然后按照此处的说明迁移项目: Migrating from GoogleAPIClient to GoogleAPIClientForREST

这主要涉及通过一些单词交换将GTL调用更改为GTLR调用。例如,GTLServiceDrive变为GTLRDriveService

关于框架搜索路径,此图像显示了您可能需要更改的部分(请注意它适用于我使用默认值):

enter image description here

搜索路径也可以是每个目标。这是显示应用程序目标和框架搜索路径的图像:

enter image description here

答案 1 :(得分:0)

虽然我指向你的解决方案可能适用于其他库,但它肯定会帮助你。 https://stackoverflow.com/a/25874524/5032645。请尝试让我知道,如果我应该为您简化它。

答案 2 :(得分:0)

首先,查看Quickstart项目的Frameworks组中的Pods_QuickstartApp.framework。如果它仍然是红色的,就像你的屏幕截图一样,那么Xcode并没有构建它。如果Xcode没有构建框架,Xcode就无法为您导入它。

Cocoapods构建一个包含您的应用程序项目的工作区,以及另一个将您的个人pod框架组装成更大框架的项目。

似乎cocoapods构建了您的工作区,您确实打开了工作区而不是项目。这很好。

检查名为&#34; Podfile&#34;的文件的内容。它应匹配:

platform :ios, '7.0'
use_frameworks!
target 'QuickstartApp' do
    pod 'GoogleAPIClient/Drive', '~> 1.0.2'
    pod 'GTMOAuth2', '~> 1.1.0'
end

如果没有,请修复它,退出Xcode,删除.xcodeworkspace文件,然后运行

pod install
从控制台

。这可能会修复您的依赖项,以便Xcode构建框架。

如果你确实要编译,你的问题才刚刚开始。 Google已弃用嵌入式用户代理的OAAuth授权。

OAAuth authorization from embedded user-agent deprecated

答案 3 :(得分:0)

因此,我完全按照快速入门教程开始,并且能够使其正常运行。我在框架搜索路径中移动了GoogleAPIClientForRest,高于GTMOAuth2:

Screenshot

成功包含模块后,我在代码中遇到错误,不得不更改此行以使其生成并运行: if (result.files!.countif (result.files!.count > 0)

当然,谷歌已弃用GTMOAuth2并将其替换为GTMAppAuth,这使得该应用无用。