I upload the image via .Camera to Firebase Storage. When I closed app and run again, this image don't saved at my app. I know that I missed something. Please, tell me what I should to add. Thank's a lot!
This is my code:
import UIKit
import Firebase
import FirebaseStorage
class PicturesOfCoinsViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBAction func saveButton(_ sender: UIButton) {
saveOneEuroCentImage()
}
#IBOutlet weak var oneEuroCentImage: UIImageView!
#IBAction func usePhotoButton(_ sender: UIButton) {
let picker = UIImagePickerController()
picker.sourceType = .camera
self.present(picker, animated: true, completion: nil)
picker.delegate = self
}
func saveOneEuroCentImage() {
let storageRef = FIRStorage.storage().reference().child("userPictures/oneEuroCent.jpg")
if let uploadData = UIImagePNGRepresentation(self.oneEuroCentImage.image!) {
storageRef.put(uploadData, metadata: nil) {(metadata, error) in
if error != nil {
print(error)
return
}
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
oneEuroCentImage.image = info[UIImagePickerControllerOriginalImage] as? UIImage
picker.dismiss(animated: true, completion: nil)
}
}
If you want to have a persistent copy of the image on your app then you must save the photo to your apps document directory before the upload. From your code above you are only uploading it to your cloud storage in firebase but there is no code for saving your picture locally, thats why it does not exist when the app is run again.
I suggest you create a documents directory file path or url for the image and then save it.
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let path = paths.first
let imageFolderPath = path?.appending("MyFBImages")
if !FileManager.default.fileExists(atPath: imageFolderPath!){
do {
try FileManager.default.createDirectory(atPath: imageFolderPath!, withIntermediateDirectories: true, attributes: [:])
} catch let error {
print(error.localizedDescription)
}
}
let imageFilePath = imageFolderPath?.appending("myImageName.jpg")
let imageData = UIImageJPEGRepresentation(UIImage(), 1)
do {
try imageData?.write(to: URL(fileURLWithPath: imageFilePath!))
} catch let error {
print(error.localizedDescription)
}
N/B : the imageData in the code you can get that from the image you created just before the upload to firebase.
This should help you save your image locally. Next time you run your app you can access your previous images by initializing UIImage from contents of the url that holds your saved photos.
I hope this helps you out.
Related
I hope the problem is explained well on the title but what I want to do is to write the message on my message app and want to retrieve it and write it on the app's message cell but nothing is seen. When I go to my firebase console I can see the messages there but not on app. I didn't attach anything about project but I don't know what to attach. but let me add my chatViewController at least .`import UIKit
import Firebase
class ChatViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var messageTextfield: UITextField!
let db = Firestore.firestore()
var messages: [Message] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
navigationItem.hidesBackButton = true
title = K.appName
tableView.register(UINib(nibName: K.cellNibName, bundle: nil), forCellReuseIdentifier: K.cellIdentifier)
loadMessages()
}
func loadMessages() {
db.collection(K.FStore.collectionName)
.order(by: K.FStore.dateField)
.addSnapshotListener { (querySnapshot, error) in
self.messages = []
if let e = error {
print("There was an issue retrieving data from Firestore \(e)")
}else {
if let snapshotDocuments = querySnapshot?.documents {
for doc in snapshotDocuments {
let data = doc.data()
if let messageSender = data[K.FStore.senderField] as? String, let messageBody = data[K.FStore.bodyField] as? String {
let newMessage = Message(sender: messageSender, body: messageBody)
self.messages.append(newMessage)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}
}
}
}
#IBAction func sendPressed(_ sender: UIButton) {
if let messageBody = messageTextfield.text, let messageSender = Auth.auth().currentUser?.email {
db.collection(K.FStore.collectionName).addDocument(data: [K.FStore.senderField: messageSender, K.FStore.bodyField: messageBody]) { (error) in
if let e = error {
print("There was an issue saving data to firestore \(e)")
} else {
print("successfully saved data.")
}
}
}
}
#IBAction func logOutPressed(_ sender: UIBarButtonItem) {
do {
try Auth.auth().signOut()
navigationController?.popToRootViewController(animated: true)
} catch let signOutError as NSError {
print ("Error signing out: %#", signOutError)
}
}
}
extension ChatViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return messages.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: K.cellIdentifier, for: indexPath) as! MessageCell
cell.label.text = messages[indexPath.row].body
return cell
}
}
`
And below is console output
'<FIRFirestore: 0x6000016d7040>
2022-10-17 17:55:19.817200+0300 Flash Chat iOS13[5876:41767] 10.0.0 - [FirebaseAnalytics][I-ACS023007] Analytics v.10.0.0 started
2022-10-17 17:55:19.817551+0300 Flash Chat iOS13[5876:41767] 10.0.0 - [FirebaseAnalytics][I-ACS023008] To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled (see xxx
2022-10-17 17:55:19.824914+0300 Flash Chat iOS13[5876:41677] [Assert] UINavigationBar decoded as unlocked for UINavigationController, or navigationBar delegate set up incorrectly. Inconsistent configuration may cause problems. navigationController=<UINavigationController: 0x13984a200>, navigationBar=<UINavigationBar: 0x13950f870; frame = (0 48; 0 50); opaque = NO; autoresize = W; layer = <CALayer: 0x600000390980>> delegate=0x13984a200
2022-10-17 17:55:19.873401+0300 Flash Chat iOS13[5876:41763] 10.0.0 - [FirebaseAnalytics][I-ACS800023] No pending snapshot to activate. SDK name: app_measurement
2022-10-17 17:55:19.890442+0300 Flash Chat iOS13[5876:41765] 10.0.0 - [FirebaseAnalytics][I-ACS023012] Analytics collection enabled
2022-10-17 17:55:19.890731+0300 Flash Chat iOS13[5876:41765] 10.0.0 - [FirebaseAnalytics][I-ACS023220] Analytics screen reporting is enabled. Call Analytics.logEvent(AnalyticsEventScreenView, parameters: [...]) to log a screen view event. To disable automatic screen reporting, set the flag FirebaseAutomaticScreenReportingEnabled to NO (boolean) in the Info.plist
successfully saved data.'
I currently have a function that allows me to upload an image to Firebase Storage. But how in the world can I achieve the same, with a video instead of an image?
I suspect I have to change UIImage and .jpg to something else. But what is the type of a video?
#State var pickedImages: [UIImage] = []
#State var retrievedImages = [UIImage]()
This is my function:
func uploadImage() {
// Create storage reference
let storageRef = Storage.storage().reference()
// Turn our image into data
let selectedImage = pickedImages[0]
let imageData = selectedImage.jpegData(compressionQuality: 0.8)
guard imageData != nil else {
let er = "THIS: Error while converting to data"
return print(er)
}
// Specifie filepath and name
let path = "images/\(UUID().uuidString).jpg"
let fileRef = storageRef.child(path)
// Upload that data
let uploadTask = fileRef.putData(imageData!, metadata: nil) {metaData, error in
print("THIS: from uploadTAsk")
// Check for errors
if error == nil && metaData != nil {
// Save reference in firestore DB
let db = Firestore.firestore()
db.collection("images").document("user1").setData(["url": path]) { error in
print("THIS: inside closure")
// If there was no errors, display the image
if error == nil {
DispatchQueue.main.async {
self.retrievedImages.append(selectedImage)
}
}
}
}
}
}
I am trying out a firebase storage function and I am unable to show the downloaded image in imageview. Download is successful but nothing shows. If I use a Image from assets it does show. Why is this not working?
DownloadViewController:
import UIKit
import FirebaseStorage
import Firebase
#objc(DownloadViewController)
class DownloadViewController: UIViewController {
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var statusTextView: UITextView!
var storageRef: FIRStorageReference!
override func viewDidLoad() {
super.viewDidLoad()
storageRef = FIRStorage.storage().reference()
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentsDirectory = paths[0]
let filePath = "file:\(documentsDirectory)/myimage.jpg"
let storagePath = UserDefaults.standard.object(forKey: "storagePath") as! String
// [START downloadimage]
storageRef.child(storagePath).write(toFile: URL.init(string: filePath)!,
completion: { (url, error) in
if let error = error {
print("Error downloading:\(error)")
self.statusTextView.text = "Download Failed"
return
}
self.statusTextView.text = "Download Succeeded!"
print("filepath: "+filePath)
let image = UIImage.init(contentsOfFile: filePath)
self.imageView.image = image
self.imageView.layoutIfNeeded()
self.imageView.clipsToBounds = true
})
// [END downloadimage]
}
}
Try adding .resume at the end of your function block like so:
}).resume
I assume the issue here is that your file doesn't exist:
let filePath = "file:\(documentsDirectory)/myimage.jpg"
Likely doesn't resolve to the correct user documents directory, and you should use something like (pardon the Obj-C, already answered this question with it):
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory()];
NSURL *fileURL = [[tmpDirURL URLByAppendingPathComponent:#"hello"] URLByAppendingPathExtension:#"txt"];
This will also prevent issues of "works on the simulator but doesn't work on a device" and vice-versa.
Is there any framework can be used to load an image from URL in watchos 2 ? I tried SDWebImage but it doesn't support watchos2?
Its no framwork, but I've written this extension:
extension WKInterfaceImage {
public func imageFromUrl(_ urlString: String) {
if let url = NSURL(string: urlString) {
let request = NSURLRequest(url: url as URL)
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let task = session.dataTask(with: request as URLRequest, completionHandler: {(data, response, error) in
if let imageData = data as Data? {
DispatchQueue.main.async {
self.setImageData(imageData)
}
}
});
task.resume()
}
}
}
Just add a WKInterfaceImage to your watchOS storyboard, attach it and then call
imageView.imageFromUrl("https://something")
Let me know if it works!
Whenever I download an image from Firebase Storage it download's perfectly, but once I try to change the imageview "my" to it, the imageview disappears. I don't have constraints and I navigated to the local URL and found the image perfectly there. Any help? Am I doing something wrong?
func loadImages(){
let documentDirectoryURL = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true)
let newRef = storageRef!.child("Images/0.jpg")
let fileDestinationUrl = documentDirectoryURL.URLByAppendingPathComponent("p.jpg")
let downloadTask = newRef.writeToFile(fileDestinationUrl){ (URL, error) -> Void in
if (error != nil) {
print("problem")
} else {
print("done")
}
}
downloadTask.observeStatus(.Success) { (snapshot) -> Void in
print(fileDestinationUrl)
var temp = String(fileDestinationUrl)
print(temp)
var my = UIImage(contentsOfFile: temp)
self.image.image = my
}
}
Print the destinationUrl in your console .Go to your downloaded file location , open your terminal , drag and drop the DOWNLOADED image in the terminal and the terminal will give you its actual path.Now compare both the path the one that terminal gave you and the one that console gave you, match those. most like they are to be different ,change them accordingly.
Example code :-
Uploading Code : -
func profilePictureUploading(infoOnThePicture : [String : AnyObject],completionBlock : (()->Void)) {
if let referenceUrl = infoOnThePicture[UIImagePickerControllerReferenceURL] {
print(referenceUrl)
let assets = PHAsset.fetchAssetsWithALAssetURLs([referenceUrl as! NSURL], options: nil)
print(assets)
let asset = assets.firstObject
print(asset)
asset?.requestContentEditingInputWithOptions(nil, completionHandler: { (ContentEditingInput, infoOfThePicture) in
let imageFile = ContentEditingInput?.fullSizeImageURL
print("imagefile : \(imageFile)")
let filePath = FIRAuth.auth()!.currentUser!.uid + "/\(Int(NSDate.timeIntervalSinceReferenceDate() * 1000))/\(imageFile!.lastPathComponent!)"
print("filePath : \(filePath)")
FIRControllerClass.storageRef.child("ProfilePictures").child(filePath).putFile(imageFile!, metadata: nil, completion: { (metadata, error) in
if error != nil{
print("error in uploading image : \(error)")
}
else{
print("metadata in : \(metadata!)")
print(metadata?.downloadURL())
print("The pic has been uploaded")
print("download url : \(metadata?.downloadURL())")
self.uploadSuccess(metadata!, storagePath: filePath)
completionBlock()
}
})
})
}else{
print("No reference URL found!")
}
}
Downloading code : -
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
print("paths in user home page : \(paths)")
let documentDirectory = paths[0]
print("documents directory in homePage : \(documentDirectory)")
let filePath = "file:\(documentDirectory)/\(user!.uid).jpg"
var filePath2 : String = filePath
print(filePath)
let storagePath = NSUserDefaults.standardUserDefaults().objectForKey("storagePath") as! String
print("storagePath is : \(storagePath)")
storageRef.child("ProfilePictures").child(storagePath).writeToFile(NSURL.init(string: filePath)! , completion :
{ (url, err) -> Void in
if let error = err{
print("error while downloading your image :\(error)")
}else{
print("Download successful !")
print("the file filePath of the downloaded file : \(filePath)")
filePath2 = "\(documentDirectory)/\(self.user!.uid).jpg"
if let downloadedImage = UIImage(contentsOfFile: filePath2){
self.profilePictureImageView.image = downloadedImage
print("displayed")
}else{
print("unable to display")
}
}
})
where storagePath is something that you stored in your NSUserDefaults for later reference , such as this, while uploading your image to your firebase storage
The codeBlocks that i gave you are just one of many solutions, there are plenty of ways to do this, go to https://firebase.google.com/docs/storage/ios/download-files