Swift 3 Send image to CloudKit with CKAsset - ios

N.B: This is not a repeat question, I have looked at the other solutions but none are working in Swift 3, but they do in Swift 2.
I need to get an image from a photo library with UIImagePickerController, that is working fine, then what I need to do, is to somehow save that to a public record in CloudKit, I am very open as to how this is done. Please, if possible, be clear as to what I need to change/add and where.
I have provided my entire view controller file just to be sure.
import UIKit
import CloudKit
var email: String = ""
class ViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
//MARK: Properties
#IBOutlet weak var firstNameField: UITextField!
#IBOutlet weak var lastNameField: UITextField!
#IBOutlet weak var emailField: UITextField!
#IBOutlet weak var passwordField: UITextField!
#IBOutlet weak var confirmPasswordField: UITextField!
#IBOutlet weak var notMatching: UILabel!
#IBOutlet weak var emailLabel: UILabel!
#IBOutlet weak var errorLabel: UILabel!
#IBOutlet weak var photoImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.firstNameField.autocorrectionType = .no
self.lastNameField.autocorrectionType = .no
self.emailField.autocorrectionType = .no
self.passwordField.autocorrectionType = .no
self.confirmPasswordField.autocorrectionType = .no
self.notMatching.isHidden = true
firstNameField.delegate = self
lastNameField.delegate = self
emailField.delegate = self
passwordField.delegate = self
confirmPasswordField.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: UIImagePickerControllerDelegate
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
// Dismiss the picker if the user canceled.
dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
// The info dictionary may contain multiple representations of the image. You want to use the original.
guard let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage else {
fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}
// Set photoImageView to display the selected image.
photoImageView.image = selectedImage
// Dismiss the picker.
dismiss(animated: true, completion: nil)
}
//MARK: Actions
#IBAction func selectImageFromPhotoLibrary(_ sender: UITapGestureRecognizer) {
//Hide keyboards
firstNameField.resignFirstResponder()
lastNameField.resignFirstResponder()
emailField.resignFirstResponder()
passwordField.resignFirstResponder()
confirmPasswordField.resignFirstResponder()
let imagePickerController = UIImagePickerController()
imagePickerController.sourceType = .photoLibrary
imagePickerController.delegate = self
present(imagePickerController, animated: true, completion: nil)
}
#IBAction func signUpPressed(_ sender: UIButton) {
let container = CKContainer.default()
let pubDB = container.publicCloudDatabase
//let privDB = container.privateCloudDatabase
//Check if users exist
let query = CKQuery(recordType: "MyUsers", predicate: NSPredicate(format: "TRUEPREDICATE", argumentArray: nil))
pubDB.perform(query, inZoneWith: nil, completionHandler: { (records, error) in
//error code 11 is no objects found
if error == nil || error?._code == 11 {
var emailExists = false
for record in records! {
if record.object(forKey: "email") as? String == self.emailField.text {
//other user with the same username exists - don't allow user to create account
emailExists = true
}
}
if emailExists == true {
self.emailLabel.text = "\(self.emailField.text!) is taken. Please choose another one."
} else {
if self.firstNameField.text != nil && self.lastNameField.text != nil && self.passwordField.text == self.confirmPasswordField.text {
//user can sign up
let record = CKRecord(recordType: "MyUsers")
record.setObject(self.emailField.text! as CKRecordValue?, forKey: "email")
record.setObject(self.passwordField.text! as CKRecordValue?, forKey: "password")
record.setObject(self.firstNameField.text! as CKRecordValue?, forKey: "firstName")
record.setObject(self.lastNameField.text! as CKRecordValue?, forKey: "lastName")
print("all good")
pubDB.save(record, completionHandler: { (record, error) in
if error == nil {
OperationQueue.main.addOperation {
UserDefaults.standard.set(self.emailField.text!, forKey: "Email")
email = self.emailField.text!
//self.performSegue(withIdentifier: "Games", sender: self)
}
} else {
print(error)
}
})
} else {
}
}
} else {
print(error)
}
})
}
// MARK: UITextFieldDelegate
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// Hide the keyboard.
textField.resignFirstResponder()
return true
}
}
Thank you!

