最近公司需要把圖片上傳從華為云改成亞馬遜云,記錄一下操作流程,最早亞馬遜云是使用AWS的庫來進(jìn)行上傳,但是最近亞馬遜使用了Amplify方式(Swift語言)上傳。特此記錄一下基本的操作方式
首先,必須安裝 Amplify CLI,先確認(rèn)本機(jī)是否已經(jīng)安裝 nodejs,npm 然后打開終端 輸入以下連接完成 Amplify CLI安裝,
curl -sL https://aws-amplify.github.io/amplify-cli/install | bash && $SHELL
接下來打開終端,路徑設(shè)置到工程目錄下,運(yùn)行 Amplify init 命令進(jìn)行初始化

111.png

222.png

3333.png
創(chuàng)建完成后,會在控制上 IAM-角色-生成兩個角色(點(diǎn)擊這2個角色分別給他們添加S3Full的權(quán)限),還有在S3的桶上自動生成一個桶(如果要用運(yùn)維給的桶,可以刪除自動生成的桶)。

666.png
工程會新增2個json文件

555.png
目前還不能使用,接著要開始引入桶,再次打開終端,輸入amplify import storage,選擇S3 Bucket
然后 Add auth,添加一個用戶池,選擇第一個默認(rèn) Default configuration.完成用戶池的創(chuàng)建
接著會出現(xiàn)bucket,選擇運(yùn)維給你的那個就完成創(chuàng)建

777.png
完成創(chuàng)建后會提示已經(jīng)創(chuàng)建完成,接著再次打開終端 輸入 amplify push 把配置上傳到服務(wù)器

999.png
上傳完成后,在后臺點(diǎn)擊左上角選擇Cognito進(jìn)入用戶池及身份驗(yàn)證,就會看到自己創(chuàng)建的用戶池及聯(lián)合身份

888.png

100.png
然后兩個json文件也會出現(xiàn)變化。
接著點(diǎn)擊身份池上身份,然后點(diǎn)擊右上角編輯身份池,把啟用未經(jīng)驗(yàn)證的身份的訪問權(quán)限勾上

2323424.png
然后記住自己未經(jīng)身份驗(yàn)證的角色的名稱,接著去控制臺的主頁選擇IAM-角色-點(diǎn)擊剛才記住的那個名稱,給它添加權(quán)限(如果需要用戶登錄的就給另一個也添加權(quán)限)。一般給個S3Full的權(quán)限就行


至此,亞馬遜的操作就差不多了。
接下來是工程方面的操作。
如果是純OC的,可以參考https://github.com/awslabs/aws-sdk-ios-samples
以下是Swift語言的版本,(同時兼容OC環(huán)境)
在pod上導(dǎo)入相關(guān)的庫
pod 'Amplify'
pod 'Amplify/Tools'
pod 'AmplifyPlugins/AWSS3StoragePlugin'
pod 'AmplifyPlugins/AWSCognitoAuthPlugin'
然后打開工程會看到相應(yīng)的配置文件

