Display alert if URL can't be opened - ios

I want to show an alert to users via UIAlertController when my app can't open a URL. Here's my code:
guard let url = URL(string: urlLink) else {
return
}
UIApplication.shared.open(url, options: [:])
And my created alert:
let alert = UIAlertController(title: "Warning", message: "Problem with URL.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
self.present(alert, animated: true)
If I move my alert inside the guard statement, it never occurs. I tested it by changing urlLink to some random String, for example, "123". Any ideas of how I can show an alert?
EDIT:
I used canOpenURL which return Bool. Now my code is:
guard let url = URL(string: urlLink) else {
return
}
if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url, options: [:])
} else {
let alert = UIAlertController(title: "Warning", message: "Problem with URL.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
self.present(alert, animated: true)
}

Should be before return
guard let url = URL(string: urlLink) , UIApplication.shared.canOpenURL(url) else {
let alert = UIAlertController(title: "Warning", message: "Problem with URL.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
self.present(alert, animated: true)
return
}

Related

How to use mailto: with url encoded string

I need to manage mailto protocol with this string:
mailto:sales#myweb.co.uk?subject=Something%20from%20Random%20Thing%20app
I'm doing with this code:
if parameter.hasPrefix("mailto") {
let urlString = parameter.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
if let url = URL(string: urlString ?? ""), UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url)
} else {
let alert = UIAlertController(title: L10n.error, message: L10n.notSupportEmail, preferredStyle: .alert)
let cancelAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alert.addAction(cancelAction)
SectionManager.sharedInstance.navigationController?.topViewController?.present(alert, animated: true, completion: nil)
}
}
When the mail app is opened, the subject still contains the "%20" encoded spaces.
How can this be avoided?

iOS App Crashes on every device except devices connected with Xcode

My app crashes and quit when user try to register a new account but that occurs on any device except devices deployed the app with Xcode.
All the devices are registered in the developer account and running iOS 11.4.1
Here is the register button function:
#IBAction func regButton(_ sender: Any) {
usernameText = usernameTextField.text
mobileText = mobileTextField.text
emailText = emailTextField.text
passwordText = passwordTextField.text
fieldText = categoryTextField.text
print(usernameText ?? "damn")
print(mobileText ?? "damn")
print(emailText ?? "damn")
print(passwordText ?? "damn")
print(fieldText ?? "damn")
if(type=="Seeker")
{
let url1 = "http://app.alosboiya.com.sa/hourjob.asmx/insert_jobseeker?name="+usernameText!+"&phone="+mobileText!
let url2 = "&email="+emailText!+"&password="+passwordText!+"&workex="+"companyDescText!"
let url3 = "&category="+fieldText!+"&image="+"downloadURLGlobal!"
let url4 = "&unpaidhour="+"string"+"&hourpaidlast30="+"string"+"&totalhourworked="+"string"+"&balance="+"string"+"&username="+usernameText!
stringURL = url1 + url2 + url3 + url4
}else
{
let url1 = "http://app.alosboiya.com.sa/hourjob.asmx/insert_company?name="+usernameText!+"&field="+fieldText!
let url2 = "&phone="+mobileText!+"&email="+emailText!+"&password="+passwordText!+"&workex="+"companyDescText!"+"&crcopy="+"downloadURLGlobal!"+"&logo="+"string"+"&username="+usernameText!
stringURL = url1 + url2
}
if Reachability.isConnectedToNetwork()
{
if(checkbox.on==true)
{
let url = URL(string: stringURL!)
Alamofire.request(url!).responseString {
(response) in
let result = response.result.value
do {
if(result=="True")
{
let alert = UIAlertController(title: "Registration Successfully", message: "Registration Done Successfully Congratulations",
preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style:
UIAlertActionStyle.default, handler: self.doSomething))
self.present(alert, animated: true, completion: nil)
}else
{
let alert = UIAlertController(title: "Registration Failed", message: "Registration Failed Please Try Again", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: { (action) in
alert.dismiss(animated: true, completion: nil)
}))
self.present(alert, animated: true, completion: nil)
}
}
}
}else
{
let alert = UIAlertController(title: "License Agreement", message: "Check to Agree Licence Agreement", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: { (action) in
alert.dismiss(animated: true, completion: nil)
}))
self.present(alert, animated: true, completion: nil)
}
}else
{
let alert = UIAlertController(title: "No Network Connection", message: "Connection Error Please Try Again", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: { (action) in
alert.dismiss(animated: true, completion: nil)
}))
self.present(alert, animated: true, completion: nil)
}
}
If a user will tap the button but one or both text fields are empty then your app will crash due to forced unwraping (! mark) which you use in your code.
Example: if mobileText field will be empty then the your app will crash:
let url1 = "http://app.alosboiya.com.sa/hourjob.asmx/insert_jobseeker?name="+usernameText!+"&phone="+mobileText!
the solution is to use guard statement
guard let usernameText = usernameTextField.text,
mobileText = mobileTextField.text,
emailText = emailTextField.text,
passwordText = passwordTextField.text,
fieldText = categoryTextField.text else {
return
}

Want to use UIAlertController inside an Alamofire reponseJSON block

