Zhiting cloud disk - development guide iOS: file list and permission description

Posted by ianhull on Sat, 12 Feb 2022 10:28:22 +0100

1. List of documents

1.1 my file - myfileviewcontroller swift

  • Data acquisition - acquire data through SA interface
        NetworkManager.shared.fileList(path: "/", page: page, page_size: 30) { [weak self] response in
            guard let self = self else { return }
            LoadingView.hide()
            self.tableView.mj_header?.endRefreshing()
            self.tableView.mj_footer?.endRefreshing()
    
            //Delete files without readable permissions
            let datas = response.list.filter({$0.read != 0})
            
            if isReload {//Pull down refresh or first load data
                if datas.count == 0 {
                    self.tableView.mj_footer?.isHidden = true
                    self.tableView.reloadData()
                    }else{
                        self.emptyView.removeFromSuperview()
                        self.currentDatas = datas
                        self.tableView.reloadData()
                    }
            }else{//Pull up to load more data
                if !response.pager.has_more {//No data
                    self.tableView.mj_footer?.endRefreshingWithNoMoreData()
                    self.isGetAllData = true
                    return
                }
                self.isGetAllData = false
                self.currentDatas += datas
                self.tableView.reloadData()
            }
        } failureCallback: {[weak self] code, err in
            guard let self = self else { return }
            LoadingView.hide()
            self.tableView.mj_header?.endRefreshing()
            self.tableView.mj_footer?.endRefreshing()
            
            if self.currentDatas.count == 0 {
                self.tableView.addSubview(self.emptyView)
                    self.emptyView.snp.makeConstraints {
                        $0.center.equalToSuperview()
                        $0.width.equalTo(Screen.screenWidth)
                        $0.height.equalTo(ZTScaleValue(110))
                    }
                }else{
                    self.emptyView.removeFromSuperview()
                }
            self.showToast("\(err)")
        }
  • This page has no selection function
  • Click the folder to enter your own directory
            let vc = ChangeFolderPlaceController()
            let nav = UINavigationController(rootViewController: vc)
            nav.modalPresentationStyle = .fullScreen
            self.present(nav, animated: true, completion: nil)

1.2 shared file - sharefileviewcontroller swift

Users can get folders shared by other users

