database - 如何在 Firebase 中存储图像
问题描述
我正在尝试将测试图像存储在 Firebase 存储中,但它没有出现,我认为问题出在 viewDidLoad 中的完成处理程序上,但我不确定如何修复它。它应该是“photoHelper”还是其他?下面我包含了处理 imagePicker 的“MyProfileViewController”和两个服务功能“创建图像”和“上传图像”。
import UIKit
import AVFoundation
import Photos
class MyProfileViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
@IBOutlet weak var profileButton: UIButton!
let photoHelper = MGPhotoHelper()
var imagePicker: UIImagePickerController!
override func viewDidLoad() {
super.viewDidLoad()
profileButton.layer.cornerRadius = 0.5 * profileButton.bounds.size.width
profileButton.clipsToBounds = true
photoHelper.completionHandler = { image in
ProfileService.createImage(for: image)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
@IBAction func addPhoto(_ sender: UIButton) {
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
imagePicker = UIImagePickerController()
imagePicker.delegate = self
if (UIImagePickerController.isSourceTypeAvailable(.camera))
{
let cameraAction = UIAlertAction(title: "Use Camera", style: .default) { (action) in
let status = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
if (status == .authorized){
self.DisplayPicker(type: .camera)
}
if (status == .restricted){
self.HandleRestricted()
}
if (status == .denied){
self.HandleDenied()
}
if (status == .notDetermined){
AVCaptureDevice.requestAccess(for: AVMediaType.video, completionHandler: { (granted) in
if (granted){
self.DisplayPicker(type: .camera)
}
})
}
}
alertController.addAction(cameraAction)
}
if (UIImagePickerController.isSourceTypeAvailable(.photoLibrary)) {
let photoLibraryAction = UIAlertAction(title: "Use Photo Library", style: .default) { (action) in
let status = PHPhotoLibrary.authorizationStatus()
if (status == .authorized){
self.DisplayPicker(type: .photoLibrary)
}
if (status == .restricted){
self.HandleRestricted()
}
if (status == .denied){
self.HandleDenied()
}
if (status == .notDetermined){
PHPhotoLibrary.requestAuthorization({ (status) in
if (status == PHAuthorizationStatus.authorized){
self.DisplayPicker(type: .photoLibrary)
}
})
}
}
alertController.addAction(photoLibraryAction)
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alertController.addAction(cancelAction)
alertController.popoverPresentationController?.sourceView = self.profileButton
alertController.popoverPresentationController?.sourceRect = self.profileButton.bounds
present(alertController, animated: true, completion: nil)
}
func HandleDenied(){
let alertController = UIAlertController(title: "Media Access Denied", message: "CameraTutorial does not access to your device's media. Please update your settings", preferredStyle: .alert)
let settingsAction = UIAlertAction(title: "Go to Settings", style: .default){ (action) in
DispatchQueue.main.async {
UIApplication.shared.open(NSURL(string: UIApplication.openSettingsURLString)! as URL)
}
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alertController.popoverPresentationController?.sourceView = self.profileButton
alertController.popoverPresentationController?.sourceRect = self.profileButton.bounds
alertController.addAction(settingsAction)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
}
func HandleRestricted(){
let alertController = UIAlertController(title: "Media Access Denied", message: "This device is restricited from accessing any media at this time", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
alertController.popoverPresentationController?.sourceView = self.profileButton
alertController.popoverPresentationController?.sourceRect = self.profileButton.bounds
alertController.addAction(defaultAction)
present(alertController, animated: true, completion: nil)
}
func DisplayPicker(type: UIImagePickerController.SourceType){
self.imagePicker.mediaTypes = UIImagePickerController.availableMediaTypes(for: type)!
self.imagePicker.sourceType = type
self.imagePicker.allowsEditing = true
DispatchQueue.main.async {
self.present(self.imagePicker, animated: true, completion: nil)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
let chosenImage = info[UIImagePickerController.InfoKey.editedImage] as! UIImage
profileButton.imageView?.contentMode = .scaleAspectFill
profileButton.setImage(chosenImage, for: .normal)
dismiss(animated: true, completion: nil)
}
}
创建图像功能
static func createImage(for image: UIImage) {
let imageRef = Storage.storage().reference().child("test_image.jpg")
StorageService.uploadImage(image, at: imageRef) { (downloadURL) in
guard let downloadURL = downloadURL else {
return
}
let urlString = downloadURL.absoluteString
print("image url: \(urlString)")
}
}
上传图片功能
static func uploadImage(_ image: UIImage, at reference: StorageReference, completion: @escaping (URL?) -> Void) {
// 1
guard let imageData = image.jpegData(compressionQuality: 0.1) else {
return completion(nil)
}
// 2
reference.putData(imageData, metadata: nil, completion: { (metadata, error) in
// 3
if let error = error {
assertionFailure(error.localizedDescription)
return completion(nil)
}
// 4
reference.downloadURL(completion: { (url, error) in
if let error = error {
assertionFailure(error.localizedDescription)
return completion(nil)
}
completion(url)
})
})
}
解决方案
首先启用规则,如果你没有。
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if true;
}
}
}
用于上传和图像到 Firebase 存储的代码。
private void uploadImage() {
if(filePath != null)
{
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setTitle("Uploading...");
progressDialog.show();
StorageReference ref = storageReference.child("images/"+ UUID.randomUUID().toString());
ref.putFile(filePath)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
progressDialog.dismiss();
Toast.makeText(MainActivity.this, "Uploaded", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
progressDialog.dismiss();
Toast.makeText(MainActivity.this, "Failed "+e.getMessage(), Toast.LENGTH_SHORT).show();
}
})
.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
@Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double progress = (100.0*taskSnapshot.getBytesTransferred()/taskSnapshot
.getTotalByteCount());
progressDialog.setMessage("Uploaded "+(int)progress+"%");
}
});
}
这里 Filepath 是图像的 Uri。希望它有所帮助。
推荐阅读
- databricks - 如何重命名增量表中的列
- reactjs - 在严格模式下反应组件的双重渲染 - 我是否正确使用状态?
- node.js - Discord API:如何获取邀请码?
- xamarin - 货币 Xamarin iOS 中的小数位错误
- sql - SQL oracle:如何获取今天和去年之间的日期
- android - 在本机反应中为图像设置动画
- php - 会话中的 $_SERVER['REQUEST_URI'] 保存最新的丢失文件而不是页面 URI
- arduino - 使用北斗全球短消息通信服务(BDS SMS)
- python - 问题运行 streamlit hello
- linkedin - LinkedIn 共享 api 以检索喜欢和评论