UIImagePickerControllerDelegate error - swift

So I have this code that will get photos my gallery or use the camera to change the UIImage.
#IBAction func tappedCamera() {
print("tapped camera")
let optionMenu = UIAlertController(title: nil, message: "Choose Option", preferredStyle: .actionSheet)
let cameraAction = UIAlertAction(title: "Camera", style: .default, handler: {
(alert: UIAlertAction!) -> Void in
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera) {
self.picker.sourceType = UIImagePickerControllerSourceType.camera;
self.picker.allowsEditing = true
self.present(self.picker, animated: true, completion: nil)
}
})
let galleryAction = UIAlertAction(title: "Gallery", style: .default, handler: {
(alert: UIAlertAction!) -> Void in
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary) {
self.picker.sourceType = UIImagePickerControllerSourceType.photoLibrary;
self.picker.allowsEditing = true
self.present(self.picker, animated: true, completion: nil)
}
})
let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: {
(alert: UIAlertAction!) -> Void in
//do none
})
optionMenu.addAction(cameraAction)
optionMenu.addAction(galleryAction)
optionMenu.addAction(cancelAction)
self.present(optionMenu, animated: true, completion: nil)
}
But I always get this error, whenever I try to capture a photo or select an image from the gallery.
[Generic] Creating an image format with an unknown type is an error

I solved it by fixing my user defaults. Because somewhere along the code I was messing up with the images, converting them to base64 strings, then saving it to user defaults.

Related

How to create extension for UIAlertController in swift?

I am trying to modulraise my code I am able to create extension for alertController without target
extension UIViewController {
func showAlert(title: String, message: String) {
let alertController = UIAlertController(title: title, message:
message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: {_ in
}))
self.present(alertController, animated: true, completion: nil)
}
}
but I am not sure how to create extension which have target and textfield(how to create and call that in viewcontroller)
my code for which i am trying to create extension
let alertController = UIAlertController(title: "enter name", message: nil, preferredStyle: .alert)
let addAction = UIAlertAction(title: "Ok", style: .default) {_ in
guard let name = alertController.textFields?.first?.text else { return }
let newTask = Task(name: name)
self.toDoStore?.add(newTask, at: 0)
let indexPath = IndexPath(row: 0, section: 0)
self.tableView.insertRows(at: [indexPath], with: .automatic)
}
addAction.isEnabled = false
let cancelAction = UIAlertAction(title: CANCEL_ACTION, style: .cancel, handler: nil)
alertController.addTextField { textField in
textField.placeholder = "enter name.."
textField.addTarget(self, action: #selector(self.handleTextChanged), for: .editingChanged)
}
alertController.addAction(addAction);
alertController.addAction(cancelAction);
present(alertController, animated: true, completion: nil)
You could try the below extension that I'm using made a few changes according to your requirements.
extension UIViewController {
func showAlert(_ title: String?,
message: String?,
actions: [String: UIAlertAction.Style] = [:],
handler: ((UIAlertAction) -> Void)? = nil,
textFields: [((UITextField) -> Void)] = []) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
if actions.isEmpty {
alert.addAction(UIAlertAction(title: "Okay", style: .default))
} else {
for action in actions {
alert.addAction(UIAlertAction(title: action.key, style: action.value, handler: handler))
}
}
for textField in textFields {
alert.addTextField(configurationHandler: textField)
}
present(alert, animated: true)
}
}
A bit of advise you can always check how the parameters that you pass are accepted by the system API and customize your own function in a similar way.

Firebase Phone Auth Swift

I would like to add the ability to register with the phone number while registering. I wrote a function but it doesn't work. Can you examine the code? What should I do?
func sendCode(_ sender: Any) {
let alert = UIAlertController(title: "Phone number", message: "Is this your phone number? \n \(emailField.text!)", preferredStyle: .alert)
let action = UIAlertAction(title: "Yes", style: .default) { (UIAlertAction) in
PhoneAuthProvider.provider().verifyPhoneNumber(self.emailField.text!, uiDelegate: nil) { (verificationID, error) in
if error != nil {
print("eror: \(String(describing: error?.localizedDescription))")
} else {
let defaults = UserDefaults.standard
defaults.set(verificationID, forKey: "authVID")
let navController = UINavigationController(rootViewController: CodeEntryView())
self.present(navController, animated: true, completion: {
})
}
}
}
let cancel = UIAlertAction(title: "No", style: .cancel, handler: nil)
alert.addAction(action)
alert.addAction(cancel)
self.present(alert, animated: true, completion: nil)
}

Swift 3 how to limit user to only taking photos and NOT videos - iOS, Xcode