///Request list data
private func getDiskData(){
        let page = (currentDatas.count / 30) + 1
        
        NetworkManager.shared.shareFileList(page: page, page_size: 30) { [weak self] response in
            guard let self = self else {return}
            print("Request succeeded")
            LoadingView.hide()
            self.tableView.mj_header?.endRefreshing()
            self.tableView.mj_footer?.endRefreshing()
            
            //Delete files without readable permissions
            let datas = response.list.filter({$0.read != 0})
            self.currentDatas.append(contentsOf: datas)
            
            
            if !response.pager.has_more {
                self.tableView.mj_footer?.endRefreshingWithNoMoreData()
            }

            if self.currentDatas.count == 0 {
                //Empty data display page
                self.tableView.addSubview(self.emptyView)
                self.emptyView.snp.makeConstraints {
                    $0.center.equalToSuperview()
                    $0.width.equalTo(Screen.screenWidth)
                    $0.height.equalTo(ZTScaleValue(110))
                }
                self.tableView.reloadData()
            }else{
                
                self.emptyView.removeFromSuperview()
                self.tableView.reloadData()
            }

        } failureCallback: {[weak self] code, err in
            guard let self = self else { return }
            print("request was aborted")
            LoadingView.hide()
            self.tableView.mj_header?.endRefreshing()

            if self.currentDatas.count == 0 {
                //Empty data display page
                self.tableView.addSubview(self.emptyView)
                    self.emptyView.snp.makeConstraints {
                        $0.center.equalToSuperview()
                        $0.width.equalTo(Screen.screenWidth)
                        $0.height.equalTo(ZTScaleValue(110))
                    }
                }else{
                    self.emptyView.removeFromSuperview()
                }
            self.showToast("\(err)")
        }
    }
  • The logic of shared files is roughly the same as that of my file page, but the folders shared by other users allow the selection of function modules
       // MARK: - funtionTabbarAction
        funtionTabbarView.shareBtn.clickCallBack = { _ in
            print("Click share to")
            let shareVC = FileShareController()
            shareVC.fileDatas = self.seletedFiles
            self.navigationController?.pushViewController(shareVC, animated: true)
            self.hideFunctionTabbarView()
        }
        funtionTabbarView.downloadBtn.clickCallBack = { _ in
            print("Click download")
        }
        funtionTabbarView.copyBtn.clickCallBack = {[weak self] _ in
            guard let self = self else {return}
            print("Click Copy to")
            let vc = ChangeFolderPlaceController()
            vc.isRootPath = true
            vc.currentPaths = ["root directory"]
            vc.seletedFiles = self.seletedFiles
            vc.type = .copy
            let nav = UINavigationController(rootViewController: vc)
            nav.modalPresentationStyle = .fullScreen
            self.present(nav, animated: true, completion: nil)
            self.hideAllFuntionView()
        }
        funtionTabbarView.resetNameBtn.clickCallBack = { [weak self] _ in
            guard let self = self else { return }
            print("Click rename")
            guard let file = self.seletedFiles.first else { return }
            self.showResetNameView(name: file.name, isFile: file.type == 1)
            self.setNameView?.setNameCallback = { name in
                if name.isEmpty {
                    SceneDelegate.shared.window?.makeToast("Please enter a name".localizedString)
                    return
                }
                if let originalExtension = file.name.components(separatedBy: ".").last,
                   let newExtension = name.components(separatedBy: ".").last
                {
                    if originalExtension != newExtension && file.type == 1 {
                        let alertViewController = UIAlertController(title: "", message: "Changing the file type may make the file unavailable,Continue?", preferredStyle: .alert)
                        alertViewController.addAction(UIAlertAction(title: "cancel".localizedString, style: .cancel, handler: nil))
                        alertViewController.addAction(UIAlertAction(title: "determine".localizedString, style: .default, handler: { [weak self] _ in
                            guard let self = self else { return }
                            LoadingView.show()
                            
                            NetworkManager.shared.renameFile(path: file.path, name: name) { [weak self] response in
                                guard let self = self else { return }
                                file.name = name
                                self.setNameView?.removeFromSuperview()
                                self.hideAllFuntionView()
                                self.tableView.reloadData()
                                LoadingView.hide()
                                SceneDelegate.shared.window?.makeToast("Rename successful".localizedString)
                            } failureCallback: { code, err in
                                SceneDelegate.shared.window?.makeToast(err)
                                LoadingView.hide()
                            }
                        }))
                        self.present(alertViewController, animated: true, completion: nil)
                        return
                    }
                }


1.3 folder subset Directory - folderviewcontroller swift

  1. The subset directory can exist in the form of various types of files, which can be distinguished according to the type of data model.

2. Click "file type" in the subset directory to display functionView, and the function is opened according to the permission.
3. Subset directory files and folders can be selected to display the function tabbar.

2. Folder sharing

Users can share folders with selected users and give them read, write and delete permissions according to their own needs

   ///Share folders with users
    private func shareFilesToCloud() {
        
        var filePaths = [String]()
        for file in fileDatas {
            filePaths.append(file.path)
        }
        
        if seletedUsers.count == 0 {
            return
        }
        let userIds = seletedUsers.map(\.user_id)
        let editMemberAlert = EditShareMemberAlert()
        editMemberAlert.set(members: seletedUsers)
        editMemberAlert.reSetBtn()
        //Authority judgment
        if self.fileDatas.filter({ $0.read == 0 }).count > 0 {//No read permission
            editMemberAlert.readBtn.isUserInteractionEnabled = false
            editMemberAlert.readBtn.alpha = 0.5
        } else {
            editMemberAlert.readBtn.isUserInteractionEnabled = true
            editMemberAlert.readBtn.alpha = 1
            editMemberAlert.readBtn.isSelected = true
        }
        if self.fileDatas.filter({ $0.write == 0 }).count > 0 {//No write permission
            editMemberAlert.writeBtn.isUserInteractionEnabled = false
            editMemberAlert.writeBtn.alpha = 0.5
        } else {
            editMemberAlert.writeBtn.isUserInteractionEnabled = true
            editMemberAlert.writeBtn.alpha = 1
        }
        if self.fileDatas.filter({ $0.deleted == 0 }).count > 0 {//No permission to delete
            editMemberAlert.deleteBtn.isUserInteractionEnabled = false
            editMemberAlert.deleteBtn.alpha = 0.5
        } else {
            editMemberAlert.deleteBtn.isUserInteractionEnabled = true
            editMemberAlert.deleteBtn.alpha = 1
        }
        editMemberAlert.sureCallback = { [weak self] read, write, delete in
            guard let self = self else { return }
            LoadingView.show()
            NetworkManager.shared.shareFiles(paths: filePaths, usersId: userIds, read: read, write: write, delete: delete, fromUser: UserManager.shared.currentUser.nickname) { respond in
                SceneDelegate.shared.window?.makeToast("Sharing successful".localizedString)
                editMemberAlert.removeFromSuperview()
                LoadingView.hide()
                self.navigationController?.popViewController(animated: true)
                
            } failureCallback: { code, err in
                LoadingView.hide()
                SceneDelegate.shared.window?.makeToast("Sharing failed".localizedString)
            }
        }
        SceneDelegate.shared.window?.addSubview(editMemberAlert) 
    }

3. File upload and download

3.1 file upload selector


 

The selector of pictures and videos in the file upload selector adopts the third-party library TZImagePickerController. For detailed introduction and use method, please refer to TZImagePickerController. The selector of other files adopts the uidocumentpickerview controller provided by the system

3.2 file upload and download function

  

The upload and download functions of zhiting cloud disk App are realized by calling the library encapsulated by gomobile The library realizes the functions of file fragment upload, fragment download and breakpoint continuation, which can be easily called to the client Based on this library, iOS encapsulates the GoFileManager class, which is convenient for use in projects

GoFileManager class code fragment:

  ///Download task
    /// - Parameters:
    ///- url: task url
    func download(path: String) {
        goOperationQueue.async { [weak self] in
            guard let self = self else { return }
            print(Thread.current)
            ///Family scopeToken
            let scopeToken = AreaManager.shared.currentArea.scope_token
            
            ///Folder password
            let pwd = self.getDirDownloadPwd(by: path)

            let downloader = GonetGetFileDownloader(self.downloadUrlFromPath(path), self.goCachePath, "{\"scope-token\":\"\(scopeToken)\", \"pwd\":\"\(pwd)\"}")
            self.taskCountChangePublisher.send(())
            
            if self.getDownloadingCount() < 2 {
                downloader?.start(self.goDownloadCallbackObj)
            }
            
        } 
    }
    ///Upload file
    /// - Parameters:
    ///- urlPath: upload address
    ///- filename: file name
    ///- tmpPath: file location (pictures and videos are absolute paths, and other files are relative paths under sandbox tmp)
    ///   - scopeToken: scopeToken
    func upload(urlPath: String, filename: String, tmpPath: String) {
        goOperationQueue.async { [weak self] in
            guard let self = self else { return }
            
            var filePath = tmpPath
            if let path = tmpPath.components(separatedBy: "file://").last {
                filePath = path
            }
            
            let scopeToken = AreaManager.shared.currentArea.scope_token
            let pwd = self.getDirUploadPwd(by: urlPath)

            let uploader = GonetGetFileUploader("\(urlPath)\(filename)", self.goCachePath, filePath, filename, "{\"scope-token\":\"\(scopeToken)\", \"pwd\":\"\(pwd)\"}")
            try? uploader?.createTmpFile()
            self.taskCountChangePublisher.send(())
            
            
            if self.getUploadingCount() < 2 {
                uploader?.start(self.goUploadCallbackObj)
            }  
        }
    }

4.4 permission description

  • Read: if the read of model type is 0, it has no read permission, and if it is 1, it has read permission.

    1. Permission to view this folder and all files / folders below it; 2. The entry of the corresponding folder is displayed only if you have permission

  • Write: if the write of model type is 0, there is no writable permission, and if it is 1, there is writable permission.

    1. Including permissions for creating new folders, uploading, renaming, sharing and downloading; 2. Only when you have permission can you display the entry of the corresponding operation;

  • Delete: if the delete of model type is 0, there is no permission to delete, and if it is 1, there is permission to delete.

    1. Including permission to move and delete;

    2. The entry of the corresponding operation is displayed only when you have permission;

    3. Having the permission to move and copy does not mean that you can successfully move and copy. You need to see whether you have the write permission to move into the folder;

Topics: iOS