2

It looks like there aren't any documented official methods of obtaining the Apple Watch model from a watch app, but there is this post showing special use of sysctlbyname:

How to determine the Apple Watch model?

Could anyone help me figure out why this function isn't working? It sometimes returns

"Watc\t"

instead of the expected

"Watch2,4"

Swift's sysctlbyname function seems to be this c function described here: https://opensource.apple.com/source/Libc/Libc-167/gen.subproj/sysctlbyname.c.auto.html

My code is copied from the swift answer in the SO post:

private func getWatchModel() -> String? {
   var size: size_t = 0
   sysctlbyname("hw.machine", nil, &size, nil, 0)
   var machine = CChar()
   sysctlbyname("hw.machine", &machine, &size, nil, 0)
   return String(cString: &machine, encoding: String.Encoding.utf8)?.trimmingCharacters(in: .whitespacesAndNewlines)
} // Should return a string like "Watch2,4"
idz
  • 12,825
  • 1
  • 29
  • 40
TealShift
  • 842
  • 5
  • 19
  • It'd probably be useful to see your code. Does it work on macOS? If not, it's probably easier to debug on macOS than on watchOS. – nneonneo Oct 21 '20 at 01:35
  • 1
    Also, your mention of "sometimes" makes me think that maybe you're misusing the buffer somehow - either freeing the buffer prematurely, or not allocating enough space for it. – nneonneo Oct 21 '20 at 01:42
  • @nneonneo Those are good thoughts. I have not tried testing on another platform. And I have added my code to the post (same as the code from from the linked SO post). – TealShift Oct 21 '20 at 16:15
  • Honestly, I am not very familiar with how the buffer *could* be misused here and have trusted the original author. Would be very interesting to gain some insight though. – TealShift Oct 21 '20 at 16:17

1 Answers1

4

You never allocate a buffer to receive the machine string. Change

var machine = CChar()

to

var machine = [CChar](repeating: 0, count: size) 

and you should be good to go!

idz
  • 12,825
  • 1
  • 29
  • 40
  • Nice! This makes sense. I'm testing this now, but might take a while for me to confirm it does the trick and I can approve your answer. Thanks! I should however point out this particular code doesn't compile... I changed it to Array(repeating... – TealShift Oct 21 '20 at 20:08
  • 1
    Whoops, typo! Will update! Should be `[CChar](repeating: 0, count: size) ` or `Array...` as you point out. – idz Oct 21 '20 at 20:14
  • Thanks for the solution. On simulator, it gives the Mac Machine. Is there anyway to test this on simulator ? – claude31 Nov 04 '21 at 09:43
  • @claude31 I don't know of anyway (short of mocking out the call) to test it on the simulator. – idz Nov 04 '21 at 17:22
  • Thanks, that's what I thought. In an app, I needed to detect if watch 7 (because of insets modifications). I finally used the screen bounds size to test it it is Watch 7 or not. – claude31 Nov 05 '21 at 12:07