What Device am I?

If someone wants to translate this to iOS-XOJO, here is some SWIFT code I use to determine which device the app is actually running on (NOTE: this is based on actual device metrics, so may not work on future devices)

var device_type:Int=0

let iPhone4     = 0
let iPhone5     = 1
let iPhone6     = 2
let iPhone6Plus = 3
let iPad2       = 4
let iPadRetina  = 5

func dev_width()  -> CGFloat { return UIScreen.mainScreen().bounds.size.width  }

func dev_height() -> CGFloat { return UIScreen.mainScreen().bounds.size.height }

func dev_scale()  -> CGFloat { return UIScreen.mainScreen().scale }

func is_IPAD() -> Bool {
    if (device_type==iPad2) || (device_type==iPadRetina) {
        return true
    }
    return false
}

func get_device_id()  {
    switch dev_width() {
    case 320: // either a 4s or 5s
        device_type=iPhone4
        if dev_height()>480 {device_type=iPhone5}
    case 375:
        device_type=iPhone6
    case 414:
        device_type=iPhone6Plus
    case 768: // either iPad2 or Retina
        device_type=iPad2
        if dev_scale()==2 {device_type=iPadRetina}
    default:
        device_type=iPhone4
    }
}

I’d declare into UIDevice
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIDevice_Class/index.html

If I recall… UIDEVICE doesn’t work if you are running in the Simulator… I believe that was in fact my first take on this…

Seems rather silly that the simulator won’t return UIDEVICE information on the device it is simulating

[quote=152291:@Dave S]If someone wants to translate this to iOS-XOJO, here is some SWIFT code I use to determine which device the app is actually running on (NOTE: this is based on actual device metrics, so may not work on future devices)
[/quote]

Using the screen size, though, could become kind of unreliable is/when Apple releases new devices. In Particular, I fear the Resizable iPhone and iPad is a sign there will be more to come.

Although there is no indication that will ever become reality, what about if iOS becomes able to vary resolution, like the Display control panel does in Mac OS X ? After all, that would be a logical evolution. Already, rooted Android tablets can do that.

Finally, iPad 9" and 7" have the same resolution. Yet, it could be useful to know the physical size of the screen.

For the moment, though, it looks as quite useful as it is. Thank you for sharing this.

Norman’s suggestion of UIDevice seems a more powerful way to go. The name property looks like what is needed. Maybe a declare guru will come along and provide that ?

I definitely would not rely on screen sizes for determining devices.

Again… I stated it works only for current devices… and UIDEVICE does NOT work in the simulator

so use #if DebugBuild
For the simulator use the size
UIDevice for real devices

[quote=152318:@Norman Palardy]so use #if DebugBuild
For the simulator use the size
UIDevice for real devices[/quote]

From a question in SO, http://stackoverflow.com/questions/6621730/uidevice-model-vs-localizedmodel
it seems the simulator does return “iPhone Simulator” no matter the device selected. But it does report something.

So that could be enough to use a conditional and then use the size.

I have been trying to come up with a declare based on the Swift example :

[code]
currentDevice
Returns an object representing the current device.

Declaration
SWIFT
class func currentDevice() -> UIDevice[/code]

and

[code]The name identifying the device. (read-only)

Declaration
SWIFT
var name: String { get }[/code]

So far, here is what I got.

declare function currentDevice lib "UIKit" () as Ptr soft declare function deviceName lib "UIKit" selector "name" (classRef as Ptr) as Ptr

Now I a stuck as I do not know how to go from Ptr to Text :frowning:

If something in UIKit/Cocoa/etc is declared to use a NSString, have the declare use a CFStringRef. It will then do implicit conversion to Text for you when assigned to a Text variable.

I don’t think “NAME” is what you are going to want…

Keyword : arbitrary , as in the user can change the NAME of the device to anything they want

maybe “MODEL”, but Apples doc infers it returns “iPhone” or “iPad” but not which “model” of iPhone

they seem to suggest this

but that looks like its just a more stable version of my original idea :slight_smile:

[quote=152333:@Dave S]I don’t think “NAME” is what you are going to want…

The value of this property is an arbitrary alphanumeric string that is associated with the device as an identifier. For example, you can find the name of an iOS device in the General > About settings.
Keyword : arbitrary , as in the user can change the NAME of the device to anything they want

