Creating an image format with an unknown type is an error...Swift3 - ios

I'm learning some swift 3 following courses on youtube. The code below I've written is for creating a user account and storing details in a Firebase database. When testing, I can progress up to the point of submitting the registration form. I then receive the following error:
[Generic] Creating an image format with an unknown type is an error.
Fatal Error: unexpectedly found nil whilst unwrapping an Optionional value.
I have also had the below on the line highlighted in the codeblock below:
exc_bad_instruction(code=exc_i386_invop subcode=0x0)
Below is my code. I have highlighted where the exception is thrown. Any assistance would be much appreciated.
import UIKit
import Firebase
class Signup_ViewController: UIViewController,
UIImagePickerControllerDelegate, UINavigationControllerDelegate {
// Input data fields for signup form
#IBOutlet weak var usernameField: UITextField!
#IBOutlet weak var emailField: UITextField!
#IBOutlet weak var nameField: UITextField!
// Password data field for signup form
#IBOutlet weak var passwordField: UITextField!
#IBOutlet weak var confirmPasswordField: UITextField!
// Next button for signup form (Hidden by default)
#IBOutlet weak var nextBtn: UIButton!
let picker = UIImagePickerController()
var userStorage: FIRStorageReference!
var ref: FIRDatabaseReference!
override func viewDidLoad() {
super.viewDidLoad()
picker.delegate = self
let storage = FIRStorage.storage().reference(forURL: "XXXXXXXXXXXXXXXXXXXX") // Defines URL for Firebase storage container
ref = FIRDatabase.database().reference()
userStorage = storage.child("users") // Folder on Firebase storage
}
// Image for signup form - user profile image
#IBOutlet weak var imgView: UIImageView!
// Action for when user presses the "Select profile picture" button
#IBAction func selectProfileImagePress(_ sender: Any) {
picker.allowsEditing = true // Enables user to edit photo
picker.sourceType = .photoLibrary // Enables user to pick photo from photo library
present(picker, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerEditedImage] as? UIImage {
self.imgView.image = image // Checks image selected exists
nextBtn.isHidden = false // Unhides "Next" button once image has been picked
}
self.dismiss(animated: true, completion: nil)
}
// Action for when the "Next" button is pressed
#IBAction func nextPressed(_ sender: Any) {
guard usernameField.text != "", nameField.text != "", emailField.text != "", passwordField.text != "", confirmPasswordField.text != "" else { return }
if passwordField.text == confirmPasswordField.text { // Checks password and confirm password match <---- Error highlights this line when the app crashes out.
FIRAuth.auth()?.createUser(withEmail: emailField.text!, password: passwordField.text!, completion: { (user, error) in
if let error = error {
print(error.localizedDescription)
}
if let user = user {
let changeRequest = FIRAuth.auth()!.currentUser!.profileChangeRequest()
changeRequest.displayName = self.nameField.text!
changeRequest.commitChanges(completion: nil)
let imageRef = self.userStorage.child("\(user.uid).jpg") // Creates JPG file for user uploading (user.uid is variable for specific user)
let data = UIImageJPEGRepresentation(self.imgView.image!, 0.5) // Prepares user profile picture to be sent to Firebase. Applies 0.5 compression to image.
let uploadTask = imageRef.put(data!, metadata: nil, completion: { (metadata, err) in
if err != nil {
print(err!.localizedDescription)
}
imageRef.downloadURL(completion: { (url, er) in
if er != nil {
print(er!.localizedDescription)
}
if let url = url {
let userInfo: [String : Any] = ["uid" : user.uid,
"username" : self.usernameField.text!,
"name" : self.nameField.text!,
"urltoImage" : url.absoluteString]
self.ref.child("users").child(user.uid).setValue(userInfo)
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "userVC")
self.present(vc, animated: true, completion: nil)
}
})
})
uploadTask.resume()
}
})
} else {
print ("Password does not match")
}
}
}

