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.
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 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)
}
I tried to upload images into firebase storage, and fyi my app is under firebase phone number Auth registration. And here is my code for uploading images:
#IBAction func addBtnClicked(_ sender: UIButton) {
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?
if let editedImage = info["UIImagePickerControllerEditedImage"] as? UIImage {
selectedImageFromPicker = editedImage
} else if let originalImage = info["UIImagePickerControllerOriginalImage"] as? UIImage {
selectedImageFromPicker = originalImage
}
if let selectedImage = selectedImageFromPicker {
imageView.image = selectedImage
}
let storageRef = Storage.storage().reference().child("profile_images").child("test01.png")
if let uploadData = UIImagePNGRepresentation(self.imageView.image!) {
storageRef.putData(uploadData, metadata: nil) { (metadata, error) in
if let error = error {
print(error)
return
}
}
dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
print("canceled picker")
dismiss(animated: true, completion: nil)
}
But every time after I compiled, I got this error code:
User does not have permission to access gs://cal-dev.appspot.com/profile_images/test01.png." UserInfo={object=profile_images/test01.png, ResponseBody={
"error": {
"code": 403,
"message": "Permission denied. Could not perform this operation"
}
Have you given read and write access in your firebase console? It seems that you are not authorized to write data to firebase..
It looks like the didFinishPickingMediaWithInfo function is going on an infinite loop and it eventually crashes with an error that says in the console:
warning: could not execute support code to read Objective-C class data in >the process. This may reduce the quality of type information available.
Right when I record a video and press the choose button, it crashes because it calls the didFinishPickingMediaWithInfo. Here is the relevant code:
let imagePicker: UIImagePickerController! = UIImagePickerController()
let saveFileName = "/test.mp4"
if (UIImagePickerController.isSourceTypeAvailable(.camera)) {
if UIImagePickerController.availableCaptureModes(for: .rear) != nil {
//if the camera is available, and if the rear camera is available, the let the image picker do this
imagePicker.sourceType = .camera
imagePicker.mediaTypes = [kUTTypeMovie as String]
imagePicker.allowsEditing = false
imagePicker.delegate = self as? UIImagePickerControllerDelegate & UINavigationControllerDelegate
imagePicker.videoMaximumDuration = 60
imagePicker.videoQuality = .typeIFrame1280x720
present(imagePicker, animated: true, completion: nil)
} else {
postAlert("Rear camera doesn't exist", message: "Application cannot access the camera.")
}
} else {
postAlert("Camera inaccessable", message: "Application cannot access the camera.")
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
print(123)
imagePickerController(imagePicker, didFinishPickingMediaWithInfo: [saveFileName : kUTTypeMovie])
let videoURL = info[UIImagePickerControllerReferenceURL] as? NSURL
print("\(String(describing: videoURL))" )
guard let path = videoURL?.path else { return }
let videoName = path.lastPathComponent
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentDirectory = paths.first as String!
let localPath = documentDirectory! + "/" + videoName
guard let imageData = NSData(contentsOfFile: localPath) else { return }
let image = UIImage(data: imageData as Data)
picker.dismiss(animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
self.imagePicker.delegate = self
}
Thank you in advance!
You are calling the function from inside of itself, here:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
print(123)
imagePickerController(imagePicker, didFinishPickingMediaWithInfo: [saveFileName : kUTTypeMovie])
That is causing your infinite loop.
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.