Here is a simple way to save an image as a CKAsset with CloudKit. Please make sure to change the name for your Record, and the field name for the asset from when you set up the record.
let documentsDirectoryPath:NSString = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
var imageURL: URL!
let tempImageName = "Image2.jpg"
func saveImage(_ image: UIImage?) {
// Create a CKRecord
let newRecord:CKRecord = CKRecord(recordType: "<INSERT_RECORD_NAME")
if let image = image {
let imageData:Data = UIImageJPEGRepresentation(image, 1.0)!
let path:String = self.documentsDirectoryPath.appendingPathComponent(self.tempImageName)
try? UIImageJPEGRepresentation(image, 1.0)!.write(to: URL(fileURLWithPath: path), options: [.atomic])
self.imageURL = URL(fileURLWithPath: path)
try? imageData.write(to: self.imageURL, options: [.atomic])
let File:CKAsset? = CKAsset(fileURL: URL(fileURLWithPath: path))
newRecord.setObject(File, forKey: "<INSERT_RECORD_ASSET_FIELD_NAME")
}
if let database = self.publicDatabase {
database.save(newRecord, completionHandler: { (record:CKRecord?, error:Error?) in
// Check if there was an error
if error != nil {
NSLog((error?.localizedDescription)!)
}
else if let record = record {
// Do whatever you want with the record, but image record was saved, asset should be saved.
}
})
}
}
If you can't do JPEG format, and need to save as .png you can substitute the UIImageJPEGRepresentation section with this:
let imageData:Data = UIImagePNGRepresentation(image)!
try? UIImagePNGRepresentation(image)!.write(to: URL(fileURLWithPath: path), options: [.atomic])
And make the tempImageName something like let tempImageName = "Image2.png"
Hope this helps