maybe “MODEL”, but Apples doc infers it returns “iPhone” or “iPad” but not which “model” of iPhone[/quote]

The only way to really know is to try to fetch these properties and see what is actually returned.

I tried with the declares I had concocted above and a returned CFStringRef, but it crashes :frowning:

OK. I have been trying to get the famous singleton of UIDevice from which I cna have the device name, but this defintly is not it :

declare function currentDevice lib "UIKit" () as Ptr

It simply crashes. Maybe because we do not have UIDevice as type that the function is supposed to return ?

[code]Returns an object representing the current device.

Declaration
SWIFT
class func currentDevice() -> UIDevice
OBJECTIVE-C

  • (UIDevice *)currentDevice
    [/code]

If this does not work, and in spite of the good advice from our friends engineers, I am inclined to believe that using the screen resolution is a more practical way than to bump into the walls of declares…

To call a class method you have to pass the class reference itself. It crashes because you are not passing a class ref. The code should be:

declare function NSClassFromString lib "Foundation" (clsName as cfstringref) as ptr
declare function currentDevice lib "UIKit" selector "currentDevice" (clsRef as ptr) as ptr
dim currentDeviceRef as ptr = currentDevice(NSClassFromString("UIDevice"))

[quote=152707:@Jason King]To call a class method you have to pass the class reference itself. It crashes because you are not passing a class ref. The code should be:

declare function NSClassFromString lib "Foundation" (clsName as cfstringref) as ptr declare function currentDevice lib "UIKit" selector "currentDevice" (clsRef as ptr) as ptr dim currentDeviceRef as ptr = currentDevice(NSClassFromString("UIDevice")) [/quote]

Jason, you saved me from digital perdition. I did not realize I needed to pass the class ref. Thank you.

Now this works :

[code] declare function NSClassFromString lib “Foundation” (clsName as cfstringref) as ptr
declare function currentDevice lib “UIKit” selector “currentDevice” (clsRef as ptr) as ptr
dim currentDeviceRef as ptr = currentDevice(NSClassFromString(“UIDevice”))

declare function deviceName lib “UIKit” selector “model” (classRef as Ptr) as CFStringRef

dim t as text
dim c as CFStringRef
c = deviceName(currentDeviceRef)
t = c
system.DebugLog t[/code]

I have tried name, but on my iPhone 5s, all I got was the name I had given to it, “Mitch”. Model now says ‘iPhone’. Unfortunately, it does not give the precise model. Maybe one can use that as a start, and refine with the screen resolution.

It does not solve the issue of detecting 7" vs 9" iPad, though.

exactly what I said above. I don’t see anything in UIDEVICE that delinates the device other that iPhone or iPad, another reason I took the approach that I did (for now)

There is yet another approach described in
http://iphonedevsdk.com/forum/iphone-sdk-development/21423-get-the-type-of-the-iphone-programmatically.html

That uses the BSD library uname

Strange enough, the iOS dev library lists the OS X Man page
https://developer.apple.com/library/ios/documentation/System/Conceptual/ManPages_iPhoneOS/man3/uname.3.html

Now I have no idea how to declare that.

If at all possible, since it seems necessary to link a library to the code displayed at the page I posted, which is obviously not possible with Xojo.

I’m trying to restrict access to a server based on anykind of device ID, that’s why I thought about macaddress, which is the method I’m using in other platforms.
The idea is: to have a dual identification, user and device, so any user can connect using user/password to idenfity himself, but only from the devices previously allowed by the company.

The UIDevice works to solve my problem. Thanks a lot.

Did this discussion ever net out to a straightforward way to identify the device running one’s code? In my case, I just need to distinguish betwixt iPad and retina iPad. I do not speak declares.

I think at this point, your best bet is to look at the resolution of the screen.
As pointed out above it is not perfect, and will have issues when new devices are introduced
and it won’t tell the difference between an iPad Mini 2, 3 or 4 vs full size iPad as they are all the same resolution

Now my next question is… why do you need to tell the iPad2 from iPad retina?
You are dealing in Points, and both have the same number of points (762x1024), the Retina just has 2x the pixels, but there should be no need for you to “code” differently, just supply image~ipad and image~ipad@2x for your icons and such