error cannot convert value of type `Void` to expected argument type `() -> Void` UIAlertController - swift

Very often I have to show an alert to the user and I find myself writing the same code over and over again, so I built a convenience method.
When self.convenience.showAlertToUser() is called in viewDidLoad I get error for argument doThisAction cannot convert value of type Void to expected argument type () -> Void. I don't understand why, because I pass in an argument of that type. Also, I don't know if I am creating a retain cycle, so I would appreciate your help.
class ConvenienceMethods {
func showAlertToUser(alertMessage: String = "",actionOkTitle:String, actionCancelTitle:String, controller: UIViewController, cancelAction: Bool, doAction: #escaping (() -> Void)) {
let customAlert = UIAlertController(title: "", message: alertMessage, preferredStyle: .alert)
let actionCancel = UIAlertAction(title: actionCancelTitle, style: .cancel, handler: nil)
let actionOk = UIAlertAction(title: actionOkTitle, style: .default, handler: { (action: UIAlertAction) in
doAction()
})
if cancelAction == true {
customAlert.addAction(actionCancel)
}
customAlert.addAction(actionOk)
controller.present(customAlert, animated: true, completion: nil)
}
}
class ManageFeedbackTableViewController {
let convenience = ConvenienceMethods()
override func viewDidLoad() {
super.viewDidLoad()
let doThisAction = self.segueWith(id: "segueID")
self.convenience.showAlertToUser(alertMessage: "someMessage", actionOkTitle: "OK", actionCancelTitle: "No", controller: self, cancelAction: false, doAction: doThisAction)
}
//perform an action
func segueWith(id: String) -> Void{
self.performSegue(withIdentifier: id, sender: self)
}
}

Because you are to passing a reference to the function but the result itself.
Replace
let doThisAction = self.segueWith(id: "segueID")
By :
let doThisAction = { self.segueWith(id: "segueID") }

#bibscy,
doThisAction is a closure to which we can assign a block of code within "{ }" as follows:-
let doThisAction = { self.segueWith(id: "segueID") } which will work.

Related

Passing selector to a different class in swift5