5555.png
接著開始寫初始化流程,也可以參照他們官方的文檔 https://docs.amplify.aws/lib/q/platform/ios/
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
//初始化流程
let credentialsProvider = AWSCognitoCredentialsProvider(regionType:.APSoutheast1,
identityPoolId:"ap-southeast-1:a5f09d6d-e4a5-4997-8f3e-1d388de90abc")
let configuration = AWSServiceConfiguration(region:.APSoutheast1, credentialsProvider:credentialsProvider)
try Amplify.add(plugin: AWSCognitoAuthPlugin())
try Amplify.add(plugin: AWSS3StoragePlugin())
try Amplify.configure()
return true
}
然后是注冊與登錄,如果不需要登錄的話,就不需要這2步操作
//注冊流程
func signUp(username: String, password: String, email: String) {
let userAttributes = [AuthUserAttribute(.email, value: email)]
let options = AuthSignUpRequest.Options(userAttributes: userAttributes)
Amplify.Auth.signUp(username: username, password: password, options: options) { result in
switch result {
case .success(let signUpResult):
if case let .confirmUser(deliveryDetails, _) = signUpResult.nextStep {
print("Delivery details \(String(describing: deliveryDetails))")
} else {
print("SignUp Complete")
}
case .failure(let error):
print("An error occurred while registering a user \(error)")
}
}
}
//登錄流程
func signIn(username: String, password: String, email: String) {
// Amplify.Auth.signOut()
Amplify.Auth.signIn(username: username, password: password) { result in
switch result {
case .success:
print("Sign in succeeded")
case .failure(let error):
print("Sign in failed \(error)")
}
}
}
然后是上傳下載的流程
//下載流程
func download(name:String){
let downloadToFileName = FileManager.default.urls(for: .documentDirectory,
in: .userDomainMask)[0]
.appendingPathComponent(name)
Amplify.Storage.downloadFile(
key: name,
local: downloadToFileName,
progressListener: { progress in
print("Progress: \(progress)")
}, resultListener: { event in
switch event {
case .success:
print("Completed")
case .failure(let storageError):
print("Failed: \(storageError.errorDescription). \(storageError.recoverySuggestion)")
}
})
}
//上傳流程,我這邊是改成數(shù)組上傳
func uploadData(images:NSArray,index:Int){
let timeInterval:NSInteger = NSInteger(NSDate.init().timeIntervalSince1970)
let theFinal = timeInterval
let stringName = String(format: "path%d.jpg", theFinal)
let imgGet:UIImage = images.object(at: index) as! UIImage
let data = imgGet.jpegData(compressionQuality: 0.5)
//
let options = StorageUploadDataRequest.Options(accessLevel: .guest)
Amplify.Storage.uploadData(key: stringName, data: data!, options: options) { progress in
print("Progress: \(progress)")
} resultListener: { event in
switch event {
case .success(let data):
if index != images.count-1 {
uploadData(images: images, index: index+1)
}else{
print("Completed: \(data)")
}
case .failure(let storageError):
print("Failed: \(storageError.errorDescription). \(storageError.recoverySuggestion)")
}
}
}
我這里寫了一個OC調(diào)用Swift的版本,僅供參考,上傳的狀態(tài)可以使用kvo對isUploadImageDone進(jìn)行監(jiān)聽
import Amplify
import AmplifyPlugins
import AWSCognitoIdentityProvider
//使用單例進(jìn)行初始化
@objc class UploadImageAmazon: NSObject {
@objc dynamic var isUploadImageDone:Bool = false
@objc var aryImages:NSMutableArray = NSMutableArray()
@objc static let staticInstance = UploadImageAmazon()
@objc static func sharedInstance() -> UploadImageAmazon{
return staticInstance
}
private override init(){
do {
let credentialsProvider = AWSCognitoCredentialsProvider(regionType:.APSoutheast1,
identityPoolId:"ap-southeast-1:84207a2d-de78-45e2-bb6c-fd1c214c6f17")
let configuration = AWSServiceConfiguration(region:.APSoutheast1, credentialsProvider:credentialsProvider)
AWSServiceManager.default().defaultServiceConfiguration = configuration
try Amplify.add(plugin: AWSCognitoAuthPlugin())
try Amplify.add(plugin: AWSS3StoragePlugin())
try Amplify.configure()
print("Amplify configured with storage plugin")
} catch {
print("Failed to initialize Amplify with \(error)")
}
}
func signUp(username: String, password: String, email: String) {
let userAttributes = [AuthUserAttribute(.email, value: email)]
let options = AuthSignUpRequest.Options(userAttributes: userAttributes)
Amplify.Auth.signUp(username: username, password: password, options: options) { result in
switch result {
case .success(let signUpResult):
if case let .confirmUser(deliveryDetails, _) = signUpResult.nextStep {
print("Delivery details \(String(describing: deliveryDetails))")
} else {
print("SignUp Complete")
}
case .failure(let error):
print("An error occurred while registering a user \(error)")
}
}
}
func signIn(username: String, password: String, email: String) {
// Amplify.Auth.signOut()
Amplify.Auth.signIn(username: username, password: password) { result in
switch result {
case .success:
print("Sign in succeeded")
case .failure(let error):
print("Sign in failed \(error)")
}
}
}
@objc func uploadData(images:NSArray,index:Int,userid:NSInteger){
let timeInterval:NSInteger = NSInteger(NSDate.init().timeIntervalSince1970)
let theFinal = timeInterval + userid
let stringName = String(format: "feedback/%d.jpg", theFinal)
let imgGet:UIImage = images.object(at: index) as! UIImage
let data = imgGet.jpegData(compressionQuality: 0.5)
Amplify.Storage.uploadData(key:stringName, data: data!,
progressListener: { progress in
print("Progress: \(progress)")
}, resultListener: { (event) in
switch event {
case .success(let data):
if index != images.count-1 {
self.isUploadImageDone = false
let next = index + 1
self.aryImages.add("public/".appending(stringName))
self.uploadData(images: images, index: next,userid: userid)
}else{
self.aryImages.add("public/".appending(stringName))
self.isUploadImageDone = true
}
print("Completed: \(data)")
case .failure(let storageError):
print("Failed: \(storageError.errorDescription). \(storageError.recoverySuggestion)")
}
})
}
@objc func download(imagePath:String){
let downloadToFileName = FileManager.default.urls(for: .documentDirectory,
in: .userDomainMask)[0]
.appendingPathComponent(imagePath)
Amplify.Storage.downloadFile(
key: imagePath,
local: downloadToFileName,
progressListener: { progress in
print("Progress: \(progress)")
}, resultListener: { event in
switch event {
case .success:
print("Completed")
case .failure(let storageError):
print("Failed: \(storageError.errorDescription). \(storageError.recoverySuggestion)")
}
})
}
}
以上就是亞馬遜云上傳圖片的基本流程,但是目前有個奇怪的問題,不管是登錄還是未登錄用戶,上傳的圖片都只能放到public文件夾上,這個問題期待后續(xù)能解決,還有如果要刪除亞馬遜云的配置,不能簡單的刪除,必須要使用命令,打開終端,輸入amplify delete 來進(jìn)行刪除才能刪除徹底,不然會在IAM-角色里多了很多沒用的角色