Swift 5 version, but abstracted to a function where I can pass in a UI Image object and return the URL to be used. Useful where I had the image saved in CoreData and wanted to later upload to CloudKit as well.
func getImageURL(for image: UIImage?) -> URL {
let documentsDirectoryPath:NSString = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
let tempImageName = "tempImage.jpg"
var imageURL: URL?
if let image = image {
let imageData:Data = image.jpegData(compressionQuality: 1.0)!
let path:String = documentsDirectoryPath.appendingPathComponent(tempImageName)
try? image.jpegData(compressionQuality: 1.0)!.write(to: URL(fileURLWithPath: path), options: [.atomic])
imageURL = URL(fileURLWithPath: path)
try? imageData.write(to: imageURL!, options: [.atomic])
}
return imageURL!
}
And then how I use it:
let imageURL = getImageURL(for: UIImage(data: itemToPublish!.Photo!)!)
let imageAsset = CKAsset(fileURL: imageURL)
itemBeingUpdated["photo"] = imageAsset
CKContainer.default().publicCloudDatabase.save(challengeRecord) { ...

Related

Share Extension don't open/share .HEIC type image

i created share extension for my app which can share image/videos from photos(Gallery) and it work properly but here problem is if i select .HEIC type file then click on my share extension it show error as shown in below screenshot .
import UIKit
import Social
import MobileCoreServices
import AVKit
import Toast_Swift
//#objc(ShareExtensionViewController)
class ShareViewController: UIViewController {
#IBOutlet weak var image: UIImageView!
#IBOutlet weak var btn: UIButton!
#IBOutlet weak var lbl: UILabel!
#IBOutlet weak var view2: UIView!
#IBOutlet weak var cancel: UIButton!
#IBOutlet weak var blurview: UIVisualEffectView!
var allMedia = [Data()]
var singleImage = UIImage()
var imagesUrl = [URL]()
let groupPath = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "
my group identifire ")
var saveDone = Bool()
override func viewDidLoad() {
super.viewDidLoad()
let attachments = (self.extensionContext?.inputItems.first as? NSExtensionItem)?.attachments ?? []
self.btn.setTitle("Add", for: .normal)
self.btn.layer.cornerRadius = 10
self.cancel.layer.cornerRadius = 10
self.image.clipsToBounds = false
applyshadow(image: image)
blurview.isHidden = true
}
override func viewDidAppear(_ animated: Bool) {
self.handleSharedFile()
}
// MARK:- function
func applyshadow(image: UIImageView) {
image.clipsToBounds = false
image.layer.shadowColor = UIColor.systemGray.cgColor
image.layer.shadowOpacity = 1
image.layer.shadowOffset = CGSize.zero
image.layer.shadowRadius = 7.5
}
func videotext(string : String) ->Bool{
let videoextension = [".MP4",".mp4",".mkv",".MKV",".AVI",".avi",".mov", ".MOV"]
if videoextension.contains(string){
return true
}
return false
}
func videoThumb(filepath: URL) -> UIImage{
do{
// let filepath = data?.appendingPathComponent(lbl[indexPath.row])
let asset = AVURLAsset(url: filepath, options: nil)
let imgGenerator = AVAssetImageGenerator(asset: asset)
imgGenerator.appliesPreferredTrackTransform = true
let cgImage = try imgGenerator.copyCGImage(at: CMTimeMake(value: 0, timescale: 1), actualTime: nil)
let uiImage = UIImage(cgImage: cgImage)
return uiImage
}catch let error {
print("Error: \(error.localizedDescription)")
return UIImage()
}
}
private func handleSharedFile() {
// extracting the path to the URL that is being shared
let attachments = (self.extensionContext?.inputItems.first as? NSExtensionItem)?.attachments ?? []
let contentType = kUTTypeData as String
for provider in attachments {
// Check if the content type is the same as we expected
if provider.hasItemConformingToTypeIdentifier(contentType) {
provider.loadItem(forTypeIdentifier: contentType,
options: nil) { [unowned self] (data, error) in
guard error == nil else { return }
if let url = data as? URL {
imagesUrl.append(url)
print(imagesUrl)
if videotext(string: String(url.lastPathComponent.suffix(4))){
DispatchQueue.main.async {
self.image.image = videoThumb(filepath: url)
if attachments.count > 1 {
lbl.text = "\(attachments.count) Items"
}else{
lbl.text = url.lastPathComponent
}
}
}else {
let imageData = try? Data(contentsOf: url)
DispatchQueue.main.async {
if provider == attachments.last{
self.image.image = UIImage(data: imageData!)
}
self.singleImage = UIImage(data: imageData!)!
if attachments.count > 1 {
lbl.text = "\(attachments.count) Items"
}else{
lbl.text = url.lastPathComponent
}
}
}
}else {
print("Impossible to save image")
}
}
}
}
}
thank You in advance for read, giving attention, answer and upvote my question :)

Can't upload user picked image to firebase storage and download url to store in database

I am trying to upload a picture picked by the user to firebase storage and then the url downloaded so the picture can be stored in realtime database, but have not been able to get it working with my code! I was originally going to use metadata!.downloadUrl() but that is no longer functional because of an update, so I am lost.
Here is my code:
import Firebase
import FirebaseAuth
import FirebaseDatabase
import FirebaseStorage
class createPostViewController: UIViewController {
#IBOutlet weak var profileImage: UIImageView!
#IBOutlet weak var contactEmail: UITextField!
#IBOutlet weak var contactPhoneNum: UITextField!
#IBOutlet weak var name: UITextField!
#IBOutlet weak var age: UITextField!
#IBOutlet weak var gender: UITextField!
#IBOutlet weak var lastSeen: UITextField!
#IBOutlet weak var profileDescription: UITextField!
#IBOutlet weak var postBtn: UIButton!
var imagePicker: UIImagePickerController!
var selectedImage: UIImage!
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(createPostViewController.handleSelect))
profileImage.addGestureRecognizer(tapGesture)
imagePicker = UIImagePickerController()
imagePicker.allowsEditing = true
imagePicker.delegate = self
postBtn.layer.cornerRadius = 10
// Do any additional setup after loading the view.
}
#objc func handleSelect(){
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
present(imagePicker, animated: true, completion: nil)
}
#IBAction func post(_ sender: AnyObject) {
let userID = Auth.auth().currentUser?.uid
Database.database().reference().child("profiles").child(userID!).observe(.value, with: { (snapshot) in
let post: Dictionary<String, AnyObject> = [
// "userImg": as AnyObject,
"name": self.name.text as AnyObject,
"contactEmail": self.contactEmail.text as AnyObject,
"contactPhoneNum": self.contactPhoneNum.text as AnyObject,
"age": self.age.text as AnyObject,
"gender": self.gender.text as AnyObject,
"lastSeen": self.lastSeen.text as AnyObject,
"profileDescription": self.profileDescription.text as AnyObject,
]
let firebasePost = Database.database().reference().child("profiles").childByAutoId()
firebasePost.setValue(post)
})
}
func uploadImageToFireBase(image: UIImage) {
// Create the file metadata
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"
let storageRef = Storage.storage().reference()
let profileRef = storageRef.child("images/rivers.jpg")
// Upload the file to the path FILE_NAME
Storage.storage().reference().child("FILE_NAME").putData(image.jpegData(compressionQuality: 0.42)!, metadata: metadata) { (metadata, error) in
guard let metadata = metadata else {
// Uh-oh, an error occurred!
print((error?.localizedDescription)!)
return
}
// Metadata contains file metadata such as size, content-type.
let size = metadata.size
print("Upload size is \(size)")
print("Upload success")
}
}
//func uploadToCloud(fileURL : URL) {
// let storage = Storage.storage()
//let data = Data()
//let storageRef = storage.reference()
//let localFule = fileURL
//let userID = Auth.auth().currentUser?.uid
//let photoRef = storageRef.child("profilePhoto\(userID)")
//let uploadTask = photoRef.putFile(from: localFule, metadata: nil) { (metadata, err) in
// guard let metadata = metadata else {
// print(err?.localizedDescription)
// return
//}
//print("Photo Upload")
// }
// }
}
extension createPostViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate{
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info["UIImagePickerControllerEditedImage"]as? UIImage {
selectedImage = image
print("success")
profileImage.image = image
uploadImageToFireBase(image: selectedImage)
} else {
print("image wasnt selected")
}
dismiss(animated: true, completion: nil)
}
}
I think you can still use the downloadUrl method on the storage reference.
func uploadImageToFireBase(image: UIImage) {
// Create the file metadata
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"
// Upload the file to the path FILE_NAME
Storage.storage().reference().child("FILE_NAME").putData(image.jpegData(compressionQuality: 0.42)!, metadata: metadata) { (metadata, error) in
guard let metadata = metadata else {
print((error?.localizedDescription))
return
}
Storage.storage().reference().child("FILE_NAME").downloadURL { (imageUrl, error) in
if let error = error {
print("error: ", error.localizedDescription)
return
}
if let userID = Auth.auth().currentUser?.uid {
let currentUserRef = Database.database().reference().child("profiles").child(userID)
currentUserRef.updateChildValues(["profileImage": imageUrl])
}
}
}
}
Pls see this answer.