I have a view controller which with a button to restore the default settings. Contained within the same VC is the function restoreDefaults()
#IBAction func resetBtnAct(_ sender: Any) {
let alert = AlertGenFromVC(sendingVC: self).generateAlert(
titleIn: "Warning!",
messageIn: "You are about to reset to the default settings. You will not be able to undo this action.",
actionTitle1: "Reset", actionAct1: #selector(self.restoreDefaults), actionTitle2: "Cancel", actionAct2: nil)
self.present(
alert,
animated: false,
completion: nil)
}
I am passing this to another class which is then used to present the alert controller
class AlertGenFromVC {
var originVC: AnyObject?
var originTextField: UITextField?
init(sendingVC: AnyObject) {
originVC = sendingVC
}
func generateAlert(titleIn: String, messageIn: String, actionTitle1:String, actionAct1:Selector, actionTitle2:String?, actionAct2:Selector?) -> UIAlertController {
let alert = UIAlertController(
title: titleIn,
message: messageIn,
preferredStyle: .alert)
// Add first action
let action1 = UIAlertAction(title: actionTitle1, style: UIAlertAction.Style.default, handler: {(action) in actionAct1
})
alert.addAction(action1)
//Action 2
if actionTitle2 != nil && actionAct2 != nil {
print("act2")
let action2 = UIAlertAction(title: actionTitle2, style: UIAlertAction.Style.default, handler: {action in actionAct2
})
alert.addAction(action2)
} else if actionTitle2 != nil && actionAct2 == nil {
print("action 2 nil")
let action2 = UIAlertAction(title: actionTitle2, style: UIAlertAction.Style.default, handler: nil)
alert.addAction(action2)
}
let popover = alert.popoverPresentationController
popover?.sourceView = self.originVC as? UIView
popover?.sourceRect = CGRect(x: 32, y: 32, width: 64, height: 64)
return alert
}
}
Action 1 and 2 both show a warning "Expression of type 'Selector' is unused".
The alert is presented fine but there is no action on clicking the button. Am i defining the selectors incorrectly or am I doing something else wrong? All suggestions gratefully received.
An extra class to create an alert controller to be presented by an UIViewController is an unswifty approach.
A better one is an extension of UIViewController
extension UIViewController {
func showAlert(titleIn: String,
messageIn: String,
actionTitle1: String,
actionAct1: (() -> Void)? = nil,
actionTitle2: String?,
actionAct2: (() -> Void)? = nil) {
let alert = UIAlertController(
title: titleIn,
message: messageIn,
preferredStyle: .alert)
// Add first action
let action1 = UIAlertAction(title: actionTitle1, style: .default, handler: { _ in actionAct1?() })
alert.addAction(action1)
//Action 2
if let title2 = actionTitle2 {
print(title2)
let action2 = UIAlertAction(title: title2, style: .default, handler: { _ in actionAct2?() })
alert.addAction(action2)
}
let popover = alert.popoverPresentationController
popover?.sourceView = self.view
popover?.sourceRect = CGRect(x: 32, y: 32, width: 64, height: 64)
self.present(alert, animated: true, completion: nil)
}
and use it
func restoreDefaults() {
// do something
}
func resetBtnAct(_ sender: Any) {
self.showAlert(
titleIn: "Warning!",
messageIn: "You are about to reset to the default settings. You will not be able to undo this action.",
actionTitle1: "Reset",
actionAct1: restoreDefaults,
actionTitle2: "Cancel")
}
You can directly pass the function as a parameter. For example like this:
let alert = AlertGenFromVC(sendingVC: self).generateAlert(
titleIn: "Warning!",
messageIn: "You are about to reset to the default settings. You will not be able to undo this action.",
actionTitle1: "Reset", actionAct1: self.restoreDefaults, actionTitle2: "Cancel", actionAct2: nil)
The function generateAlert would look like this:
func generateAlert(titleIn: String, messageIn: String, actionTitle1:String, actionAct1: #escaping ((UIAlertAction) -> Void), actionTitle2:String?, actionAct2: ((UIAlertAction) -> Void)? = nil) -> UIAlertController {
let alert = UIAlertController(
title: titleIn,
message: messageIn,
preferredStyle: .alert)
// Add first action
let action1 = UIAlertAction(title: actionTitle1, style: UIAlertAction.Style.default, handler: actionAct1)

How can I output UIAlertController to a separate file and output data from there?

I'm trying to output alert to a separate function, since there will be many similar ones.
Here is my alert:
extension UIViewController {
func alertEditSum(nameCell: String, completion: (() -> Void)) {
let alertController = UIAlertController(title: "Hello", message: "", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Save", style: .default , handler: { _ in
let nameFolderField = alertController.textFields![0] as UITextField
if nameFolderField.isTextFieldCheck(text: nameFolderField.text!) == true {
// -----here----
}
}))
alertController.addAction(UIAlertAction(title: "Cancel"
, style: .cancel, handler: nil))
alertController.addTextField(configurationHandler: { (nameField: UITextField!) -> Void in
nameField.clearButtonMode = .always
nameField.keyboardType = .decimalPad
})
self.present(alertController, animated: true)
}
}
and my piece of code is in another VC:
self.sortedDate[indexPath.section-1].personPayment = Double(nameFolderField.text!)!
do {
try! self.context.save()
collectionView.reloadData()
}
The problem is that I need to consider what exactly the user enters in UITextField. text! (nameFolderField.text!). I also can't add completion to the alert code, writes an error.
Completion should be added to the line where it says: / / - - - - - here----
Please tell me how to solve this problem?
This should do the trick:
func alertEditSum(nameCell: String, completion: #escaping ((String?) -> Void)) {
let alertController = UIAlertController(title: "Hello", message: "", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Save", style: .default, handler: { _ in
let nameFolderField = alertController.textFields![0] as UITextField
if nameFolderField.isTextFieldCheck(text: nameFolderField.text!) == true {
completion(nameFolderField.text)
}
}))
alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { _ in
completion(nil)
}))
alertController.addTextField(configurationHandler: { nameField in
nameField.clearButtonMode = .always
nameField.keyboardType = .decimalPad
})
self.present(alertController, animated: true)
}
To call it:
theViewController.alertEditSum(nameCell: "text") { text in
if let text = text {
//Do stuff
} else { //Text is invalid or user has cancel
}
}
Now, isTextFieldCheck(text:) is I guess a method on UITextField, since it's checking its own text, why giving it as a parameter?
Why not just func isTextValid()?
I would also avoid the force unwrap: !.
Going further, would be to use Result<String, Error> in the completion:
completion((Result<String, Error>) -> Void)) to have more infos if needed (user has canceled, text wasn't not valid for any reason, etc.)
You neeed #escaping completion to send value from inside a closure to a caller , Main changes completion:#escaping (String?) -> Void) and completion(nameFolderField.text)
extension UIViewController {
func alertEditSum(nameCell: String,completion:#escaping (String?) -> Void) {
let alertController = UIAlertController(title: "Hello", message: "", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Save", style: .default , handler: { _ in
let nameFolderField = alertController.textFields!.first!
if nameFolderField.isTextFieldCheck(text: nameFolderField.text!) {
completion(nameFolderField.text)
}
}))
alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
alertController.addTextField(configurationHandler: { (nameField: UITextField!) -> Void in
nameField.clearButtonMode = .always
nameField.keyboardType = .decimalPad
})
self.present(alertController, animated: true)
}
}
Call
alertEditSum(nameCell:<#SomeValue#>) { result in
print(result)
}

