Check if device supports blur
Asked Answered
B

4

6

My app uses UIBlurEffect, however older devices (specifically iPads 2 and 3, that support iOS 8) don't have blur support.

I'd like to check if the user's device has blur support or not. How do I do it?

Belldame answered 10/1, 2015 at 17:2 Comment(0)
M
11

UIDevice has an internal method [UIDevice _graphicsQuality] that seems promising, but of course your app will be rejected by Apple. Let's create our own method:

First of all, we need to know the exact device type we're working on:

#import <sys/utsname.h>

NSString* deviceName()
{
    struct utsname systemInfo;
    uname(&systemInfo);

    return [NSString stringWithCString:systemInfo.machine
                              encoding:NSUTF8StringEncoding];
}

This should return iPad2,1 for iPad 2, for example. Here's an updated list of iDevice models: https://theiphonewiki.com/wiki/Models

So, let's classify our device models in two groups: those that have poor graphics quality (and thus don't support blur), and those with great graphics quality. According to my investigation, these are the devices that Apple considers with "poor" graphics (these may change in the future):

iPad iPad1,1 iPhone1,1 iPhone1,2 iPhone2,1 iPhone3,1 iPhone3,2 iPhone3,3 iPod1,1 iPod2,1 iPod2,2 iPod3,1 iPod4,1 iPad2,1 iPad2,2 iPad2,3 iPad2,4 iPad3,1 iPad3,2 iPad3,3

So we write the following code:

NSSet *graphicsQuality = [NSSet setWithObjects:@"iPad",
                                                     @"iPad1,1",
                                                     @"iPhone1,1",
                                                     @"iPhone1,2",
                                                     @"iPhone2,1",
                                                     @"iPhone3,1",
                                                     @"iPhone3,2",
                                                     @"iPhone3,3",
                                                     @"iPod1,1",
                                                     @"iPod2,1",
                                                     @"iPod2,2",
                                                     @"iPod3,1",
                                                     @"iPod4,1",
                                                     @"iPad2,1",
                                                     @"iPad2,2",
                                                     @"iPad2,3",
                                                     @"iPad2,4",
                                                     @"iPad3,1",
                                                     @"iPad3,2",
                                                     @"iPad3,3",
                                                     nil];
 if ([graphicsQuality containsObject:deviceName()]) {
     // Device with poor graphics, blur not supported
 } else {
     // Blur supported
 }

Be careful because even though the device may support blur, the user may have disabled advanced visual effects from Settings, Accessibility.

Alternative method

https://gist.github.com/conradev/8655650

Mastersinger answered 10/1, 2015 at 17:52 Comment(1)
When using the Simulator, the systemInfo.machine property is x86_64 (on my Mac);Stoichiometric
I
6

Here is a Swift version of Daniel Martin's answer. Some of the code was adapted from here:

func isBlurSupported() -> Bool {
    var supported = Set<String>()
    supported.insert("iPad")
    supported.insert("iPad1,1")
    supported.insert("iPhone1,1")
    supported.insert("iPhone1,2")
    supported.insert("iPhone2,1")
    supported.insert("iPhone3,1")
    supported.insert("iPhone3,2")
    supported.insert("iPhone3,3")
    supported.insert("iPod1,1")
    supported.insert("iPod2,1")
    supported.insert("iPod2,2")
    supported.insert("iPod3,1")
    supported.insert("iPod4,1")
    supported.insert("iPad2,1")
    supported.insert("iPad2,2")
    supported.insert("iPad2,3")
    supported.insert("iPad2,4")
    supported.insert("iPad3,1")
    supported.insert("iPad3,2")
    supported.insert("iPad3,3")

    return !supported.contains(hardwareString())
}

func hardwareString() -> String {
    var name: [Int32] = [CTL_HW, HW_MACHINE]
    var size: Int = 2
    sysctl(&name, 2, nil, &size, &name, 0)
    var hw_machine = [CChar](count: Int(size), repeatedValue: 0)
    sysctl(&name, 2, &hw_machine, &size, &name, 0)

    let hardware: String = String.fromCString(hw_machine)!
    return hardware
}
Ignite answered 2/5, 2015 at 2:15 Comment(0)
W
2

Many thanks do Daniel Martin for the great answer. I have made a UIDevice category that combines the following checks for availability of the blur effect:

  1. iOS version

  2. Device type (thanks to Daniel Martin)

  3. Private UIDevice method _graphicsQuality when building for the simulator. (This is done since the device type check does not work in the simulator - will be compiled out when building for arm architectures)

  4. 'Reduce Transparency' accessibility setting

I've made a gist containing the category: https://gist.github.com/mortenbekditlevsen/5a0ee16b73a084ba404d

And a small writeup about the issue as a whole:

http://mojoapps.dk/?p=1

Note: When using the gist, don't forget to subscribe to the

 UIAccessibilityReduceTransparencyStatusDidChangeNotification
notification to refresh the UI when the accessibility setting changes.

I hope that someone finds this useful. :-)

Wanettawanfried answered 30/1, 2015 at 7:23 Comment(0)
O
-2

Here are a few ways to do this:

if objc_getClass("UIBlurEffect") != nil {
   // UIBlurEffect exists
} else {
   // UIBlurEffect doesn't exist
}

Or with access to the blurEffect class

if let blurEffect: AnyClass = NSClassFromString("UIBlurEffect") {
    // UIBlurEffect exists
} else {
    // UIBlurEffect doesn't exist
}

There's actually a duplicate question here, although the title probably doesn't make it easy to find: How do I do weak linking in Swift?

-- Edit --

Misunderstood the question. There appears to be no way to find this out short of checking the device name:

Detect if device properly displays UIVisualEffectView?

I would rely on whatever Apple's fallback implementation is. It looks like they still apply the tint color so that is probably fine in most cases. If you really must change the appearance when no blur will be applied, I think device name is not terrible since they specifically outlined which devices do not support blur.

Often answered 10/1, 2015 at 17:24 Comment(2)
This won't work, because since the device is running iOS 8, the class does exist, but on the older devices, the blur view will not be rendered the same way as the new devices do.Belldame
Sorry, didn't notice the last piece of the question. I believe there is no way to check this without checking the name of the device.Often

© 2022 - 2024 — McMap. All rights reserved.