Issue uploading an image to firebase storage

I am trying to write a function that will allow a user to set a new profile image, new image will be uploaded and the old image will be removed from firebase storage.
I have two functions that will do this and they work individually, however if I run the upload after the delete function the new image will not upload, even though I get a success message in the console nothing appears in the storage. Ideally I would like to remove first and the set the new image, and I have tried doing this multiple ways; completion handlers, adding delays but nothing has worked. I now even have two buttons one controlling each function to test this but this is still not working. What am I missing?? Any help would be great as ive spent hours racking my brains with this!
Here is my complete code for the VC:
//
// LandingVC.swift
// Login
//
// Created by George Woolley on 07/11/2017.
// Copyright © 2017 George Woolley. All rights reserved.
//
import UIKit
import FBSDKLoginKit
import SwiftKeychainWrapper
import Firebase
class MyAccountVC: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var profilePictureImg: UIImageView!
#IBOutlet weak var usernameField: UILabel!
#IBOutlet weak var saveButton: UIButton!
#IBOutlet weak var changeProfilePicButton: UIButton!
let picker = UIImagePickerController()
let myUID = KeychainWrapper.standard.string(forKey: "uid")
override func viewDidLoad() {
super.viewDidLoad()
picker.delegate = self
if myUID == nil {
print("You are not logged in")
} else {
let ref = DataService.ds.DBCurrentUser
ref.child("MyDetails").observe(.value, with: { (snapshot) in
if let snapshots = snapshot.children.allObjects as? [DataSnapshot] {
for snap in snapshots {
if snap.key == "username" {
self.usernameField.text = snap.value as? String
}
if snap.key == "profileImageURL" {
if let url = snap.value as? String {
let ref = Storage.storage().reference(forURL: url)
ref.getData(maxSize: 2 * 1024 * 1024, completion: { (data, error) in
if error != nil {
print("An error has occured downloading image")
} else {
print("Image downloaded")
if let imageData = data {
if let img = UIImage(data: imageData) {
self.profilePictureImg.image = img
}
}
}
})
}
}
}
}
})
}
}
func removeImgFromFirebaseStorage() {
let ref = DataService.ds.DBCurrentUser.child("MyDetails")
ref.observe(.value) { (snapshot) in
if let snapshots = snapshot.children.allObjects as? [DataSnapshot] {
for snap in snapshots {
if snap.key == "profileImageURL" {
if let url = snap.value as? String {
let img = Storage.storage().reference(forURL: url)
img.delete(completion: { (error) in
if error != nil {
print("Error is \(String(describing: error))")
} else {
print("Success")
}
})
}
}
}
}
}
saveButton.isHidden = false
changeProfilePicButton.isHidden = true
}
func uploadImageToFirebase() {
if let imageToUpload = profilePictureImg.image {
if let imageData = UIImageJPEGRepresentation(imageToUpload, 0.2) {
let metaData = StorageMetadata()
metaData.contentType = "image/jpeg"
let imageUID = UUID().uuidString
DataService.ds.StorageProfile.child(imageUID).putData(imageData, metadata: metaData, completion: { (metadata, error) in
if error != nil {
print("Error occured uploading profile image")
} else {
print("Sucess")
if let downloadURL = metadata?.downloadURL()?.absoluteString {
DataService.ds.DBCurrentUser.child("MyDetails").child("profileImageURL").setValue(downloadURL)
}
}
})
}
}
saveButton.isHidden = true
changeProfilePicButton.isHidden = false
}
#IBAction func saveButonPressed(_ sender: Any) {
uploadImageToFirebase()
}
#IBAction func changeProfilePicturePressed(_ sender: Any) {
picker.allowsEditing = true
picker.sourceType = .photoLibrary
picker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
present(picker, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
profilePictureImg.contentMode = .scaleAspectFill
profilePictureImg.image = chosenImage
dismiss(animated: true, completion: removeImgFromFirebaseStorage)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
#IBAction func logOffPressed(_ sender: Any) {
KeychainWrapper.standard.removeObject(forKey: "uid")
performSegue(withIdentifier: "loginVC", sender: nil)
let fbLogin = FBSDKLoginManager()
fbLogin.logOut()
try! Auth.auth().signOut()
}
}

