共计 8315 个字符,预计需要花费 21 分钟才能阅读完成。
1. 文件列表
1.1 我的文件——MyFileViewController.swift
- 数据获取——通过 SA 接口获取数据
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()
// 删选没有可读权限的文件
let datas = response.list.filter({$0.read != 0})
if isReload {// 下拉刷新 or 首次加载数据
if datas.count == 0 {
self.tableView.mj_footer?.isHidden = true
self.tableView.reloadData()}else{self.emptyView.removeFromSuperview()
self.currentDatas = datas
self.tableView.reloadData()}
}else{// 上拉加载更多数据
if !response.pager.has_more {// 已无数据
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)")
}
- 此页面无抉择性能
- 点击文件夹进入本人目录
let vc = ChangeFolderPlaceController()
let nav = UINavigationController(rootViewController: vc)
nav.modalPresentationStyle = .fullScreen
self.present(nav, animated: true, completion: nil)
1.2 共享文件——ShareFileViewController.swift
用户能够获取到其余用户共享进去的文件夹.
/// 申请列表数据
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("申请胜利")
LoadingView.hide()
self.tableView.mj_header?.endRefreshing()
self.tableView.mj_footer?.endRefreshing()
// 删选没有可读权限的文件
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 {
// 空数据展现页面
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("申请失败")
LoadingView.hide()
self.tableView.mj_header?.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)")
}
}
- 共享文件与我的文件页面逻辑大致相同,但其余用户共享过去的文件夹容许抉择功能模块
// MARK: - funtionTabbarAction
funtionTabbarView.shareBtn.clickCallBack = { _ in
print("点击分享到")
let shareVC = FileShareController()
shareVC.fileDatas = self.seletedFiles
self.navigationController?.pushViewController(shareVC, animated: true)
self.hideFunctionTabbarView()}
funtionTabbarView.downloadBtn.clickCallBack = { _ in
print("点击下载")
}
funtionTabbarView.copyBtn.clickCallBack = {[weak self] _ in
guard let self = self else {return}
print("点击复制到")
let vc = ChangeFolderPlaceController()
vc.isRootPath = true
vc.currentPaths = ["根目录"]
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("点击重命名")
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("请输出名称".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:" 更改文件类型可能导致文件不可用, 是否持续?", preferredStyle: .alert)
alertViewController.addAction(UIAlertAction(title: "勾销".localizedString, style: .cancel, handler: nil))
alertViewController.addAction(UIAlertAction(title: "确定".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("重命名胜利".localizedString)
} failureCallback: { code, err in
SceneDelegate.shared.window?.makeToast(err)
LoadingView.hide()}
}))
self.present(alertViewController, animated: true, completion: nil)
return
}
}
1.3 文件夹子集目录——FolderViewController.swift
- 子集目录可存在各类型文件的存在模式,依据数据 model 的 type 来辨别。
2. 子集目录点击文件类型是,展现 functionView,性能依据权限凋谢。
3. 子集目录文件及文件夹均可抉择,展现性能 tabbar。
2. 文件夹共享
用户能够将文件夹共享给选中的用户, 并依据本身需要赋予他们读写删的权限.
/// 共享文件夹给用户
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()
// 权限判断
if self.fileDatas.filter({$0.read == 0}).count > 0 {// 没有可读权限
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 {// 没有写入权限
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 {// 没有删权限
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("共享胜利".localizedString)
editMemberAlert.removeFromSuperview()
LoadingView.hide()
self.navigationController?.popViewController(animated: true)
} failureCallback: { code, err in
LoadingView.hide()
SceneDelegate.shared.window?.makeToast("共享失败".localizedString)
}
}
SceneDelegate.shared.window?.addSubview(editMemberAlert)
}
3. 文件上传下载
3.1 文件上传选择器
文件上传选择器中图片和视频的选择器采纳的是第三方库 TZImagePickerController, 具体介绍及应用办法可参考 TZImagePickerController, 其余文件的选择器则采纳零碎自带的 UIDocumentPickerViewController.
3.2 文件上传下载性能
智汀云盘 App 的上传、下载性能是调用 gomobile 封装的库实现的. 该库实现了文件的分片上传、分片下载、断点续传等性能,能够很不便的给客户端调用.iOS 端基于该库封装了 GoFileManager 类,不便我的项目中应用.
GoFileManager 类代码片段:
/// 下载工作
/// - Parameters:
/// - url: 工作 url
func download(path: String) {goOperationQueue.async { [weak self] in
guard let self = self else {return}
print(Thread.current)
/// 家庭 scopeToken
let scopeToken = AreaManager.shared.currentArea.scope_token
/// 文件夹明码
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)
}
}
}
/// 上传文件
/// - Parameters:
/// - urlPath: 上传地址
/// - filename: 文件名
/// - tmpPath: 文件地位 (图片、视频为绝对路径 其余文件为沙盒 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 权限阐明
-
读:model 类型的 read 为 0 则无可读权限,为 1 则有可读权限。
1、查看该文件夹及其上面所有文件 / 文件夹的权限;2、有权限才展现对应文件夹的入口
-
写:model 类型的 write 为 0 则无可写权限,为 1 则有可写权限。
1、包含新建文件夹、上传、重命名、共享、下载的权限;2、有权限才展现对应操作的入口;
-
删:model 类型的 delete 为 0 则无可删权限,为 1 则有可删权限。
1、包含挪动、删除的权限;
2、有权限才展现对应的操作的入口;
3、有挪动、复制的权限,不代表能胜利挪动复制,须要看是否有移入文件夹的【写】权限,有能力操作;