I'm trying to make a link to our business facebook page from my app. So far it doesn't seem to be working. My aim was to click a button 'Facebook', have an alert pop up asking if the person wanted to open Facebook with a yes/cancel answer, and then refer them directly to our Facebook page either in the app or on the web. I've tried searching and everything I'm finding doesn't seem to help me with exactly what I needed to I tried to incorporate my own button with a link to the page I want but I don't seem to be getting anywhere. When I run my app in the simulator, the button is functional in so much as it presses and highlights but doesn't provide the alert which should then allow the person to go to the Facebook page.
Can someone help me achieve this. So far this is what I have:
#IBAction func displayFacebookPage(_ sender: Any) {
let alert = UIAlertController(title: "Open in Facebok?", message: nil, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.default) {_ in
let appURL = URL(string: "fb:/
let webURL = URL(string: "https:/
let application = UIApplication.shared
if application.canOpenURL(appURL) {
if #available(iOS 10.0, *) {
application.open(appURL)
} else {
if #available(iOS 10.0, *) {
application.open(webURL as URL)
} else {
}
}
alert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
}
Thanks!
Your braces are not correct. Use the following code
let alert = UIAlertController(title: "Open in Facebok?", message: nil, preferredStyle: UIAlertControllerStyle.alert)
let action = UIAlertAction(title: "Yes", style: UIAlertActionStyle.default) { _ in
let appURL = URL(string: "fb:/")
let webURL = URL(string: "https:/")
let application = UIApplication.shared
if application.canOpenURL(appURL!) {
if #available(iOS 10.0, *) {
application.open(appURL!)
} else {
if #available(iOS 10.0, *) {
application.open(webURL!)
} else {
}
}
}
}
let noAction = UIAlertAction(title: "No", style: UIAlertActionStyle.cancel, handler: nil)
alert.addAction(action)
alert.addAction(noAction)
self.present(alert, animated: true, completion: nil)
Related
On my app I used to present programmatically an UIAlert with the following code:
debugPrint("didReceiveInvitationFromPeer")
let fieldAlert = UIAlertController(title: "Richiesta di conssessione",
message: "da parte di \(peerID.displayName)",
preferredStyle: .alert)
fieldAlert.addAction( UIAlertAction(title: "Rifiuta", style: .cancel) { (action) in
invitationHandler(false, nil)
} )
fieldAlert.addAction( UIAlertAction(title: "accetta", style: .default) { (action) in
invitationHandler(true, self.session)
delay(2) {
// do stuff
}
} )
if let scene = UIApplication.shared.connectedScenes.first,
let sd : SceneDelegate = (scene.delegate as? SceneDelegate) {
sd.window?.rootViewController?.present(fieldAlert, animated: true, completion: nil)
}
but now SceneDelegate not exists anymore, is there any solution to how can present the alert?
No need SceneDelegate, you can directly present by this
UIApplication.shared.windows.first?.rootViewController?.present(fieldAlert, animated: true, completion: nil
I have login alert connected to UIViewController called Intro the alert show up in home screen and in all tabBar views when the user click in one of them, the alert prevent user from using the app unless he sign up. I want to stop the alert from showing because I'm implementing it somewhere else.
I tried to delete/comment the code but that resulted in a lot of errors showing
// MARK: - SHOW LOGIN ALERT
func showLoginAlert(_ mess:String) {
let alert = UIAlertController(title: APP_NAME,
message: mess,
preferredStyle: .alert)
let ok = UIAlertAction(title: "Login", style: .default, handler: { (action) -> Void in
let aVC = self.storyboard?.instantiateViewController(withIdentifier: "Intro") as! Intro
self.present(aVC, animated: true, completion: nil)
})
alert.addAction(ok)
let cancel = UIAlertAction(title: "Cancel", style: .destructive, handler: { (action) -> Void in })
alert.addAction(cancel)
present(alert, animated: true, completion: nil)
}
// MARK: - FIRE A SIMPLE ALERT
func simpleAlert(_ mess:String) {
let alert = UIAlertController(title: APP_NAME,
message: mess, preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in })
alert.addAction(ok)
present(alert, animated: true, completion: nil)
}
I am making a StockApplication using Swift and I am trying to make an Alert in the Portfolio and I am getting some errors. I have looked up the newest version of Alertview but nothing has worked so I was just looking for some help.
static func showAlert(title: String, message: String, caller: UITableViewController) {
if #available(iOS 8.0, *) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
} else {
// Fallback on earlier versions
}
if #available(iOS 8.0, *) {
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default) {
UIAlertAction in
}
} else {
// Fallback on earlier versions
}
if #available(iOS 8.0, *) {
alertcontroller.addAction(okAction)
} else {
// Fallback on earlier versions
}
caller.presentViewController(alertController, animated: true, completion: nil)
}
}
My error I'm getting Use of Unresolved Identifier alertcontroller.
Your code is all split up and your declaration of alertController is scoped to only the first if statement.
The best approach would be to group all of your code together properly:
Swift 2:
static func showAlert(title: String, message: String, caller: UITableViewController) {
if #available(iOS 8.0, *) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default) { action in
// do something
}
alertcontroller.addAction(okAction)
caller.presentViewController(alertController, animated: true, completion: nil)
} else {
// Fallback to UIAlertView on earlier versions
}
}
Of course if you have no need to support iOS 7 then none of this is needed. Just do:
static func showAlert(title: String, message: String, caller: UITableViewController) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default) { action in
// do something
}
alertcontroller.addAction(okAction)
caller.presentViewController(alertController, animated: true, completion: nil)
}
Swift 3:
static func showAlert(title: String, message: String, caller: UITableViewController) {
if #available(iOS 8.0, *) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default) { action in
// do something
}
alertController.addAction(okAction)
caller.present(alertController, animated: true, completion: nil)
} else {
// Fallback to UIAlertView on earlier versions
}
}
It looks like you're instantiating alertController inside the chunk of code where you specify that it only be executed if iOS 8.0 is available. Try something like this instead:
var alertController:UIAlertController?
if #available(iOS 8.0, *) {
alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
} else {
// Fallback on earlier versions
// Do whatever else with the alertController
}
The problem based on what error you said you're seeing is that you're trying to present a UIAlertController at the end of your method named alertController, but it's telling you there isn't any property named alertController, which tells me that line of code where you instantiated it isn't being called, which means that if condition wasn't satisfied.
I would do this, it's updated and much simpler:
func showAlert(title: String, message: String, caller: UITableViewController) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default)
alertController.addAction(okAction)
caller.present(alertController, animated: true, completion: nil)
}
Im having a problem where after I broadcast my screen live, I then try to record the screen but it doesn't work. Same thing happens when I record my screen and then I try to broadcast the screen live. Im not trying to do them together btw. This is after one is done and I try to use the other one. Let me know if you need to see code or more info. Im in Swift 3 and using the new replay kit framework. Thanks!
EDIT: THIS IS THE CODE IM USING
//LIVE STREAM REPLAYKIT=====================================================================
func broadcastActivityViewController(_ broadcastAVC: RPBroadcastActivityViewController, didFinishWith broadcastController: RPBroadcastController?, error: Error?) {
print("=====hello delegate \(broadcastController?.broadcastURL) (error)")
self.broadcastController = broadcastController
self.broadcastController?.delegate = self
broadcastAVC.dismiss(animated: true) {
self.broadcastController?.startBroadcast(handler: { error in
print("start broadcast \(error)")
print("\(broadcastController?.broadcastExtensionBundleID)")
print("==url=\(broadcastController?.broadcastURL)")
print("==serviceInfo=\(broadcastController?.serviceInfo)")
//This is called when the broadcast is live
})
}
}
func broadcastController(_ broadcastController: RPBroadcastController, didFinishWithError error: Error?) {
print("broadcastController====delegate")
let alert = UIAlertController(title: "Alert", message: "There was an error broadcasting your screen. Please try again", preferredStyle: UIAlertControllerStyle.alert)
// show the alert
self.view!.window?.rootViewController!.present(alert, animated: true, completion: nil)
alert.addAction(UIAlertAction(title: "Okay", style: UIAlertActionStyle.destructive, handler: { action in
// add action
}))
}
func broadcastController(_ broadcastController: RPBroadcastController, didUpdateServiceInfo serviceInfo: [String : NSCoding & NSObjectProtocol]) {
print("broadcastController====didUpdateServiceInfo")
}
//LIVE STREAM REPLAYKIT=========================================================
//RECORD SCREEN REPLAYKIT-------------------------------------------------------------------
func startRecoding() {
let recorder = RPScreenRecorder.shared()
if recorder.isAvailable {
recorder.startRecording(handler: { (error) in
if error == nil { // Recording has started
} else {
// Handle error
print("Dont Allow Recording")
}
})
} else {
print("Did not record screen")
//if iphone or ipad doesnt support replaykit
// create the alert
let alert = UIAlertController(title: "Alert", message: "Please make sure your device supports ReplayKit!", preferredStyle: UIAlertControllerStyle.alert)
// show the alert
self.view!.window?.rootViewController!.present(alert, animated: true, completion: nil)
alert.addAction(UIAlertAction(title: "Try Again!", style: UIAlertActionStyle.destructive, handler: { action in
// add action
}))
}
}
func stopRecording() {
let sharedRecorder = RPScreenRecorder.shared()
sharedRecorder.stopRecording(handler: { (previewViewController: RPPreviewViewController?, error) in
if previewViewController != nil {
print("stopped recording")
previewViewController!.previewControllerDelegate = self
let alertController = UIAlertController(title: "Recording", message: "Tap view to watch, edit, share, or save your screen recording!", preferredStyle: .alert)
let viewAction = UIAlertAction(title: "View", style: .default, handler: { (action: UIAlertAction) -> Void in
self.view?.window?.rootViewController?.present(previewViewController!, animated: true, completion: nil)
})
alertController.addAction(viewAction)
self.previewViewController = previewViewController!
self.previewViewController.modalPresentationStyle = UIModalPresentationStyle.fullScreen
self.view?.window?.rootViewController!.present(alertController, animated: true, completion: nil)
}
else {
print("recording stopped working")
//create the alert================================
let alert = UIAlertController(title: "Alert", message: "Sorry, there was an error recording your screen. Please Try Again!", preferredStyle: UIAlertControllerStyle.alert)
// show the alert
self.view!.window?.rootViewController!.present(alert, animated: true, completion: nil)
alert.addAction(UIAlertAction(title: "Try Again!", style: UIAlertActionStyle.destructive, handler: { action in
// add action
}))
}
})
}
func previewControllerDidFinish(_ previewViewController: RPPreviewViewController) {
print("cancel and save button pressed")
previewViewController.dismiss(animated: true, completion: nil)
//dismiss preview view controller when save or cancel button pressed
}
I believe that this is a bug in ReplayKit, I'm not sure if it has been resolved as of 10.1 or not, but it is worth trying the 10.1 beta to see if it solves your issue.
I've been looking up a lot of tutorials on UIAlertController. Thus far, the way I found was to activate a UIAlertController by linking it to a button or label and then call a IBAction.
I tried to replicate the code to automatically pop an alert when user enters the app (I wanted to ask the user if they want to go through the tutorial). However, I keep getting the error:
Warning: Attempt to present UIAlertController on MainViewController whose view is not in the window hierarchy!
Then I tried to add the UIAlertController to the MainViewController via addChildViewController and addSubview. However, I get the error:
Application tried to present modally an active controller
I figured that I cannot use the presentViewController function and commented it out.
The UIAlertController is displayed BUT when I tried to click on the cancel or the never button, this error occurs.
Trying to dismiss UIAlertController with unknown presenter.
I am really stumped. Can someone share what I am doing wrong? Thank you so much. Here is the code.
func displayTutorial() {
alertController = UIAlertController(title: NSLocalizedString("tutorialAlert", comment: ""), message: NSLocalizedString("tutorialMsg", comment: ""), preferredStyle: .ActionSheet)
self.addChildViewController(alertController)
self.view.addSubview(alertController.view)
alertController.didMoveToParentViewController(self)
alertController.view.frame.origin.x = self.view.frame.midX
alertController.view.frame.origin.y = self.view.frame.midY
//alertController.popoverPresentationController?.sourceView = self.view*/
let OkAction = UIAlertAction(title: NSLocalizedString("yesh", comment: ""), style: .Destructive) { (action) in
}
alertController.addAction(OkAction)
let cancelAction = UIAlertAction(title: NSLocalizedString("notNow", comment: ""), style: .Destructive) { (action) in
//println(action)
self.tutorial = 1
self.presentedViewController?.dismissViewControllerAnimated(true, completion: nil)
}
alertController.addAction(cancelAction)
let neverAction = UIAlertAction(title: NSLocalizedString("never", comment: ""), style: .Cancel) { (action) in
self.tutorial = 1
}
alertController.addAction(neverAction)
//self.presentViewController(alertController, animated: false) {}
}
I found the solution. Apparently, I cannot call the UIAlertController from the func viewDidLoad. I must call the function from viewDidAppear. So my code now is
override func viewDidAppear(animated: Bool) {
if tutorial == 0 {
displayTutorial(self.view)
}
}
func displayTutorial(sender:AnyObject) {
let alertController = UIAlertController(title: NSLocalizedString("tutorialAlert", comment: ""), message: NSLocalizedString("tutorialMsg", comment: ""), preferredStyle: .ActionSheet)
let OkAction = UIAlertAction(title: NSLocalizedString("yesh", comment: ""), style: .Destructive) { (action) in
}
alertController.addAction(OkAction)
let cancelAction = UIAlertAction(title: NSLocalizedString("notNow", comment: ""), style: .Default) { (action) in
//println(action)
self.tutorial = 1
self.presentedViewController?.dismissViewControllerAnimated(true, completion: nil)
}
alertController.addAction(cancelAction)
let neverAction = UIAlertAction(title: NSLocalizedString("never", comment: ""), style: .Cancel) { (action) in
self.tutorial = 1
}
alertController.addAction(neverAction)
self.presentViewController(alertController, animated: true, completion: nil)
if let pop = alertController.popoverPresentationController {
let v = sender as UIView
pop.sourceView = view
pop.sourceRect = v.bounds
}
}
Thanks to this posting: Warning: Attempt to present * on * whose view is not in the window hierarchy - swift
Below UIAlertController with extension would help you show alert with dynamic number of buttons with completion handler for selected index
extension UIViewController {
func displayAlertWith(message:String) {
displayAlertWith(message: message, buttons: ["Dismiss"]) { (index) in
}
}
func displayAlertWith(message:String, buttons:[String], completion:((_ index:Int) -> Void)!) -> Void {
displayAlertWithTitleFromVC(vc: self, title: Bundle.main.infoDictionary!["CFBundleDisplayName"] as! String, andMessage: message, buttons: buttons, completion: completion)
}
func displayAlertWithTitleFromVC(vc:UIViewController, title:String, andMessage message:String, buttons:[String], completion:((_ index:Int) -> Void)!) -> Void {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
for index in 0..<buttons.count {
let action = UIAlertAction(title: buttons[index], style: .default, handler: {
(alert: UIAlertAction!) in
if(completion != nil){
completion(index)
}
})
alertController.addAction(action)
}
DispatchQueue.main.async {
vc.present(alertController, animated: true, completion: nil)
}
}
}
If you need to auto dismiss the alert you can call dismiss on presented view controller after some delay.
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
vc.dismiss(animated: true, completion: nil)
}
Hope this might help you.