Firebase来帮忙资料上传 Day 12

将资料上传至Firebase上

使用UIImagePikerController来选取照片上传

  • 使用UINavigationControllerDelegate
    • 导向拍照或是相簿的画面
  • 使用UIImagePickerControllerDelegate
    • 照片拍下来之後的动作

做一个UIAlertController来挑选要使用的方式

// 产生一个UIImagePickerController的控制器
let imagePicker = UIImagePickerController()

// 先点ImageView属性栏位的User Interaction Enabled
// 新增一个Tap Gesture Recognizer套用到ImageView上
// 将ViewController连结Tap Gesture Recognizer的动作上,将连结方式选择为@IBAction

@IBAction func addimage(_ sender: UIGestureRecognizer){

	let controller = UIAlertController(title: "选取上传方式", message: nil, preferredStyle: .alert)
	let controllerAction_camera = UIAlertAction(title: "相机", style: .default){(_ ) in
            self.cameraTake()
      }
	let controllerAction_gallery = UIAlertAction(title: "相簿", style: .default, handler: {(_ ) in
            self.galleryUse()})
	let controllerAction_cancel = UIAlertAction(title: "取消", style: .cancel, handler: nil)
        
	controller.addAction(controllerAction_camera)
	controller.addAction(controllerAction_gallery)
	controller.addAction(controllerAction_cancel)
        
	self.present(controller, animated: true, completion: nil)

}

// 使用Function让程序码更加容易读
func cameraTake(){
				// 选择ImagePickerController的类型
        imagePicker.sourceType = .camera
        self.present(imagePicker, animated: true, completion: nil)
				}
    
func galleryUse(){
        imagePicker.sourceType = .photoLibrary
        self.present(imagePicker, animated: true, completion: nil)
				}

override func viewDidLoad() {
			super.viewDidLoad()
			// 将imagePicker控制器的指派透过现在这个ViewController来执行
			imagePicker.delegate = self
			}

// UIImagePickerControllerDelegate让资料知道会用哪种方式来储存
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        // 这边选择使用原相机储存,且将图片显示在ImageView
				if let image = info[.originalImage] as? UIImage {
                    self.addimage.image = image
        }
                
                picker.dismiss(animated: true)
		 }

开启隐私权设定

打开Info.plist

按下+

输入Privacy - Camera Usage Description

输入Privacy - Photo Library Usage Description

为什麽输入这个?

因为iOS的隐私设定,如果没有这两项说明没有办法启动我的相机与相簿

将刚刚输入的资料上传到Firebase

安装Firebase/Database

pod 'Firebase/Database'

pod install

新增文字资料到网路上

import FirebaseDatabase

// 新增一个add的按钮,并连结到这个ViewController
@IBAction func addbutton(_ sender: Any) {
        
				// 在Firebase上传资料需要有一个refence(),故新增一个
        let ref = Database.database().reference()
        
        // child(" ")表示生成一个分支叫" "
				// childByAutoId()表示会自动生成一个ID编码
				// setValue()是上传的主要function
        ref.child("BookName").childByAutoId().setValue(AddBookName.text)
        ref.child("BookAuthor").childByAutoId().setValue(AddBookAuthor.text)
        ref.child("BookISBN").childByAutoId().setValue(AddBookISBN.text)
        ref.child("BookImage").childByAutoId().setValue(addimage.image)
        
    }

成果展示:

https://i.imgur.com/Bez0eds.png

https://i.imgur.com/0zZjCKl.png

补充:

後来发现如果使用AutoId我根本很难去提取资料,所以我要将我的书名命名

下面补上,後来做的修改

我希望我的资料是透过一个名为Book的Structure上传到网路上

那麽我应该做出这样的修改:

先新增一个Swift文件,名为Book

import Foundation
import Firebase

class Book{
	var booktitle:String
	var bookauthors:String
	var bookISBN:String
	var bookimage:[String]?
	var key:String
	var ref:DataBaseReference?

	// 自己从程序内部输入进资料
	// 将外部(textfield)的这些输入到Book这个Struture内变数
	init(booktitle:String,bookauthors:String,bookISBN:String,bookimage:[String],key:String = ""){
			self.key = key
			self.booktitle = booktitle
			self.bookauthors = bookauthors
			self.bookISBN = bookISBN
			self.bookimage = bookimage
			self.ref = nil
	}