Using a escape function in Swift to allow the use of parameters

I am new to this escape function in Swift, but I follow a tutorial and I use the following function below: (the function is working for me)
static func showThreeOptions(messageText: String, titleOne:String, titleTwo: String, actionOne: #escaping () -> (Void), actionTwo: #escaping () -> (), currentView: UIViewController ) {
// create the alert
let alert = UIAlertController(title: "Alerta", message: messageText, preferredStyle: UIAlertController.Style.alert)
// add the actions (buttons)
alert.addAction(UIAlertAction(title: titleOne, style: UIAlertAction.Style.default, handler: { (alert) in
actionOne()
} ))
alert.addAction(UIAlertAction(title: titleTwo, style: UIAlertAction.Style.default, handler: { (alert) in
actionTwo()
} ))
alert.addAction(UIAlertAction(title: "Cancelar", style: UIAlertAction.Style.destructive, handler: nil))
// show the alert
currentView.present(alert, animated: true, completion: nil)
}
Now, I want to change the actionTwo() to actionTwo(number:Int),
but I don't know how to change the signature actionTwo: #escaping () -> ()
How can I change the signature
actionTwo: #escaping () -> () to allow to be able to call actionTwo(number:Int) ?
-----UPDATE-----
I create the function
actionTwo(2) and it works. Thank you #RobNapier
But there is another problem now.
I call the function
AlertActions.showThreeOptions(
messageText: "Resenha Finalizada.",
titleOne: "Marcas/Fotos",
titleTwo: "Editar",
actionOne: self.someHandlerOne,
actionTwo: self.someHandlerTwo(2),
currentView: self
)
This is the functions
func someHandlerOne() {
print("test")
}
func someHandlerTwo(_ id:Int) {
print("test2")
}
Now I get the following error when I call someHandlerTwo(_ id:Int)
Cannot convert value of type '()' to expected argument type '(Int) -> ()'
How can I fix that error?
-----UPDATE 2-----
I find out how to use a escaping function now
func notImplemented(resDado_id: Int) -> () {
print(resDado_id)
}
Change #escaping () -> () to #escaping (Int) -> (). Instead of something that takes no parameters, you want something that takes one.
It's a little nicer to use Void for return values that are (), like (Int) -> Void, but it means the same thing.
My suggestion is a different approach:
Write an extension of UIViewController and use the UIAlertAction handler signature for actionOne and actionTwo.
This is still more versatile and the UIAlertAction handler closures don't escape
extension UIViewController {
func showThreeOptions(messageText: String, titleOne:String, titleTwo: String, actionOne: ((UIAlertAction) -> Void)? = nil, actionTwo: ((UIAlertAction) -> Void)? = nil) {
// create the alert
let alert = UIAlertController(title: "Alerta", message: messageText, preferredStyle: .alert)
// add the actions (buttons)
alert.addAction(UIAlertAction(title: titleOne, style: .default, handler: actionOne))
alert.addAction(UIAlertAction(title: titleTwo, style: .default, handler: actionTwo))
alert.addAction(UIAlertAction(title: "Cancelar", style: .destructive, handler: nil))
// show the alert
self.present(alert, animated: true, completion: nil)
}
}
The closures can even be declared as functions for example
func actionOne(action : UIAlertAction) {
//
}
Edit:
You don't need to pass a parameter, you can create the handler inline and capture the id
func deleteSomething(at id: Int) {
let handler : (UIAlertAction) -> Void = { action in
db.deletarResDados(id: id)
}
showThreeOptions(messageText: "Resenha Finalizada.",
titleOne: "Marcas/Fotos",
titleTwo: "Editar",
actionOne: nil,
actionTwo: handler)
}