The UIAlertControllers are not being executed or are not being displayed. If i solely write a print statement then there's output in the console but now the print statements are also not being executed(if i write them along with the UIAlertControllers like in the code i wrote below).
Alamofire.request(some_url, method: .post, parameters: data, encoding: URLEncoding.default, headers: nil).responseJSON{
response in
let json = JSON(response.result.value)
print(json)
self.eventid = json[0]["EventRegID"].stringValue
if !json[0]["AuthKeyError"].exists(){
if !json[0]["ExceptionOccured"].exists(){
if !json[0]["RegistrationFailed"].exists() {
if !json[0]["EventInHold"].exists() {
if json[0]["RegistrationSuccess"].exists() {
let alertController = UIAlertController(title: "", message: json[0]["RegistrationSuccess"].stringValue, preferredStyle: .alert)
let no1Action = UIAlertAction(title: "OK", style: .default) { (action) -> Void in
print("The user has registered successfully")
}
alertController.addAction(no1Action)
}
else{
}
}
else {
let alertController = UIAlertController(title: "", message: "Event is on hold.", preferredStyle: .alert)
let no2Action = UIAlertAction(title: "OK", style: .default) { (action) -> Void in
print("The event is on hold.")
}
let yes2Action = UIAlertAction(title: "GO", style: .default) { (action) -> Void in
self.performSegue(withIdentifier: "bullshit", sender: self)
}
alertController.addAction(no2Action)
alertController.addAction(yes2Action)
}
}
else {
print("Registration failed due to connection issues. Please login.")
let alertController = UIAlertController(title: "", message: "Registration failed", preferredStyle: .alert)
let no3Action = UIAlertAction(title: "OK", style: .default) { (action) -> Void in
print("The registration failed")
}
alertController.addAction(no3Action)
}
}
else {
print("There's some problem with the database")
let alertController = UIAlertController(title: "", message: "Some problem with the server", preferredStyle: .alert)
let no4Action = UIAlertAction(title: "OK", style: .default) { (action) -> Void in
print("The user has registered successfully")
}
alertController.addAction(no4Action)
}
}
else {
print("AuthKeyError")
let alertController = UIAlertController(title: "", message: "Auth key error", preferredStyle: .alert)
let no5Action = UIAlertAction(title: "OK", style: .default) { (action) -> Void in
print("AAUTH KEY ERROR")
}
alertController.addAction(no5Action)
}
}
}
else {
print("not ok")
}
}
you need to present the alertcontroller after addAction
presentViewController(alertController, animated: true, completion: nil)
maybe you have to present it in a new operation
OperationQueue.main.addOperation {
presentViewController(alertController, animated: true, completion: nil)
}

Adding a action to a UIAlert that takes the user to settings

I have a UIAlert that notifies the user that they do not have an internet connection and that they need one in order to use the app. As well as letting them dismiss the alert by tapping the ok action I also want to have a action that when tapped takes the user to the settings app.
func displayAlert(title: String, message: String){
var formEmpty = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
formEmpty.addAction((UIAlertAction(title: "Ok", style: .Default, handler: { (action) -> Void in
})))
Use this code . May be help it.
override func viewDidAppear(animated: Bool) {
var alertController = UIAlertController (title: "Title", message: "Go to Settings?", preferredStyle: .Alert)
var settingsAction = UIAlertAction(title: "Settings", style: .Default) { (_) -> Void in
let settingsUrl = NSURL(string: UIApplicationOpenSettingsURLString)
if let url = settingsUrl {
UIApplication.sharedApplication().openURL(url)
}
}
var cancelAction = UIAlertAction(title: "Cancel", style: .Default, handler: nil)
alertController.addAction(settingsAction)
alertController.addAction(cancelAction)
presentViewController(alertController, animated: true, completion: nil);
}
Please note UIApplicationOpenSettingsURLString is only available on iOS8.0 and after so if your app should support iOS7 you'll have to check for availability of the constant (or if using Swift 2.0 use the #availability keyword).
You can navigate to the setting with this code:
let settingsUrl = NSURL(string: UIApplicationOpenSettingsURLString)
UIApplication.sharedApplication().openURL(settingsUrl!)
After adding this code in your function your function will look like:
func displayAlert(title: String, message: String){
var formEmpty = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
formEmpty.addAction((UIAlertAction(title: "Ok", style: .Default, handler: { (action) -> Void in
//This will call when you press ok in your alertview
let settingsUrl = NSURL(string: UIApplicationOpenSettingsURLString)
UIApplication.sharedApplication().openURL(settingsUrl!)
})))
}
For iOS 10, Swift 3:
let alert = UIAlertController(title: "Alert!", message: "your message here", preferredStyle: .alert)
let settingsAction = UIAlertAction(title: "Settings", style: .default) { (_) -> Void in
let settingsUrl = NSURL(string: UIApplicationOpenSettingsURLString)
UIApplication.shared.open(settingsUrl as! URL, options: [:], completionHandler: nil)
alert.addAction(settingsAction)
present(alert, animated: true, completion: nil)

AlertController appears twice when saving video

Here is my code:
let library = ALAssetsLibrary()
library.writeVideoAtPathToSavedPhotosAlbum(NSURL(string: path), completionBlock: { (url, error) -> Void in
if error != nil {
let error = UIAlertController(title: "Error!", message:
"Your video is NOT saved!", preferredStyle: UIAlertControllerStyle.Alert)
error.addAction(UIAlertAction(title: "Shit!", style: UIAlertActionStyle.Default,handler:
{ action in navigationController!.popViewControllerAnimated(true) }))
self.presentViewController(error, animated: true, completion: nil)
} else {
let alertController = UIAlertController(title: "Done!", message:
"Your video is saved!", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Nice!", style: UIAlertActionStyle.Default,handler:
{ action in navigationController!.popViewControllerAnimated(true) }))
self.presentViewController(alertController, animated: true, completion: nil)
}
})
And the AlertController that says that video is saved appears twice if I press "OK" really fast (If I wait a few seconds everything is fine). What's the problem and how can I solve it ?

Resources