Instead of your code :
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerEditedImage] as? UIImage {
self.imgView.image = image // Checks image selected exists
nextBtn.isHidden = false // Unhides "Next" button once image has been picked
}
self.dismiss(animated: true, completion: nil)
}
use this one ..
/// what app will do when user choose & complete the selection image :
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
/// chcek if you can return edited image that user choose it if user already edit it(crop it), return it as image
if let editedImage = info[UIImagePickerControllerEditedImage] as? UIImage {
/// if user update it and already got it , just return it to 'self.imgView.image'
self.imgView.image = editedImage
/// else if you could't find the edited image that means user select original image same is it without editing .
} else if let orginalImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
/// if user update it and already got it , just return it to 'self.imgView.image'.
self.imgView.image = orginalImage
}
else { print ("error") }
/// if the request successfully done just dismiss
picker.dismiss(animated: true, completion: nil)
}
And for this error :
Creating an image format with an unknown type is an error…Swift3
It's a bug in xcode , if picker could select and return images properly that means everything is okay , just ignore it .

Related

I get "boringssl" error when uploading image to Firebase for iOS

I'm simply trying to upload an image but I'm getting this error "[boringssl] boringssl_metrics_log_metric_block_invoke(153) Failed to log metrics
Optional("User does not have permission to access 'here was the link to the folder.' ")"
My goal is to upload a photo and access it later from another page, but now I'm getting this error.
edit: Later I realized that I am getting some of the same error while signing up "[boringssl] boringssl_metrics_log_metric_block_invoke(153)".
The entered user can register and appears in the Firebase interface, but the above error is displayed on the console.
import UIKit
import Firebase
class UploadViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var commentText: UITextField!
#IBOutlet weak var uploadVar: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
imageView.isUserInteractionEnabled = true
let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(chooseImage))
imageView.addGestureRecognizer(gestureRecognizer)
}
#IBAction func UploadClicked(_ sender: Any) {
let storage = Storage.storage()
let storageReferance = storage.reference()
let mediaFolder = storageReferance.child("media")
if let data = imageView.image?.jpegData(compressionQuality: 0.5) {
let imageReferance = mediaFolder.child("image.jpg")
imageReferance.putData(data, metadata: nil) { metaData, error in
if error != nil {
print(error?.localizedDescription)
} else {
imageReferance.downloadURL { url, error in
if error == nil {
let imageURL = url?.absoluteString
print(imageURL)
}
}
}
}
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
imageView.image = info[.originalImage] as? UIImage
self.dismiss(animated: true, completion: nil)
}
#objc func chooseImage() {
let pickerController = UIImagePickerController()
pickerController.delegate = self
pickerController.sourceType = .photoLibrary
present(pickerController, animated: true, completion: nil)
}
}

User variable is nil when creating a user with Firebase

