skip to Main Content

I have this code:

public enum DeviceUtil {
  public static var isPhone: Bool {
    return UIDevice.current.userInterfaceIdiom == .phone
  }
}

And I got warning saying UIDevice API has to be on the main actor. I have a few places where I have to check the device type in background thread.

Is there other API i can use that works on background thread?

2

Answers


  1. There is no need to call UIDevice.current.userInterfaceIdiom every time. The device won’t change.

    You could replace the computed property with a static assignment

    public enum DeviceUtil {
      public static var isPhone = UIDevice.current.userInterfaceIdiom == .phone
    }
    

    Then, as long as your first access to this property is on the main thread you are good.

    Login or Signup to reply.
  2. The warning you’re seeing is because UIDevice API calls should be performed on the main thread due to UIKit’s thread-safety requirements. To address this, you can create a utility function that ensures the check is performed on the main thread, even when called from a background thread.

    import UIKit
    
    public enum DeviceUtil {
        @MainActor
        public static var isPhone: Bool {
            return UIDevice.current.userInterfaceIdiom == .phone
        }
        
        @MainActor public static func isPhone(completion: @escaping (Bool) -> Void) {
            if Thread.isMainThread {
                completion(isPhone)
            } else {
                DispatchQueue.main.async {
                    completion(isPhone)
                }
            }
        }
    }
    

    Usage

    checking device type in Background Thread

    DispatchQueue.global(qos: .background).async {
        DeviceUtil.isPhone { isPhone in
            if isPhone {
                print("Running on an iPhone")
            } else {
                print("Running on an iPad")
            }
        }
    }
    

    checking device type in main thread

    DeviceUtil.isPhone { isPhone in
        if isPhone {
            print("Running on an iPhone")
        } else {
            print("Running on an iPad")
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search