My photo app crashes when user selects video. The user can select photo and it works fine, but I'd like to remove the option to take a video. How do I disable video? The relevant chunk of code is below...
#IBAction func choosePhoto(_ sender: UIButton) {
let alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .actionSheet)
imagePicker = UIImagePickerController()
imagePicker.delegate = self
if (UIImagePickerController.isSourceTypeAvailable(.camera)) {
let cameraAction = UIAlertAction(title: "Use Camera", style: .default) { (action) in
let status = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)
if (status == .authorized) {
self.displayPicker(type: .camera)
}
if (status == .restricted) {
self.handleRestricted()
}
if (status == .denied) {
self.handleDenied()
}
if (status == .notDetermined) {
AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler: { (granted) in
if (granted) {
self.displayPicker(type: .camera)
}
})
}
}
alertController.addAction(cameraAction)
}
if (UIImagePickerController.isSourceTypeAvailable(.photoLibrary)) {
let photoLibraryAction = UIAlertAction(title: "Use Photo Library", style: .default) { (action) in
let status = PHPhotoLibrary.authorizationStatus()
if (status == .authorized) {
self.displayPicker(type: .photoLibrary)
}
if (status == .restricted) {
self.handleRestricted()
}
if (status == .denied) {
self.handleDenied()
}
if (status == .notDetermined) {
PHPhotoLibrary.requestAuthorization({ (status) in
if (status == PHAuthorizationStatus.authorized) {
self.displayPicker(type: .photoLibrary)
}
})
}
}
alertController.addAction(photoLibraryAction)
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
}
func handleDenied() {
let alertController = UIAlertController(title: "Camera Access Denied", message: "This app does not have acces to your device's camera. Please update your settings.", preferredStyle: .alert)
let settingsAction = UIAlertAction(title: "Go To Settings", style: .default) { (action) in
DispatchQueue.main.async {
UIApplication.shared.open(NSURL(string: UIApplicationOpenSettingsURLString)! as URL)
}
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alertController.popoverPresentationController?.sourceView = self.photoImage
alertController.popoverPresentationController?.sourceRect = self.photoImage.bounds
alertController.addAction(settingsAction)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
}
func handleRestricted() {
let alertController = UIAlertController(title: "Camera Access Denied", message: "This device is restricted from accessing the camera at this time", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alertController.popoverPresentationController?.sourceView = self.photoImage
alertController.popoverPresentationController?.sourceRect = self.photoImage.bounds
alertController.addAction(defaultAction)
present(alertController, animated: true, completion: nil)
}
func displayPicker(type: UIImagePickerControllerSourceType) {
self.imagePicker.mediaTypes = UIImagePickerController.availableMediaTypes(for: type)!
self.imagePicker.sourceType = type
self.imagePicker.allowsEditing = true
DispatchQueue.main.async {
self.present(self.imagePicker, animated: true, completion: nil)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let chosenImage = info[UIImagePickerControllerEditedImage] as! UIImage
photoImage.contentMode = .scaleAspectFill
photoImage.image = chosenImage
dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
Put this line right after imagePicker.delegate = self
imagePicker.mediaTypes = [kUTTypeImage as String]
Remember to add import MobileCoreServices at the beginning of the file.
What you want to do is after you init imagePicker set the following property
imagePicker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType: UIImagePickerControllerSourceTypeCamera];
https://developer.apple.com/documentation/uikit/uiimagepickercontroller/1619173-mediatypes

crop square image after get app gallary

I am new in swift. I made simple iphone app. Use this link: http://www.oodlestechnologies.com/blogs/Open-Image-Gallery-and-Take-photo-in-Swift and my app worked perfect. I want my app to select cropable image like facebook or telegram.
Like this:
My code:
private func showBottomActionSheet(){
let chooseOptionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
let takePhotoAction = UIAlertAction(title: "Take Photo", style: .Default, handler: {
(alert: UIAlertAction!) -> Void in
self.openCamera()
})
let choosePhotoAction = UIAlertAction(title: "Choose Photo", style: .Default, handler: {
(alert: UIAlertAction!) -> Void in
self.openGallary()
})
let findImagesAction = UIAlertAction(title: "Find Images", style: .Default, handler: {
(alert: UIAlertAction!) -> Void in
print("Clicked Find Images")
})
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: {
(alert: UIAlertAction!) -> Void in
print("Cancelled")
})
chooseOptionMenu.addAction(takePhotoAction)
chooseOptionMenu.addAction(choosePhotoAction)
chooseOptionMenu.addAction(findImagesAction)
chooseOptionMenu.addAction(cancelAction)
self.presentViewController(chooseOptionMenu, animated: true, completion: nil)
}
private func openGallary()
{
self.picker!.allowsEditing = false
self.picker!.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
presentViewController(picker!, animated: true, completion: nil)
}
private func openCamera()
{
if(UIImagePickerController .isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera)){
self.picker!.allowsEditing = false
self.picker!.sourceType = UIImagePickerControllerSourceType.Camera
self.picker!.cameraCaptureMode = .Photo
presentViewController(self.picker!, animated: true, completion: nil)
}else{
let alert = UIAlertController(title: "Camera Not Found", message: "This device has no Camera", preferredStyle: .Alert)
let ok = UIAlertAction(title: "OK", style:.Default, handler: nil)
alert.addAction(ok)
presentViewController(alert, animated: true, completion: nil)
}
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
dismissViewControllerAnimated(true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]){
let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
self.choosenPhoto = chosenImage
DefaultUser.setUserImage(chosenImage)
dismissViewControllerAnimated(true, completion: nil)
}
I found objective c code but didn't find code for swift 2.
Plz, advise me. thanks !

How to get the index of item selected in Alert of UIAlertController Swift

I am going to use UIAlertController for a user to select one item.
The items to select are array as following:
let arraySelect = ["NewYork", "Washington", "Seoul", "Tokyo", "Peking", "Sidney", ... ]
let alert = UIAlertController(title: nil, message: nil, preferredStyle: .Alert)
// Add items in array to Alert
for var i = 0; i < arraySelect.count; i++ {
alert.addAction(UIAlertAction(title: arrayBibleVersions[i], style: .Default, handler: {(_) in }))
}
// Add cancel button.
alert.addAction(UIAlertAction(title: "취소", style: .Cancel, handler: {(_) in }))
self.presentViewController(alert, animated: false, completion: nil)
When a user touched one item, I have to get the index of the item that a user toched on.
But I don't know how to get the index..
Please help me.
I solved my question as following:
let arraySelect = ["NewYork", "Washington", "Seoul", "Tokyo", "Peking", "Sidney", ... ]
let alert = UIAlertController(title: nil, message: nil, preferredStyle: .Alert)
let closure = { (action: UIAlertAction!) -> Void in
let index = alert.actions.indexOf(action)
if index != nil {
NSLog("Index: \(index!)")
}
}
for var i = 0; i < arrayBibleVersions.count; i++ {
alert.addAction(UIAlertAction(title: arrayBibleVersions[i][1], style: .Default, handler: closure))
}
alert.addAction(UIAlertAction(title: "cancel", style: .Cancel, handler: {(_) in }))
self.presentViewController(alert, animated: false, completion: nil)
This is how I solved it in Swift 4 / iOS11
projects.forEach { project in
alertController.addAction(
UIAlertAction(title: project.name, style: .default, handler: { action in
if let index = alertController.actions.index(where: { $0 === action }) {
self.showProject(project: projects[index])
}
})
)
}
I have the same problem too and found the method below which saved me.
But be careful if the item in array are the same, it will return the first item's index.
Fortunately, It's work in this case, because we create the action and using action to search.
extension Array where Self.Element : Equatable {
...
#inlinable public func index(of element: Element) -> Int?
...
}
It work in Swift 4
let arraySelect = ["NewYork", "Washington", "Seoul", "Tokyo", "Peking", "Sidney"]
let alert = UIAlertController(title: nil, message: nil, preferredStyle: .alert)
// Add items in array to Alert
for name in arraySelect {
alert.addAction(UIAlertAction(title: name, style: .default, handler: {(action) in
// print idx that user selected
if let idx = alert.actions.index(of: action) {
print("idx = \(idx)")
}
}))
}
// Add cancel button.
alert.addAction(UIAlertAction(title: "취소", style: .cancel, handler: {(_) in }))
self.present(alert, animated: true, completion: nil)
This is working good:
var arraySelect = ["NewYork", "Washington", "Seoul", "Tokyo", "Peking", "Sidney"]
let alert = UIAlertController(title: nil, message: nil, preferredStyle: .Alert)
let closure = { (action: UIAlertAction!) -> Void in
let index = alert.actions.indexOf(action)
if index != nil {
NSLog("Index: \(index!)")
}
}
for field in arraySelect {
alert.addAction(UIAlertAction(title: field, style: .Default, handler: closure))
}
alert.addAction(UIAlertAction(title: "cancel", style: .Cancel, handler: {(_) in }))
self.presentViewController(alert, animated: false, completion: nil)
Block is executed when the user selects a action.
// Add cancel button.
alert.addAction(UIAlertAction(title: "취소", style: .Cancel, handler: {(_) in
//your code
}))
func FirefoxAhri(){
let optionMenu = UIAlertController(title: "title", message: "message", preferredStyle: UIAlertControllerStyle.ActionSheet)
let action1 = UIAlertAction(title: "Yes", style: UIAlertActionStyle.Destructive){
action -> Void in
//do stuff on click Yes
}
let action2 = UIAlertAction(title: "No", style: UIAlertActionStyle.Destructive){
action -> Void in
//do stuff on click No
}
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel) { action -> Void in
print("Cancel")
// do nothing if you don't want. alert closes automatically
}
optionMenu.addAction(action1)
optionMenu.addAction(action2)
optionMenu.addAction(cancelAction)
self.presentViewController(optionMenu, animated: true, completion: nil)
}