	// 当从网路上抓下来的档案,输入进资料
	init(snapshot:DataSnapshot){
			key = snapshot.key
			let snapshotValue = snapshot.value as![String:AnyObject]
			booktitle = snapshotValue["booktitle"] as! String
			bookauthors = snapshotValue["bookauthors"] as! String
			bookISBN = snapshotValue["bookISBN"] as! String
			bookimage = snapshotValue["bookimage"] as? [String]
			ref = snapshot.ref
	}
	

// 因为上传资料,需要将其变成字典的形式
// 所以将Book变成字典的形式
	func becomeDictionary() -> Any{
			return ["booktitle":booktitle,
							"bookauthors":bookauthors,
							"bookISBN":bookISBN,
							"bookimage":bookimage
							]
	}

原本的addButton也会开始做很多事情

func addbutton(){

// 将刚刚资料输入进Book struture
let book = Book(booktitle:AddBookName.text!,bookauthors:AddBookAuthors.text,
								bookISBN:AddBookISBN.text,bookimage:[""])
// 将刚刚的资料上传到Firebase
self.uploadtoFirebase(value:book)

}
func uploadtoFirebase(values:Book){
	// 首先先用每个Book的名字创造一个类似资料夹的东西,来存放每本书的资料
	let bookItemRef = self.ref!.child(values.booktitle.lowercased())
	// 因为要上传图片,我们需要一个Storage的ref
	// 一样根据书名,做一个类似资料夹的东西
	let storageImageRef = Storage.storage().reference().child("BookRentImage").child((values.booktitle))

	// 当我们要上传的时候,有鉴於上传图片跟上传一些文字资料的速度并不一样,所以在这边先做一个辨认
	// 如果有的话,则新增一个在书名的资料夹内
	if addimage.image != nil{
		let uploadTask = StorageImageRef.child("\(values.booktitle).jpeg").putData(self.ImageData!,metadata:nil,completion:{(data,error) in 
				if error != nil{
					print("Error",error.localizedDescription)
					return
				}
		})

DispatchQueue.global(qos:.userInitiated).async{
		uploadTask.observe(.success,handler:{(snapshot) in
			storageImageRef.child("\(values.booktitle).jpeg").downloadURL{(url,error) in
				if let error = error{
						print("Error",error.localizedDescription)
				}else{
				
					if let imageFileURL = url.absoluteString{
									// 检查是不是所上传的URL
									print("This is my imageURL",imageURL)
					// 如果没有问题,那麽将上传图片所产生的URL也一并上传
					let bookItem = Book(booktitle:values.booktitle,bookauthors:values.bookauthors,bookISBN:values.bookISBN,bookimage:imageURL)
					bookItemRef.setValue(bookItem.becomeDictionary(),withCompletionBlock:{(error,ref) in 
							if error == nil{
								print("Success")
							}
					// 如果要加上UIAlertController加在这边
					}
				}
		}
}

大功告成!

https://i.imgur.com/Q0cjP44.gif

https://i.imgur.com/z5MYbSQ.png

参考网址:

Swift & Firebase DB(Realtime&Cloud Firestore) 全解析

[APP开发-使用Swift] 21-2. Firebase - 新增

Firebase教学:如何实作上传图片功能与远端存取


<<:  结识班代:四则运算子函式多载 Arithmetic Operators Function Overloading

>>:  15. HTTP request methods ( 上 )--- GET vs. POST

Day 04 HTML<表单标签>

表单标签主要功用是用来收集使用者资料 常用情况 : 注册页面... 主要由 表单域、表单元素、提示文...

[Shell] Common Shells: sh, csh, tcsh, ash, bash

sh Bourne Shell, developed by Steve Bourne @ AT&a...

[早餐吃到饱 - 1] 薆悦酒店 - 五权馆(台中) #您有多久没有好好的吃顿早餐了呢~

今天用卤肉跟大家说声早安!! 薆悦酒店的早餐是有对外(非住客)开放的,但是要先预约。 今年的4月10...

[Day3]PHP的资料型态03

PHP的资料型态 Object 对象 要创建一个新的对象 object,使用 new 语句实例化一个...

Day 01-AWS Solution Architect Associate的铁人之旅行前会

最近好友阿泰邀约参加2021的铁人赛,碰巧我正在准备AWS Certified Solution A...