How to create a reusable UIAlert ActionSheet as an UIViewController extension?

I would like to create an action sheet that can be used several time in my code. To do so, I need to be able to use functions according to the action sheet title. Is there a way to pass functions as a parameter array like the "title" parameter?
//MARK: - UIAlert action sheet title
enum ActionSheetLabel: String {
case camera = "Camera"
case photoLibrary = "Album"
case cancel = "Cancel"
}
class CameraHandler {
static let cameraHandler = CameraHandler()
func openCamera() { }
func openPhotoLibrary() { }
}
//MARK: - Alert that shows an action sheet with cancel
extension UIViewController {
func showActionSheetWithCancel(vc: UIViewController, title: [ActionSheetLabel] /*Make a function parameter here to match title*/) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
for value in title {
actionSheet.addAction(UIAlertAction(title: value.rawValue, style: .default, handler: {
(alert: UIAlertAction!) -> Void in
//Use the parameter function here to match title
}))
}
actionSheet.addAction(UIAlertAction(title: ActionSheetLabel.cancel.rawValue, style: .cancel, handler: nil))
vc.present(actionSheet, animated: true, completion: nil)
}
}
For UIAlert you just need to change preferredStyle .alert it and it's working for UIAlert And and below code just copy and paste it working for UIActionSheet.
extension UIViewController {
func popupAlert(title: String?, message: String?, actionTitles:[String?], actionStyle:[UIAlertAction.Style], actions:[((UIAlertAction) -> Void)?]) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .actionSheet)
for (index, title) in actionTitles.enumerated() {
let action = UIAlertAction(title: title, style: actionStyle[index], handler: actions[index])
alert.addAction(action)
}
self.present(alert, animated: true, completion: nil)
}
}
Check below code For Usage
self.popupAlert(title: "Alert"), message: “Error in Loading”, actionTitles: ["Okey", "Email"], actionStyle: [.default, .default], actions: [nil,{ action in
// I have set nil for first button click
// do your code for second button click
}])
if you have any query then please comment me. Thank You
I have find out the best way to add an action sheet with cancel and as much action as needed.
Create an UIViewController extension with type alias:
//MARK: - Alert that shows an action sheet with cancel
extension UIViewController {
typealias AlertAction = () -> ()
typealias AlertButtonAction = (ActionSheetLabel, AlertAction)
func showActionSheetWithCancel(titleAndAction: [AlertButtonAction]) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
for value in titleAndAction {
actionSheet.addAction(UIAlertAction(title: value.0.rawValue, style: .default, handler: {
(alert: UIAlertAction!) -> Void in
value.1()
}))
}
actionSheet.addAction(UIAlertAction(title: ActionSheetLabel.cancel.rawValue, style: .cancel, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
}
}
Then, in the class or other place where you want to use it, add the method this way:
//MARK: - UIAlert action sheet title
enum ActionSheetLabel: String {
case camera = "Camera"
case photoLibrary = "Album"
case cancel = "Cancel"
}
//MARK: - Class example where to use the action sheet action
class CameraHandler {
fileprivate let currentVC: UIViewController!
func openCamera() {
// Open user camera
}
func openPhotoLibrary() {
// Open user photo library
}
// Method example of this action sheet
func showActionSheetWithCameraAndLibrary(vc: UIViewController) {
//This is the way to use the extension
vc.showActionSheetWithCancel(titleAndAction: [
(ActionSheetLabel.camera, { [weak self] in self?.openCamera() }),
(ActionSheetLabel.photoLibrary, { [weak self] in self?.openPhotoLibrary() })
])
}
}
You can pass a closure and call it in the handler something like this should work.
Also not sure why you were passing the UIViewController , as you're already defining the function in a extension UIViewController therefore i allowed my self to remove it and used self.present instead .
extension UIViewController {
func showActionSheetWithCancel(title: [ActionSheetLabel], action: #escaping () -> ()?) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
for value in title {
actionSheet.addAction(UIAlertAction(title: value.rawValue, style: .default, handler: {
(alert: UIAlertAction!) -> Void in
// action
action()
}))
}
let alertAction = UIAlertAction(title: ActionSheetLabel.cancel.rawValue, style: .cancel) { (_) in
action() // or for cancel call it here
}
actionSheet.addAction(alertAction)
self.present(actionSheet, animated: true, completion: nil)
}
}
As you can see #escaping () -> ()? is optional so you can pass nil too .
from what I understood you need to call a specific functions when the title of the alert changes & also you want to be able to do so from different viewControllers,
I hope this will help
extension UIViewController {
func showActionSheetWithCancel(vc: UIViewController, title: [ActionSheetLabel] ) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let cameraHandler = CameraHandler()
for value in title {
switch value.rawValue {
case ActionSheetLabel.camera.rawValue:
actionSheet.addAction(UIAlertAction(title: ActionSheetLabel.camera.rawValue, style: .default, handler: { (alert) in
cameraHandler.openCamera()
}))
case ActionSheetLabel.photoLibrary.rawValue:
actionSheet.addAction(UIAlertAction(title: ActionSheetLabel.photoLibrary.rawValue, style: .default, handler: { (alert) in
cameraHandler.openPhotoLibrary()
}))
default:
actionSheet.addAction(UIAlertAction(title: ActionSheetLabel.cancel.rawValue, style: .cancel, handler: nil))
}
vc.present(actionSheet, animated: true, completion: nil)
}
}
}
and the call of the function will be like this:
showActionSheetWithCancel(vc: self, title: [UIViewController.ActionSheetLabel.camera])

