Swift3 I';我正在尝试导入GoogleapClient或GoogleapClient Forest

Swift3 I';我正在尝试导入GoogleapClient或GoogleapClient Forest,swift3,google-api,ios10,xcode8-beta2,Swift3,Google Api,Ios10,Xcode8 Beta2,我试图继续制作他们的QuickStart应用程序,学习如何使用Swift进行API调用。我完全按照教程进行操作,最后得到了这段代码 import GoogleAPIClient import GTMOAuth2 import UIKit class ViewController: UIViewController { private let kKeychainItemName = "Drive API" private let kClientID = "59201906116

我试图继续制作他们的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
我得到了一个错误“没有这样的模块GoogleAppClient”,这对我来说似乎很奇怪,因为GTMOAuth2没有得到错误,即使它是我认为的同一个Pod的一部分(我对它不熟悉,所以我可能是在破坏术语)

通过研究这个问题,我发现GoogleapClient应该被GoogleapClient所取代。说只在代码中使用GoogleAppClient而不是GoogleAppClient,但我也得到了同样的错误

然后我想也许我可以重新安装pods,对谷歌的教程做一些修改。在教程中,它说在终端中执行此代码

$ 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
$cat Podfile&&
>平台:ios,“7.0”
>使用你的框架!
>目标“QuickstartApp”执行
>pod“GoogleAppClient/Drive”,“~>1.0.2”
>pod“GTMOAuth2”,“~>1.1.0”
>结束
>EOF
>吊舱安装&&
>打开QuickstartApp.xcworkspace
所以我想也许我可以在终端代码中将GoogleAppClient替换为GoogleAppClient,但这让我遇到了同样的错误

正如您在屏幕截图中看到的,框架在左侧,但我仍然得到“没有这样的模块”错误

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

搜索路径

我还发现了一些我试图遵循的建议,但我没有完全理解其中的解释。尽管如此,我还是尝试了,并且做到了(如果我做错了,请告诉我):


所以我想让GoogleAplient或GoogleAplientForest工作。感谢您的帮助

将此文件用于您的播客文件:

platform :ios, '7.0'
use_frameworks!
target 'QuickstartApp' do
    pod 'GoogleAPIClientForREST/Drive', '~> 1.1.1'
    pod 'GTMOAuth2', '~> 1.1.0'
end
将导入更改为

import GoogleAPIClientForREST
然后按照此处的说明迁移项目:

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

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

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


虽然我为您指出的解决方案可能适用于其他库,但它肯定会对您有所帮助。如果我需要为您简化它,请尝试告诉我。

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

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

看起来cocoapods构建了您的工作区,您确实打开了工作区而不是项目。那很好

检查名为“Podfile”的文件的内容。它应该匹配:

platform :ios, '7.0'
use_frameworks!
target 'QuickstartApp' do
    pod 'GoogleAPIClient/Drive', '~> 1.0.2'
    pod 'GTMOAuth2', '~> 1.1.0'
end
如果没有,请修复它,退出Xcode,删除.Xcode工作区文件,然后运行

pod install
从控制台。这可能会修复依赖关系,以便Xcode构建框架

如果您确实编译了它,那么您的问题才刚刚开始。谷歌已经否决了来自嵌入式用户代理的OAAuth授权


因此,我也完全遵循了快速入门教程,并且能够让它正常工作。我将GoogleapClientForrest框架搜索路径移动到GTMOAuth2上方:

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


当然,现在谷歌已经弃用了GTMOAuth2,并用GTMAppAuth取代它,这使得这个应用程序毫无用处。

我按照你的指示做了,我得到了同样的错误“没有这样的模块”。然后你重新运行pod安装?你在项目的Pods子目录中看到GoogleapClientForrest了吗?是的,我重新运行pod安装,GoogleapClientForrest确实在Pods子目录中。我用截图更新了我的原始问题。请查看倒数第二个截图。你可以在截图中看到子目录。看起来很有趣ting。我们正在查看的所有这些条目都定义了在何处查找原始文件和生成期间生成的文件。正如您所说,奇怪的是GTMOAuth2导入很好,但GoogleapClientForrest没有。框架搜索路径行被截断,因此我看不到是否包含GoogleapClientForrest。单击调试或发布部分,然后单击请确保您在那里看到它。另外,请查看您是否有如本文中所述的xconfig文件,并且条目是否一致。因此,简而言之,您希望查看这些不同的搜索路径,并确保您在GTMOAuth2中看到的任何条目都有与GoogleAppClientForest匹配的条目。您提供的用于更改框架搜索路径的注释链接,但是您附加的图像没有显示该内容。我已在回答中附加了正确部分的图像。您是否打开了QuickStart.xcworkspace(例如,
打开QuickStart.xcworkspace/
)从命令行进入XCode?是的,我通过命令行打开了它。为什么?我还重新构建了项目,不考虑搜索路径,所以它们现在是默认的。只需检查打开的部分。尝试跟踪项目的不同之处或不寻常之处。您使用的XCode版本和操作系统是什么?因为代码很小,y您可能会尝试删除该项目,然后使用新的pod文件重新开始导入。我使用的是Xcode 8.2、OS X 10.11.6和iOS 10.1。我已经多次使用相同的问题开始了。您不认为GTMOAuth2导入很好,而不是GoogleapClientForest很重要吗?是的