I am following a tutorial and cannot seem to register my user as the user variable in the Firebase .createUser method appears to be nil. Therefore, when I unwrap it, I get an error.
I have read through a lot of the documentation as well as checked many other questions similar to mine but nothing seems to work
import UIKit
import Firebase
import SwiftKeychainWrapper
class ViewController: UIViewController {
#IBOutlet weak var userImgView: UIImageView!
#IBOutlet weak var usernameField: UITextField!
#IBOutlet weak var emailField: UITextField!
#IBOutlet weak var passwordField: UITextField!
var imagePicker: UIImagePickerController!
var selectedImage: UIImage!
override func viewDidLoad() {
super.viewDidLoad()
imagePicker = UIImagePickerController()
imagePicker.allowsEditing = true
imagePicker.delegate = self
}
override func viewDidAppear(_ animated: Bool) {
if let _ = KeychainWrapper.standard.string(forKey: "uid") {
self.performSegue(withIdentifier: "toFeed", sender: nil)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func setupUser(userUid: String) {
if let imageData = self.userImgView.image!.jpegData(compressionQuality: 0.2) {
let imgUid = NSUUID().uuidString
let metaData = StorageMetadata()
Storage.storage().reference().child(imgUid).putData(imageData, metadata: metaData) { (metadata, error) in
let downloadURL = metadata
let userData = [
"username": self.usernameField.text!,
"userImg": downloadURL!
] as [String : Any]
Database.database().reference().child("users").child(userUid).setValue(userData)
self.performSegue(withIdentifier: "toFeed", sender: nil)
}
}
}
#IBAction func signInPressed(_ sender: Any) {
if let email = emailField.text, let password = passwordField.text {
Auth.auth().signIn(withEmail: email, password: password) { user, error in
if error != nil && !(self.usernameField.text?.isEmpty)! {
Auth.auth().createUser(withEmail: email, password: password) { (user, error) in
self.performSegue(withIdentifier: "toFeed", sender: nil)
let userID = (user?.user.uid)!
self.setupUser(userUid: userID)
KeychainWrapper.standard.set(userID, forKey: "uid")
}
} else {
if let userID = (user?.user.uid) {
KeychainWrapper.standard.set((userID), forKey: "uid")
self.performSegue(withIdentifier: "toFeed", sender: nil)
}
}
}
}
}
#IBAction func getPhoto (_ sender: AnyObject) {
present(imagePicker, animated: true, completion: nil)
}
}
extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
internal func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[.originalImage] as? UIImage {
userImgView.image = image
} else {
print("image wasnt selected")
}
imagePicker.dismiss(animated: true, completion: nil)
}
}
The error I am getting is one the "let userID = (user?.user.uid)!". It is
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
The completion block for createUser(withEmail:,password:) gets called with either a AuthResult.user or an error. That why, as Joshua commented, you should check if error is nil before accessing any of the user properties.
From the auth quickstart for Swift:
Auth.auth().createUser(withEmail: email, password: password) { authResult, error in
strongSelf.hideSpinner {
guard let user = authResult?.user, error == nil else {
strongSelf.showMessagePrompt(error!.localizedDescription)
return
}
print("\(user.email!) created")
strongSelf.navigationController?.popViewController(animated: true)
}
}

How can I save an array of images into a firebase database?

I have an app where a user takes some pictures which are saved into an array, then when he presses a button i want the array of images to be saved to firebase. I have searched around and not found any good resources for this. Bellow is the code I have already written.
DataModel where I save the array of images:
import Foundation
import UIKit
class PhotoArray {
static let sharedInstance = PhotoArray()
var photosArray: [UIImage] = []
}
Taking picture code:
import UIKit
import RealmSwift
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
// var realm: Realm!
// var photoArray = [PhotoArray]()
#IBOutlet weak var imageView: UIImageView!
let imagePicker = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
// realm = try! Realm()
imagePicker.delegate = self
imagePicker.sourceType = .camera
imagePicker.allowsEditing = false
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let userPickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
// let imageToUse = PhotoArray()
// let data = UIImagePNGRepresentation(userPickedImage) //here convert to data
PhotoArray.sharedInstance.photosArray.append(userPickedImage) //append converted data in array
// do {
// try realm.write {
// realm.add(imageToUse)
// }
// } catch {
// print(“error adding image to array\(error)“)
// }
imageView.image = userPickedImage
}
// print(PhotoArray().photosArray.count)
imagePicker.dismiss(animated: true, completion: nil)
}
#IBAction func cameraButtonPressed(_ sender: UIButton) {
present(imagePicker, animated: true, completion: nil)
}
#IBAction func cameraButtonPressed(_ sender: UIButton) {
present(imagePicker, animated: true, completion: nil)
}
#IBAction func SendDataPressed(_ sender: UIButton) {
//TODO: Send the Images to Firebase and save it in our database
let messagesDB = Database.database().reference().child("Images")
let messageDictionary = ["Images": PhotoArray.sharedInstance.photosArray as NSArray]
messagesDB.childByAutoId().setValue(messageDictionary) {
(error, refrence) in
if error != nil {
print(error!)
//somthing
}
else {
print("message saved succesfully")
//somthing
}
}
}
}
Firebase databases don't support adding images to the database. You can find the supported Firebase data types here.
You should instead upload your images to a storage provider such as Firebase Cloud Storage and then save the url to that file in your database to download from later.
Here's an example:
//Create a reference to the image
let imageRef = Storage.storage().reference().child("image.jpg")
// Get image data
if let uploadData = UIImagePNGRepresentation(userPickedImage) {
// Upload image to Firebase Cloud Storage
imageRef.putData(uploadData, metadata: nil) { (metadata, error) in
guard error == nil else {
// Handle error
return
}
// Get full image url
imageRef.downloadURL { (url, error) in
guard let downloadURL = url else {
// Handle error
return
}
// Save url to database
Firestore.firestore().collection("images").document("myImage").setData(["imageUrl" : downloadUrl.absoluteString])
}
}
}