Initializer for conditional binding error while trying to build Login

I am trying to finish my login page for a social media app and I have one error which I can't seem to figure out.
Here is the full code:
import UIKit
import Firebase
import FirebaseAuth
import FirebaseStorage
import FirebaseDatabase
import SwiftKeychainWrapper
class UserVC: UIViewController, UIImagePickerControllerDelegate,
UINavigationControllerDelegate
{
#IBOutlet weak var userImagePicker: UIButton!
#IBOutlet weak var CompleteSignInBtn: UIButton!
#IBOutlet weak var usernameField: UITextField!
var userUid: String!
var emailField: String!
var passwordField: String!
var imagePicker : UIImagePickerController!
var imageSelected = false
var username: String!
override func viewDidLoad(){
super.viewDidLoad()
imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.allowsEditing = true
}
func keychain(){
KeychainWrapper.standard.set(userUid, forKey: "uid")
}
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerEditedImage] as? UIImage {
userImagePicker.setImage(image,for:.normal)
imageSelected = true
} else {
print("Image was not selected")
}
imagePicker.dismiss(animated: true, completion: nil)
}
func setUpUser(img: String ){
let userData = [
"username": username!,
"userImg": img
]
keychain()
let setLocation = Database.database().reference().child(userUid)
setLocation.setValue(userData)
}
func uploadImg() {
if usernameField.text == nil {
print("Please choose a username")
CompleteSignInBtn.isEnabled = false
} else {
username = usernameField.text
CompleteSignInBtn.isEnabled = true
}
guard let img = userImagePicker.image, imageSelected == true else {
print("image must be selected")
return
}
if let imgData = UIImageJPEGRepresentation(img, 0.2){
let imgUid = NSUUID().uuidString
let metadata = StorageMetadata()
metadata.contentType = "img/jpeg"
Storage().reference().child(imgUid).put(imgData, metadata: metadata) { (metadata, error) in
if error =! nil {
print("Did not upload")
} else{
print("Uploaded")
let downloadURl = metadata?.downloadURL()?.absoluteString
if let url = downloadURl {
self.setUpUser(img: url)
}
}
}
}
}
#IBAction func completeAccount(_ sender: Any){
Auth.auth().createUser(withEmail: emailField, password: passwordField, completion: { (user, error) in
if error != nil {
print("Error\(error)")
} else {
if let user = user {
self.userUid = user.uid
}
}
self.uploadImg()
})
dismiss(animated: true, completion: nil)
}
#IBAction func seletedImagePicker(_ sender: Any){
present(imagePicker, animated: true, completion: nil)
}
#IBAction func cancel(_ sender: AnyObject){
dismiss(animated: true, completion: nil)
}
}
The code which is causing the error mentioned in the title is this:
guard let img = userImagePicker.image, imageSelected == true else {
print("image must be selected")
return
}
I have no idea what to do. I read that is has something to do with the fact that userimagePicker.image might not be optional, but in a guide I am following it works.
Thanks!
You've declared userImagePicker as UIButton and UIButton has no property called image. You should use currentImage
guard let img = userImagePicker.currentImage, imageSelected == true else {
print("image must be selected")
return
}

