iosswiftattributesios-simulatorswift-macro

Disable a chunk of code for old simulators in swift?


I have a "request review" alert:

SKStoreReviewController.requestReview(in: scene)

The problem is it hangs the iPhone 15.x simulator so I decided to disable it.

But there is another problem - disabling of simulator is implemented with macro:

#if !targetEnvironment(simulator)
   ...
#endif

and disabling for particular iOS versions is implemented with the attributes @available or #available.

How to combine macro with these attributes? Or are there more convenient ways to achieve this?

My current code is:

#if targetEnvironment(simulator)
        if #available(iOS 16, *) {
            SKStoreReviewController.requestReview(in: scene)
        }
#else
        SKStoreReviewController.requestReview(in: scene)
#endif

Solution

  • You can always write your own global variables that wraps these "macros" (technically they are not macros).

    #if targetEnvironment(simulator)
        let isSimulator = true
    #else
         let isSimulator = false
    #endif
    
    var ios16Available: Bool {
        if #available(iOS 16, *) {
            true
        } else {
            false
        }
    }
    

    Then you can do

    if ios16Available || !isSimulator {
        SKStoreReviewController.requestReview(in: scene)
    }
    

    You can avoid declaring ios16Available if you can accept an empty if statement (I find this horrendous):

    if #unavailable(iOS 16), isSimulator {} else {
        SKStoreReviewController.requestReview(in: scene)
    }
    

    If it is possible to return immediately, a guard works perfectly:

    guard #unavailable(iOS 16), isSimulator else {
        SKStoreReviewController.requestReview(in: scene)
        return
    }