0

I have read UIAlertView/UIAlertController iOS 7 and iOS 8 compatibility thread and tried to implement the following:

if objc_getClass("UIAlertController") != nil {

     print("UIAlertController can be instantiated")

      //make and use a UIAlertController

 }
 else {

      print("UIAlertController can NOT be instantiated")

      //make and use a UIAlertView
}

But in my environment, Xcode 7.1.1 with OS X El Capitan, If I set deployment target to iOS 7.1, Xcode reports error about UIAlertController and fix them by adding availability like follows:

if #available(iOS 8.0, *) {
    alertContoller1(alertTitle, alertMessage: alertMessage)
}

and

@available(iOS 8.0, *)
func alertContoller1(alertTitle: String, alertMessage: String) {

    let alertController = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: .Alert)

    let okAction = UIAlertAction(title: "OK", style: .Default) {
        (action) -> Void in
        print("OK button tapped.")
    }

    alertController.addAction(okAction)

    presentViewController(alertController, animated: true, completion: nil)
}

Then, when I test my app with iOS simulator 7.1 (Xcode 6.4), my app immediately crash.

Secondly, when I tried to open my project with Xcode 6.4, there are 2 problems.

1.Get compile error with available(iOS 8.0, *) portion.

2.If I remove available(iOS 8.0, *) portion, my app crash with error of instantiation of alertController

So, it's a situation of "if I am true to the one, I must be false to the other"

I'd like to confirm that is it really possible to create alert which is compatible with both iOS7.1 and iOS8.0 and after?

Based on my knowings of Android software development, there are annotation @targetAPI and @SuppressWarnings("deprecation"). Are there equivalent function or not?

If Apple's intention is cutting off old things, who rescue the people those who have old devices?

Community
  • 1
  • 1
xanadu6291
  • 931
  • 10
  • 20
  • I wrote a swift example for UIAlertController/UIAlertView once: [Adding a simple UIAlertView](http://stackoverflow.com/questions/4463806/adding-a-simple-uialertview/28383410#28383410). – FreeNickname Nov 16 '15 at 08:59
  • Does your 7.1 simulator work in El Capitan? Because mine doesn't. May be it is the issue. – FreeNickname Nov 16 '15 at 09:34
  • Try to run an empty project in the 7.1 simulator. – FreeNickname Nov 16 '15 at 09:35
  • @FreeNickname I also can't run iOS7.1 simulator on El Capitan. So I'm running iOS7.1 simulator on my another Mac (Yosemite/Xcode6.4). In Yosemite/Xcode6.4, you can't use `available(iOS 8.0, *)` version check... – xanadu6291 Nov 16 '15 at 09:54
  • @FreeNickname So my problem is that I can't get alert code which are acceptable both El Capitan/Xcode7.1.1 and Yosemite/Xcode6.4 – xanadu6291 Nov 16 '15 at 09:59
  • 1
    Yes, the problem is that you should either stick to the new Xcode 7+, or to the old 6.4. If you stick to the 7+, #availability will work, but you'll need a device to test on iOS 7. But if you use Xcode 6.*, you'll have to forget about Swift 2.0. One possible solution (a bit annoying though) is to downgrade to Yosemite and use Xcode 7.1. As far as I know, iOS 7 simulator should run fine on Yosemite. – FreeNickname Nov 16 '15 at 10:05
  • But I'm not 100% sure. You can try to install Xcode 7 alongside Xcode 6.4 on your Yosemite machine and check (don't forget to make a TimeMachine backup beforehand). – FreeNickname Nov 16 '15 at 10:06
  • @FreeNickname I also confirmed that iOS7.1 simulator run fine with Xcode6.4/Yosemite. But unfortunately build app which used `#availability` does not run. Another portion of app works fine. So the issue is related with `#availability`. Of course I can't build the code with Xcode6.4/Yosemite. Anyway many thanks for advice!! – xanadu6291 Nov 16 '15 at 11:12
  • I didn't mean Xcode6.4/Yosemite, I meant Xcode7/Yosemite. iOS 7 simulator doesn't work (at least, for me) on El Capitan, but it works on Yosemite. You can run Xcode 7.1 on Yosemite. – FreeNickname Nov 16 '15 at 14:19
  • @FreeNickname Yes, I can run Xcode 7.1 on Yosemite. But I don't want to downgrade my environment to Yosemite anymore. So, I may should drop iOS7.1 support... – xanadu6291 Nov 17 '15 at 02:30

2 Answers2

0

You can simply check out device version and based on that your can instantiate UIAlertController or UIAlertView

if Float(UIDevice.currentDevice().systemVersion) >= 8{

     print("Instantiate UIAlertController")

}else{

     print("Instantiate UIAlertView")
}

Replace @available(iOS 8.0, *)

@available(iOS 7, *)
func iOS7Work() {
    // do stuff

    if #available(iOS 8, *) {
        iOS8Work()
    }
}
Sohil R. Memon
  • 9,404
  • 1
  • 31
  • 57
  • Sorry, my problem is that if I set deployment target to iOS7.1, `UIAlertController` related sentence required `available(iOS 8.0, *)` on Xcode7. – xanadu6291 Nov 16 '15 at 09:44
  • So what's the issue? It's just saying that it requires iOS 8.0 or higher – Sohil R. Memon Nov 16 '15 at 10:05
  • If I build app with `available(iOS 8.0, *)` on Xcode7.1.1/El Capitan and copy the app to iOS7.1 Simulator, it crashes. Also, I can't build app with `available(iOS 8.0, *)` on Xcode6.4/Yosemite. i.e. I can't get the code both Xcode7.1.1/El Capitan/iOS8 and Xcode6.4/Yosemite/iOS7.1 acceptable... – xanadu6291 Nov 16 '15 at 10:59
  • 1
    It seems very difficult to build code with Xcode7,1 that runs on iOS 7.1. That's just it. If we want to support iOS 7, stay with Xcode 6.4. If you want to use Xcode 7, drop iOS 7 support. – gnasher729 Nov 16 '15 at 12:03
  • @Sohil-R-Memon I modified code based on your suggestion. Works fine with iOS9 simulator. But build app crashes immediately on iOS 7.1 simulator. Of course I can't build app with that code on Xcode6.4... So sad... – xanadu6291 Nov 16 '15 at 13:58
0

I have created a custom handler for this, You can use https://github.com/ogres/CUIAlertController , it is simple replacement for UIAlertView , it will use UIAlertView for old iOS versions and AlertController for new ones.

You can import and adopt it for Swift or have a look at the source and create a similar behavior,

Usage is very simple

NSMutableArray *actions = [[NSMutableArray alloc] init];

[actions addObject:[CUIAlertAction actionWithTitle:@"Red" block:^{
    self.view.backgroundColor = [UIColor redColor];
}]];

[actions addObject:[CUIAlertAction actionWithTitle:@"Green" block:^{
    self.view.backgroundColor = [UIColor greenColor];
}]];

[actions addObject:[CUIAlertAction actionWithTitle:@"Cancel" block:nil]];

[CUIAlertController presentAlertViewWithTitle:@"Color"
                                      message:@"Change background color"
                                      actions:actions
                               fromController:self
                                     animated:YES];
ogres
  • 3,660
  • 1
  • 17
  • 16
  • Thanks for introducing custom handler. Because I'd like to make things simply, I do not use your handler this time... – xanadu6291 Nov 16 '15 at 14:02