如何列出 Google 驱动器根文件夹中的文件和文件夹

How to list files and folder in Google drive root folder

此代码用于在我的 iOS 应用程序中显示 google 驱动器内容。现在我可以使用下面的查询 "mimeType ='\(mimeType)' or mimeType = 'application/vnd.google-apps.folder'".

登录并显示内容

问题是 returns 所有的 mp3 文件甚至是子文件夹中的文件,这不是我想要的。我想显示与 google 驱动器根目录相同的结构。然后当用户进入任何子文件夹时,我会发送另一个请求来检索该子文件夹中的 mp3 文件。

那么我该如何重建这个查询来实现它呢?

// filter/search google 驱动文件的代码。

import Foundation
import GoogleAPIClientForREST

class GoogleDriveAPI {
    private let service: GTLRDriveService
    
    init(service: GTLRDriveService) {
        self.service = service
    }
    
    public func search(_ mimeType: String, onCompleted: @escaping ([GTLRDrive_File]?, Error?) -> ()) {
        let query = GTLRDriveQuery_FilesList.query()
        query.pageSize = 100
        query.q = "mimeType ='\(mimeType)' or mimeType = 'application/vnd.google-apps.folder'"
        self.service.executeQuery(query) { (ticket, results, error) in
            onCompleted((results as? GTLRDrive_FileList)?.files, error)
        }
    }

如果你这样做 mimeType = 'application/vnd.google-apps.folder' 那么你就是在告诉它你只需要文件夹或特定的 mime 类型。

如果你这样做 'root' in parents" 它会 return 父文件夹为 root 的所有内容。

因此,如果您这样做 'root' in parents" and mimeType = 'application/vnd.google-apps.folder',您将获得所有具有根父文件夹的文件夹。

根据 DalmTo 的回答,我更改了我的代码并进行了一些测试。现在我得到了我想要的。

简而言之,我将列表文件分为两步,首先使用query = 'root' in parents"进行搜索,这将列出根文件夹中的所有内容。然后我在将该数据源传递给另一个 ViewController.

之前执行过滤器 files?.filter { [=13=].mimeType == "audio/mpeg" || [=13=].mimeType == "application/vnd.google-apps.folder"}

为此,我获取根目录下的每个文件夹和根目录下的每个 mp3 文件,其他类型的文件将被忽略。然后,如果用户在根目录中输入一个文件夹,我将执行另一个 http 请求(文件列表)以获取其内容。

Google 驱动 API 函数。
import Foundation
import GoogleAPIClientForREST

class GoogleDriveAPI {
    private let service: GTLRDriveService
    
    init(service: GTLRDriveService) {
        self.service = service
    }
    
    public func search(onCompleted: @escaping ([GTLRDrive_File]?, Error?) -> ()) {
        let query = GTLRDriveQuery_FilesList.query()
        query.pageSize = 100
        // query.q = "mimeType ='\(mimeType)' or mimeType = 'application/vnd.google-apps.folder'"
        query.q = "'root' in parents"
        self.service.executeQuery(query) { (ticket, results, error) in
            onCompleted((results as? GTLRDrive_FileList)?.files, error)
        }
    }

从 ViewController 调用 api,我在这里放了一点上下文来说明。

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .gray
        
        setViews()
        
        // add an observer on notification "userDidSignInGoogle"
        NotificationCenter.default.addObserver(self, selector: #selector(userDidSignInGoogle), name: .signInGoogleCompleted, object: nil)
        
        setUpGoogleSignIn()
    }
    
    func setUpGoogleSignIn() {
        GIDSignIn.sharedInstance().delegate = self
        GIDSignIn.sharedInstance().uiDelegate = self
        GIDSignIn.sharedInstance().scopes = [kGTLRAuthScopeDrive]
        GIDSignIn.sharedInstance().signInSilently()
    }
    
    // MARK: - Notification
    @objc private func userDidSignInGoogle(_ notification: Notification) {
        // Update screen after user successfully signed in
        updateScreen()
        print("userDidSignInGoogle")
        listAudioFilesAndFolders()
    }

    func listAudioFilesAndFolders() {
        self.googleAPIs?.search(onCompleted: { files, error in
            guard error == nil, files != nil else {
                print("Err: \(String(describing: error))")
                return
            }
            
            self.dismiss(animated: true) {
                let vc = GoogleDriveFilesViewController()
                // filter the files before passing it.
                vc.audioFilesAndFolders = files?.filter { [=11=].mimeType == "audio/mpeg" || [=11=].mimeType == "application/vnd.google-apps.folder"}
                UIApplication.getTopMostViewController()?.present(vc, animated: true)
            }
        })
    }