Alert that can work on iOS 7 and iOS 8

backwards-compatibility, ios, swift

Solution

Explicitly add UIKit in the "Link Binary With Libraries" section of your project's build phases.

You can test for the existence of UIAlertController like this:

if NSClassFromString("UIAlertController") != nil {
    // Use it
} else {
    // Fall back
}

I wrote a wrapper that works on both iOS 7 and iOS 8. You can find it here. It takes a view controller followed by a bunch of optional arguments and any number of buttons:

showAlert(self, style: .ActionSheet, sourceView: cell, completion: {
    tableView.deselectRowAtIndexPath(indexPath, animated: true)
},
    (.Default, "Send clipboard", {
        if someCondition {
            // completion must be specified because of a Swift bug (rdar://18041904)
            showAlert(self, title: "Nothing to send", message: "The clipboard is empty.", completion: nil,
                (.Cancel, "OK", nil)
            )
        }
    }),
    (.Cancel, "Cancel", nil)
)

Problem

I'm getting dyld: Symbol not found: _OBJC_CLASS_$_UIAlertAction when I'm trying to get this monstrosity to run. How do I weaklink 8.0 stuff? ``` var device : UIDevice = UIDevice.currentDevice()!; var systemVersion = device.systemVersion; var iosVerion : Float = systemVersion.bridgeToObjectiveC().floatValue; if(iosVerion < 8.0) { let alert = UIAlertView() alert.title = "Noop" alert.message = "Nothing to verify" alert.addButtonWithTitle("Click") alert.show() } else { var alert : UIAlertController? = UIAlertController(title: "Noop", message: "Nothing to verify", preferredStyle: UIAlertControllerStyle.Alert) if alert { let actionStyle : UIAlertActionStyle? = UIAlertActionStyle.Default; var alertAction : UIAlertAction? = UIAlertAction(title: "Click", style: actionStyle!, handler: nil) if(alertAction) { alert!.addAction(alertAction) self.presentViewController(alert, animated: true, completion: nil) } } } return; ``` Resolved: UIKit had to be marked Optional rather than Required. Simplified version is now: ``` var device : UIDevice = UIDevice.currentDevice()!; var systemVersion = device.systemVersion; var iosVerion : Float = systemVersion.bridgeToObjectiveC().floatValue; if(iosVerion < 8.0) { let alert = UIAlertView() alert.title = "Noop" alert.message = "Nothing to verify" alert.addButtonWithTitle("Click") alert.show() } else { var alert : UIAlertController = UIAlertController(title: "Noop", message: "Nothing to verify", preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title: "Click", style:.Default, handler: nil)) self.presentViewController(alert, animated: true, completion: nil) } ```

Original source

Related problems