I am using custom CropViewController open source imagePicker for photos, and for video I'm trying to use default imagePicker provided by Swift itself since CropViewController doesn't have video option.
After I pick a video from photo library, three buttons shown at the bottom (cancel, play, select). Play button and select button works perfectly but cancel won't work.
Here is my code to trigger imagePickerController for both photo and video.
#objc func videoPresentPicker() {
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .photoLibrary
picker.mediaTypes = [kUTTypeMovie as String]
picker.allowsEditing = true
self.present(picker, animated: true, completion: nil)
}
#objc func photoPresentPicker() {
self.croppingStyle = .default
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .photoLibrary
picker.allowsEditing = false
self.present(picker, animated: true, completion: nil)
}
I am truly appreciated for you help. I have been struggling for few days and finally reaching out for some helps...
Update
extension ChatViewController: CropViewControllerDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
internal func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let videoUrl = info[UIImagePickerController.InfoKey.mediaURL] as? NSURL {
let data = NSData(contentsOf: videoUrl as URL)!
print("File size before compression: \(Double(data.length / 1048576)) mb")
let compressedURL = NSURL.fileURL(withPath: NSTemporaryDirectory() + NSUUID().uuidString + ".m4v")
self.compressVideo(inputURL: videoUrl as URL, outputURL: compressedURL) { (exportSession) in
guard let session = exportSession else {
return
}
switch session.status {
case .unknown:
break
case .waiting:
break
case .exporting:
break
case .completed:
guard let compressedData = NSData(contentsOf: compressedURL) else {
return
}
print("File size after compression: \(Double(compressedData.length / 1048576)) mb")
case .failed:
break
case .cancelled:
break
#unknown default:
break
}
}
} else {
guard let image = (info[UIImagePickerController.InfoKey.originalImage] as? UIImage) else { return }
let cropController = CropViewController(croppingStyle: croppingStyle, image: image)
cropController.delegate = self
imageView.image = image
picker.dismiss(animated: true, completion: {
self.present(cropController, animated: true, completion: nil)
if self.inputTextField.isFirstResponder == true {
self.handleKeyboardWillShow()
}
})
}
transparentView.alpha = 0
self.tableView.frame = CGRect(x: 0, y: 0, width: 0, height: 0)
dismiss(animated: true, completion: nil)
}
Just implement this function
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated:true, completion: nil)
}
Related
The user can select a picture as a profile picture in my app.
After that he can click on done and the picture gets uploaded.
If the user does not select a picture my code still upload a blank picture by clicking on done.
How can I check if the user selected a picture and then trigger the function?
I need an if else statement but don't know how to get the status "is a picture selected?"
I could maybe also use a default value. But that would mean to download the actual picture and reupload it again as default. That does not sound good.
#IBOutlet weak var tapToChangeProfileButton: UIButton!
var imagePicker: UIImagePickerController!
var ref: DatabaseReference!
#IBAction func updateProfile(_ sender: UIButton) {
uploadPic(arg: true, completion: { (success) -> Void in
if success {
addUrlToFirebaseProfile()
} else {
}
})
func uploadPic(arg: Bool, completion: #escaping (Bool) -> ()) {
guard let imageSelected = self.image else {
completion(false);
return
}
guard let imageData = imageSelected.jpegData(compressionQuality: 0.1) else {
completion(false);
return
}
let storageRef = Storage.storage().reference(forURL: "gs://....e.appspot.com")
let storageProfileRef = storageRef.child("profilePictures").child(Auth.auth().currentUser!.uid)
let metadata = StorageMetadata()
metadata.contentType = "image/jpg"
storageProfileRef.putData(imageData, metadata: metadata, completion: {
(storageMetadata, error) in
if error != nil {
//print(error?.localizedDescription)
completion(false);
return
}
storageProfileRef.downloadURL(completion: { (url, error) in
if let metaImageURL = url?.absoluteString {
print(metaImageURL)
self.urltoPicture = metaImageURL
completion(true)
}
else
{
completion(false); return
}
})
})
}
func addUrlToFirebaseProfile(){
ref = Database.database().reference()
let userID = Auth.auth().currentUser!.uid
ref.child("user/\(userID)").updateChildValues(["profileText": profileText.text!])
print(urltoPicture)
ref.child("user/\(userID)").updateChildValues(["picture": urltoPicture])
}
self.navigationController?.popViewController(animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
let imageTap = UITapGestureRecognizer(target: self, action: #selector(openImagePicker))
profileImageView.isUserInteractionEnabled = true
profileImageView.addGestureRecognizer(imageTap)
tapToChangeProfileButton.addTarget(self, action: #selector(openImagePicker), for: .touchUpInside)
imagePicker = UIImagePickerController()
imagePicker.allowsEditing = true
imagePicker.sourceType = .photoLibrary
imagePicker.delegate = self
}
#objc func openImagePicker(_ sender:Any){
self.present(imagePicker, animated: true, completion: nil)
}
extension ImagePickerViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerControllerDidCancel(_ picker: UIImagePickerController){
picker.dismiss(animated: true, completion: nil)
}
internal func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any])
{
if let pickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
self.profileImageView.image = pickedImage
image = pickedImage
}
picker.dismiss(animated: true, completion: nil)
}
}
As I see from your code, whenever you get an image from imagePickerController you store it into variable self.image. Then whenever you click Done you just upload this self.image
Make variable self.image can be nil then remember to unset it after uploading successfully
Code will be like this
var image : UIImage? = nil
#IBAction func updateProfile(_ sender: UIButton) {
uploadPic(arg: true, completion: { (success) -> Void in
if success {
addUrlToFirebaseProfile()
self.image = nil // reset image to nil if success
} else {
}
})
}
You are setting self.image if the user selects a photo.
But you are not unsetting self.image if the user doesn't select a photo. It needs to be set to nil (not to an empty UIImage()).
I am trying to add a photo selector request access. How can I trigger and present the image picker controller if access on request(first time) is granted first? Note: The .info file is already set and everything runs smooth...
I am working with an image view with these properties:
lazy var projectImageView: UIImageView = {
let imageView = UIImageView(image: #imageLiteral(resourceName: "select_photo_empty")) //Default Image View asking for photo...
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.isUserInteractionEnabled = true
imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleSelectPhoto)))
return imageView
}()
At first hand I tried this... But the code doesn't run..
func checkStatus(){
let photoAuthorizationStatus = PHPhotoLibrary.authorizationStatus()
switch photoAuthorizationStatus {
case .authorized:
print("Access is granted by user")
case .notDetermined: PHPhotoLibrary.requestAuthorization({
(newStatus) in print("status is \(newStatus)")
if newStatus == PHAuthorizationStatus.authorized {
print("success")
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.allowsEditing = true
self.present(imagePickerController, animated: true, completion: nil)
print("Trying to open photos")
}
})
case .restricted:
print("User do not have access to photo album.")
case .denied:
print("User has denied the permission.")
}
}
#objc func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
#objc func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
// Local variable inserted by Swift 4.2 migrator.
let info = convertFromUIImagePickerControllerInfoKeyDictionary(info)
print(info)
if let editedImage = info[convertFromUIImagePickerControllerInfoKey(UIImagePickerController.InfoKey.editedImage)] as? UIImage {
projectImageView.image = editedImage
} else if let originalImage = info[convertFromUIImagePickerControllerInfoKey(UIImagePickerController.InfoKey.originalImage)] as? UIImage {
projectImageView.image = originalImage
}
setupCircularImageStyle()
dismiss(animated: true, completion: nil)
}
Here's the entire code with the required blocks:
func checkStatus(){
let photoAuthorizationStatus = PHPhotoLibrary.authorizationStatus()
switch photoAuthorizationStatus {
case .authorized:
print("Access is granted by user")
case .notDetermined: PHPhotoLibrary.requestAuthorization({
(newStatus) in print("status is \(newStatus)")
if newStatus == PHAuthorizationStatus.authorized {
print("success")
}
})
case .restricted:
print("User do not have access to photo album.")
case .denied:
print("User has denied the permission.")
}
}
#objc func handleSelectPhoto(){
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.allowsEditing = true
self.present(imagePickerController, animated: true, completion: nil)
print("Trying to open photos")
}
#objc func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
#objc func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
// Local variable inserted by Swift 4.2 migrator.
let info = convertFromUIImagePickerControllerInfoKeyDictionary(info)
print(info)
if let editedImage = info[convertFromUIImagePickerControllerInfoKey(UIImagePickerController.InfoKey.editedImage)] as? UIImage {
projectImageView.image = editedImage
} else if let originalImage = info[convertFromUIImagePickerControllerInfoKey(UIImagePickerController.InfoKey.originalImage)] as? UIImage {
projectImageView.image = originalImage
}
setupCircularImageStyle()
dismiss(animated: true, completion: nil)
}
Again, I would like to present the access request for the first time to the user, but having trouble setting the 'checkStatus' function...
Good Afternoon, I am trying to allow users to save their profile picture in firebase. my application runs without a crash. however, when I select a picture it doesn't save to the system. I have a ViewController, and an extension file that I have been placing my code in. I will place below. Please help me understand what I am doing wrong. Hopefully, this question will help others who are facing the same issues.
import UIKit
import Firebase
class EditProfileVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupProfileImageView()
self.view.backgroundColor = UIColor.white
}
func setupProfileImageView() {
view.addSubview(profileImageView)
profileImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
profileImageView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 100).isActive=true
profileImageView.widthAnchor.constraint(equalToConstant: 120).isActive = true
profileImageView.heightAnchor.constraint(equalToConstant: 120).isActive = true
profileImageView.layer.cornerRadius = 60
profileImageView.layer.masksToBounds = true
var randomString = UUID().uuidString
let storageRef = Storage.storage().reference().child;"\(randomString).png")
if let uploadImage = UIImagePNGRepresentation(self.profileImageView.image!) {
storageRef.putData(uploadImage, metadata: nil) { (metadata, error) in
if error != nil {
print("Error upload data to Firebase Storage. Detail: \(String(describing: error))")
return
}
if let profileImageURl = metadata?.downloadURL()?.absoluteString {
self.registerUser(UserId: userId, profileImageURL: profileImageURL) {
}
}
}
}
}
lazy var profileImageView: UIImageView = {
let imageView = UIImageView()
imageView.image = UIImage(named: "users")
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFill
imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleSelectProfileImageView)))
imageView.isUserInteractionEnabled = true
return imageView
}()
}
// This is my extension file
import UIKit
import Firebase
extension EditProfileVC: UIImagePickerControllerDelegate, UINavigationControllerDelegate{
#objc func handleSelectProfileImageView() {
let picker = UIImagePickerController()
picker.delegate = self
picker.allowsEditing = true
present(picker, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
var selectedImageFromPicker: UIImage?
dismiss(animated: true, completion: nil)
if let editedImage = info["UIImagePickerControllerEditedImage"] {
selectedImageFromPicker = editedImage as? UIImage
} else if let originalImage = info["UIImagePickerControllerOriginalImage"] {
selectedImageFromPicker = originalImage as? UIImage
}
if let selectedImage = selectedImageFromPicker {
profileImageView.image = selectedImage
}
print(info)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
print("Canceled Picker")
dismiss(animated: true, completion: nil)
}
}
My app doesn't crash when I run it. It's just no images are stored in firebase. I want users to click onto the EditProfileVC, then be able to change their profile picture and have it save. If anyone can help me solve this issue, it would be greatly appreciated.
While choosing an image from the image picker in iOS 10, I am getting an error - Creating an image format with an unknown type is an error
Here is my code:
func CamaraInit(){
let isOk = UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera)
if isOk {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.camera
imagePicker.cameraDevice = .rear
imagePicker.showsCameraControls = true
imagePicker.allowsEditing = true
imagePicker.cameraCaptureMode = .photo
// imagePicker.cameraCaptureMode = .video
self.present(imagePicker, animated: true, completion: nil)
}
}
func imageInit(){
let isOk = UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary)
if isOk {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
//imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: nil)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
var useImage : UIImage!
let originalImage = info[UIImagePickerControllerOriginalImage] as! UIImage
let editedImage = info[UIImagePickerControllerEditedImage] as? UIImage
if editedImage == nil {
useImage = originalImage
} else {
useImage = editedImage
}
if picker.sourceType == UIImagePickerControllerSourceType.camera {
UIImageWriteToSavedPhotosAlbum(useImage, nil, nil, nil)
}
self.UIPhotoImage = useImage
self.viewChange()
picker.dismiss(animated: true, completion: nil)
}
I have searched a lot of materials but still have no idea why.
seems it is kind of warning not error,at least in my case...after uploading your image,viewWillApear will be automatically called again.
thats why you think image was not uploaded.
The output says:
- Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates.
- Save successful
But when I go into the parse backend nothing is saved.
#IBAction func recordAction(sender: AnyObject) {
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera){
print("Camera Available")
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .Camera
imagePicker.mediaTypes = [kUTTypeMovie as String]
imagePicker.videoMaximumDuration = 180 // Perhaps reduce 180 to 120
imagePicker.videoQuality = UIImagePickerControllerQualityType.TypeMedium
imagePicker.allowsEditing = false
imagePicker.showsCameraControls = true
self.presentViewController(imagePicker, animated: true, completion: nil)
}
else {
print("Camera Unavailable")
}
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
let Video = PFObject(className:"Video")
Video["user"] = PFUser.currentUser()
let tempImage = info[UIImagePickerControllerMediaURL] as! NSURL!
_ = tempImage.relativePath
let videoData = NSData(contentsOfFile:tempImage.relativePath!)
let videoFile:PFFile = PFFile(name:"consent.mp4", data:videoData!)!
Video["videoFile"] = videoFile
self.dismissViewControllerAnimated(true, completion: nil)
videoFile.saveInBackgroundWithBlock({ (succeeded: Bool, error: NSError?) -> Void in
// Handle success or failure here ...
if succeeded {
print("Save successful")
} else {
print("Save unsuccessful: \(error?.userInfo)")
}
}, progressBlock: { (amountDone: Int32) -> Void in
})
}
I figured it out. I had an extra column in the database that was unaccounted for in the apps code. When i removed it, the data was sent successfully.