今天收到个需求,让把本地的图片文件都集成到云存储,来做缩包处理。综合考虑过七牛、腾讯云。但还是选择阿里云的 OSS。
第一步,开通阿里云存储模块功能:
https://oss.console.aliyun.com/overview
第二步,新增授权用户的RAM访问控制:
https://ram.console.aliyun.com/users
需要注意是,这里新增的用户,看个人需求。是否允许访问控制台。我这里是仅能调用api。所以打钩第二个即可。如下图:
第三步:配置用户访问OSS的权限,点击新增授权。下面则OSS完全权限或者 只读权限。因为我涉及到上传管理和删除,所以给了完全权限。如下图:
第四步:生成 AccessKey 和 secretKeyId。这里需要注意的是:仅能查看一次,记得保存好。否则每次都得重新生成。 如下图:
第五步:到这里,基础配置已经完成。剩下的就是教科书式的配置,跟着文档做吧:
import Foundation
class OSSManager {
/**
* bucket所在的region的endpoint,详情可见https://help.aliyun.com/document_detail/31837.html
* 这里默认我使用的是 杭州1
*/
private let OSS_ENDPOINT: String = "oss-cn-hangzhou.aliyuncs.com"
/**
账户秘钥参考设置流程--设置后谨记:还需配置权限
https://help.aliyun.com/zh/ram/user-guide/create-an-accesskey-pair?spm=a2c4g.11186623.0.i1#task-2245479
*/
private let accessKeyId: String = "xxxxxxxxxxxx"
private let secretKeyId: String = "xxxxxxxxxxxx"
private var client:OSSClient?
static let shared: OSSManager = OSSManager()
init() {
let credential = OSSStsTokenCredentialProvider(accessKeyId: self.accessKeyId, secretKeyId: self.secretKeyId, securityToken: "")
self.client = OSSClient(endpoint: OSS_ENDPOINT, credentialProvider: credential)
}
/// 创建区块--存储空间
func createBucket(_ bucketName: String) -> Bool {
let request = OSSCreateBucketRequest()
request.bucketName = bucketName//"evan-hangzhou"
// request.xOssACL // 访问权限无设置-默认: private
/// 存储区域: 参考网址:https://help.aliyun.com/zh/oss/user-guide/regions-and-endpoints?spm=a2c4g.11174283.0.0.44d6de536p7wcW
// request.location = "oss-cn-hangzhou"
let task = client?.createBucket(request)
task?.waitUntilFinished()
if (task?.error == nil) {
// 成功
return true
}else {
// 失败
return false
}
}
/// 删除存储区块
func deleteBucket(_ bucketName: String) -> Bool {
let request = OSSDeleteBucketRequest()
request.bucketName = bucketName
let task = client?.deleteBucket(request)
task?.waitUntilFinished()
if (task?.error == nil) {
// 成功
return true
}else {
// 失败
return false
}
}
/// 获取区块存储文件列表--异步
func getListByBucketAsync(_ bucketName: String, _ listFile: (@escaping (_ dict: [Any])->Void)) {
let getBucket = OSSGetBucketRequest()
getBucket.bucketName = bucketName;
client?.getBucket(getBucket).continue({ task in
guard let error = task.error else {
if let s = task.result as? OSSGetBucketResult,let dict = s.contents {
listFile(dict)
}
return
}
return nil
})
}
/// 获取区块存储文件列表--同步
func getListByBucketSync(_ bucketName: String) -> [Any] {
let getBucket = OSSGetBucketRequest()
getBucket.bucketName = bucketName;
let task = client?.getBucket(getBucket)
task?.waitUntilFinished()
if let s = task?.result as? OSSGetBucketResult,let dict = s.contents {
return dict
}
return []
}
/// 异步上传文件
func uploadObjectAsync(bucketName: String, fileKey: String, filePath: URL, uploadProgress: (@escaping (_ bSent: Int64, _ totalSent: Int64, _ totalToSent: Int64) -> Void), result: (@escaping (_ isSuccess: Bool) -> Void)) {
let request = OSSPutObjectRequest()
request.bucketName = bucketName
/// 文件标识ID-一般是文件名,不可重复
request.objectKey = fileKey
// 含文件路径的URL
request.uploadingFileURL = filePath
request.contentType = "";
request.contentMd5 = "";
request.contentEncoding = "";
request.contentDisposition = "";
request.uploadProgress = { bytesSent, totalByteSent, totalBytesExpectedToSend in
uploadProgress(bytesSent, totalByteSent, totalBytesExpectedToSend)
}
client?.putObject(request).continue({ task in
if (task.error == nil) {
// 成功
result(true)
}else {
// 失败
result(false)
}
return nil
})
}
/// 同步上传文件
func uploadObjectSync(bucketName: String, fileKey: String, filePath: URL, uploadProgress: (@escaping (_ bSent: Int64, _ totalSent: Int64, _ totalToSent: Int64) -> Void)) -> Bool {
let request = OSSPutObjectRequest()
request.bucketName = bucketName
/// 文件标识ID-一般是文件名,不可重复
request.objectKey = fileKey
// 含文件路径的URL
request.uploadingFileURL = filePath
request.contentType = "";
request.contentMd5 = "";
request.contentEncoding = "";
request.contentDisposition = "";
request.uploadProgress = { bytesSent, totalByteSent, totalBytesExpectedToSend in
NSLog("%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
uploadProgress(bytesSent, totalByteSent, totalBytesExpectedToSend)
}
let task = client?.putObject(request)
task?.waitUntilFinished()
if (task?.error == nil) {
// 成功
return true
}else {
// 失败
print(task?.error ?? "")
return false
}
}
/// 异步下载
func downloadObjectAsync(bucketName: String, fileKey: String, downloadData: (@escaping (_ fileData: Data)->Void)) {
let request = OSSGetObjectRequest()
request.bucketName = bucketName
request.objectKey = fileKey
request.downloadProgress = { bytesWritten, totalBytesWritten, totalBytesExpectedToWrite in
NSLog("%lld, %lld, %lld", bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
};
client?.getObject(request).continue({ task in
if let data = task.result?.downloadedData {
// 成功
downloadData(data)
}else {
// 失败
print(task.error ?? "")
}
return nil
})
}
/// 同步下载
func downloadObjectSync(bucketName: String, fileKey: String) -> Data? {
let request = OSSGetObjectRequest()
request.bucketName = bucketName
request.objectKey = fileKey
request.downloadProgress = { bytesWritten, totalBytesWritten, totalBytesExpectedToWrite in
NSLog("%lld, %lld, %lld", bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
};
let task = client?.getObject(request)
task?.waitUntilFinished()
if let result = task?.result as? OSSGetObjectResult {
let data = result.downloadedData
// 成功
return data
}else {
// 失败
print(task?.error ?? "")
}
return nil
}
}
第六步:上面第五步直接复制,本地存文件就好了。下面是使用方法
/// 下载文件
@IBAction func btnDownloadFileClick(_ sender: Any) {
/// 获取列表
let list = OSSManager.shared.getListByBucketSync(customBucketName)
/// 循环下载
for item in list {
guard let i = item as? Dictionary<String, Any>, let key = i["Key"] as? String else { return }
let result = OSSManager.shared.downloadObjectSync(bucketName: customBucketName, fileKey: key)
if let d = result {
saveFile(key, d)
}
}
}
到此结束,如果有碰到任何问题,欢迎私信。