Use of unresolved identifier 'metadata'

I have this code, but I have a problem, because it writes me Use of unresolved identifier 'metadata', Thanks in advance! I am a beginner in Xcode, so please explain well!
I got this out of in a youtube tutorial, from zero2launch!
import UIKit
import FirebaseDatabase
import FirebaseAuth
import FirebaseStorage
class SignUpViewController: UIViewController {
#IBOutlet weak var ProfileImage: UIImageView!
#IBOutlet weak var UsernameField: UITextField!
#IBOutlet weak var PasswordField: UITextField!
#IBOutlet weak var Mailfield: UITextField!
var selectedImage: UIImage?
#IBAction func dismiss_onClick(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
ProfileImage.layer.cornerRadius = 40
ProfileImage.clipsToBounds = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(SignUpViewController.handleSelectProfileImageView))
ProfileImage.addGestureRecognizer(tapGesture)
ProfileImage.isUserInteractionEnabled = true
}
#objc func handleSelectProfileImageView() {
let pickerController = UIImagePickerController()
pickerController.delegate = self
present(pickerController, animated: true, completion: nil)
}
#IBAction func SignUpButton(_ sender: Any) {
Auth.auth().createUser(withEmail: Mailfield.text!, password: PasswordField.text! , completion:{(user: User?, error:Error?) in
if error != nil {
print(error!.localizedDescription)
return
}
let uid = user?.uid
let storageRef = Storage.storage().reference(forURL: "gs://gibble-2bed4.appspot.com").child("profile_image").child(uid!)
if let profileImg = self.selectedImage, let imageData = UIImageJPEGRepresentation(profileImg, 0.1){
storageRef.putData(imageData, metadata: nil, completion: { (matadata, error) in
if error != nil{
return
}
let profileImageUrl = metadata?.downloadURL()?.absoluteString
let ref = Database.database().reference()
let usersReference = ref.child("users")
let newUserReference = usersReference.child(uid!)
newUserReference.setValue(["username" : self.UsernameField.text!, "email": self.Mailfield.text!, "profileImageUrl": profileImageUrl])
})
}
})
}
}
extension SignUpViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
print("did Finish picking Media")
if let image = info["UIImagePickerControllerOriginalImage"] as? UIImage{
selectedImage = image
ProfileImage.image = image
dismiss(animated: true, completion: nil)
}
print(info)
}
}
You initialised matadata instead of metadata (which you want to use) in the closure in your following code (first line: "(matadata, error)"):
storageRef.putData(imageData, metadata: nil, completion: { (matadata, error) in
if error != nil{
return
}
let profileImageUrl = metadata?.downloadURL()?.absoluteString
The metadata in the last line should be matadata or you have to change it in the first line.

How to assign a picture to the UIImageView (Swift 3)

I'm trying to add an image from the gallery to the new ViewController, but get an error
Creating an image format with an unknown type is an error fatal error: unexpectedly found nil while unwrapping an Optional value
Code:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let im = info[UIImagePickerControllerOriginalImage] as? UIImage {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "editImage") as! EditImageViewController
vc.imageView.image = im
self.present(vc, animated: true, completion: nil)
} else {
print("Something went wrong")
}
imagePicker.dismiss(animated: true, completion: nil)
}
What's my mistake?
Your EditImageViewController.imageViewis nil.
To pass image from outside, you need to add UIImage property to EditImageViewController.
To assign that image to UIImageView, use viewDidLoad()
Something like this:
class EditImageViewController: UIViewController {
#IBOutlet weak var imageView: UIImageView!
var imageToAdd: UIImage?
override func viewDidLoad() {
super.viewDidLoad()
self.imageView.image = imageToAdd
}
}
To pass image to new controller, just set imageToAdd, so vc.imageView.image = im becomes vc.imageToAdd = im

Resources