Creating an image format with an unknown type is an error did not upload image. Swift

Im trying to have users upload an Image and create an account. After the image is selected however, the user is then supposed to select, 'create account'. But the program is halted and does nothing after that. Then this message shows up in the compiler, 'Creating an image format with an unknown type is an error did not upload image.'
Here is the code.
import UIKit
import Firebase
import FirebaseDatabase
import FirebaseStorage
import SwiftKeychainWrapper
class SignUpVC: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var userImagePicker: UIImageView!
#IBOutlet weak var usernameField: UITextField!
#IBOutlet weak var signUpBtn: UIButton!
var userUid: String!
var emailField: String!
var passwordField: String!
var imagePicker: UIImagePickerController!
var imageSelected = false
var username: String!
override func viewDidLoad() {
super.viewDidLoad()
imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.allowsEditing = true
}
override func viewDidDisappear(_ animated: Bool) {
if let _ = KeychainWrapper.standard.string(forKey: "uid") {
performSegue(withIdentifier: "toMessage", sender: nil)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerEditedImage] as? UIImage {
userImagePicker.image = image
imageSelected = true
} else {
print("image wasnt selected")
}
imagePicker.dismiss(animated: true, completion: nil)
}
func setUser(img: String) {
let userData = [
"username": username!,
"userImg": img
]
KeychainWrapper.standard.set(userUid, forKey: "uid")
let location = Database.database().reference().child("users").child(userUid)
location.setValue(userData)
dismiss(animated: true, completion: nil)
}
func uploadImg() {
if usernameField.text == nil {
signUpBtn.isEnabled = false
} else {
username = usernameField.text
signUpBtn.isEnabled = true
}
guard let img = userImagePicker.image, imageSelected == true else {
print("image needs to be selected")
return
}
if let imgData = UIImageJPEGRepresentation(img, 0.2) {
let imgUid = NSUUID().uuidString
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"
Storage.storage().reference().child(imgUid).putData(imgData, metadata: metadata) { (metadata, error) in
if error != nil {
print ("did not upload image")
} else {
print("uploaded")
let downloadURL = metadata?.downloadURL()?.absoluteString
if let url = downloadURL {
self.setUser(img: url)
}
}
}
}
}
#IBAction func createAccount (_ sender: AnyObject) {
Auth.auth().createUser(withEmail: emailField, password: passwordField, completion: {(user, error) in
if error != nil {
print("Cant create user")
} else {
if let user = user {
self.userUid = user.uid
}
}
self.uploadImg()
})
}
#IBAction func selectedImgPicker (_ sender: AnyObject) {
present(imagePicker, animated: true, completion: nil)
}
#IBAction func cancel (_ sender: AnyObject) {
dismiss(animated: true, completion: nil)
}
}
Sorry if this is too much, but I'm not exactly sure where to pin point this error since Xcode isn't showing it as an error. It seems as if the solution could be somewhere here but I am having trouble finding it. Thanks in advance.
You can use availableMediaTypes to make sure it only shows the valid image types.
let type = kUTTypeImage as String
let imagePicker = UIImagePickerController()
if UIImagePickerController.isSourceTypeAvailable(.camera) {
if let availableTypes = UIImagePickerController.availableMediaTypes(for: .camera) {
if availableTypes.contains(type) {
imagePicker.mediaTypes = [type]
imagePicker.sourceType = UIImagePickerControllerSourceType.camera
}
}
} else {
return
}
imagePicker.allowsEditing = true
imagePicker.showsCameraControls = true
imagePicker.delegate = self
Then you might also check UIImagePickerControllerOriginalImage
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage ?? info[UIImagePickerControllerEditedImage] as? UIImage {
userImagePicker.image = image
imageSelected = true
} else {
print("image wasnt selected")
}
imagePicker.dismiss(animated: true, completion: nil)
}

Resources