use same UIAlertController in different ViewControllers

I have used side navigation menu(SWReveal). I have 4 ViewControllers. How can use same alertAction in different views.
You can create UIViewController extension like below:
extension UIViewController {
func showAlert(title: String?, message: String?, actionTitles:[String?], actions:[((UIAlertAction) -> Void)?]) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
for (index, title) in actionTitles.enumerated() {
let action = UIAlertAction(title: title, style: .default, handler: actions[index])
alert.addAction(action)
}
self.present(alert, animated: true, completion: nil)
}
}
And you can use this alert in UIViewController like below:
showAlert(title: "Your Title", message: "Your custom Message", actionTitles: ["Ok","Cancel"], actions: [{ action1 in
//OK Action
}, { action2 in
// Cancel Action
}
])
Hope will get your solution.
You can also use like this way.
class IOSPublicDefaultAlert: NSObject{
var viewController: UIViewController?
var actionCompletion: ((String) -> ())?
var alertTitle: String?
var alertMessage : String?
var alertType: UIAlertControllerStyle?
var actionTitleAndType: [String: UIAlertActionStyle]?
init(viewController : UIViewController,alertTitle: String?,alertMessage : String?,alertType: UIAlertControllerStyle = .alert,actionTitleAndType: [String: UIAlertActionStyle] ,actionCompletion : ((String)->())?){
super.init()
self.viewController = viewController
self.actionCompletion = actionCompletion
self.alertTitle = alertTitle
self.alertMessage = alertMessage
self.alertType = alertType
self.actionTitleAndType = actionTitleAndType
showAlert()
}
func showAlert(){
let alert = UIAlertController.init(title: alertTitle, message: alertMessage, preferredStyle: self.alertType ?? .alert)
for (actionTitle, actionType) in actionTitleAndType!{
let action = UIAlertAction(title: actionTitle, style: actionType) { (action) in
if let com = self.actionCompletion{
com(actionTitle)
}
}
alert.addAction(action)
}
viewController?.present(alert, animated: true, completion: nil)
}
}
and use add where you like as below sample
_ = IOSPublicDefaultAlert.init(viewController: self, alertTitle: "Warning!!!", alertMessage: alertMessage, actionTitleAndType: ["Ok" : .destructive, "Cancel" : .default], actionCompletion: { [unowned self] (title) in
if title == "Ok"{
}
})
In swift, your project, you can create a new .swift file and in this file create a class:
import UIKit
import Foundation
class yourFileName {
//Create a class function alerview
class func displayAlert(title: String, withMessage msg: String, andbtnTitle btntitle: String, in vc: UIViewController) {
let alert = UIAlertController(title: title, message: msg, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: btntitle, style: UIAlertActionStyle.default, handler: nil))
appDelegate.window?.rootViewController?.present(alert, animated: true, completion: nil)
}
}
//and now your any ViewController.swift file or any other file in your project you can access alert following way.
class viewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
yourfilename.displayAlert(title: "Alert", withMessage msg: "my alert view display", andbtnTitle btntitle: "Ok", in vc: self) // access your alertview
}
}
I hope it's work for you.
Create BaseController with a method that can show alert.
//Copyright © 2017 dip. All rights reserved.
import UIKit
class BaseController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
///This is common method to show alert with same action
func showAlert() {
let alert = UIAlertController(title: "Alert", message: "my msg on alert", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
///This will be common alert ok aciton for all child controllers.
print("Do some userful common work..")
}))
self.present(alert, animated: true, completion: nil)
}
}
Inherit Your 4 controllers from BaseController
// Copyright © 2017 dip. All rights reserved.
//
import UIKit
class ChildVC: BaseController {
override func viewDidLoad() {
super.viewDidLoad()
//call show alert when ever you wish
///This method will call showAlert() method on super class (BaseController)
self.showAlert()
}
}
Call self.showAlert() method from child when you want show alert with common action.
// MARK: - Alertable View
protocol AlertableView {
// Use handler if need catch cancel alert action
typealias CompletionHandler = (() -> Void)
func displayAlert(with title: String, message: String, actions: [UIAlertAction]?)
func displayAlert(with title: String, message: String, style: UIAlertControllerStyle, actions: [UIAlertAction]?, completion: CompletionHandler?)
}
extension AlertableView where Self: UIViewController {
func displayAlert(with title: String, message: String, actions: [UIAlertAction]?) {
self.displayAlert(with: title, message: message, style: .alert, actions: actions, completion: nil)
}
func displayAlert(with title: String, message: String, style: UIAlertControllerStyle, actions: [UIAlertAction]?, completion: CompletionHandler?) {
let alertCancelAction = UIAlertAction(title: "Cancel".localized, style: .cancel) { (action) in
guard let completion = completion else { return }
completion()
}
let alertController = UIAlertController(title: title, message: message, preferredStyle: style)
if let actions = actions {
for action in actions {
alertController.addAction(action)
}
alertController.addAction(alertCancelAction)
} else {
// If not any custom actions, we add OK alert button
let alertOkAction = UIAlertAction(title: "OK".localized, style: .cancel) { (action) in
guard let completion = completion else { return }
completion()
}
alertController.addAction(alertOkAction)
}
self.present(alertController, animated: true, completion: nil)
}
}
Create a common function ,
import UIKit
class AlertClass: NSObject {
func showAlertWithVC(_ VC : UIViewController, andMessage message: String ){
DispatchQueue.main.async {
let alert = UIAlertController(title: "APPLICATION_NAME", message: message , preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil))
VC.present(alert, animated: true, completion: nil)
}
}
}
Simply call AlertClass().showAlertWithVC() where you want to show Alert.