1

I've looked online in many places on trying to obtain the Bluetooth MAC Address of my Macbook Air. Everything I've stumbled upon has only been based towards iOS development and nothing towards the macOS field. Everything else says it has been depreciated past iOS 7, so I don't know if it would be possible on the latest Mac operating system. Does anyone know if it is possible under any framework? I'm not looking to submit this to the App Store.

Dylan
  • 823
  • 2
  • 9
  • 33

2 Answers2

0

The best option I could find for obtaining the Bluetooth MAC Address from a macOS app with Swift revolves around executing a terminal command and then formatting the output.

It would just be a matter of specifying the launchPath of networksetup & using the flag listallhardwareports to obtain an output.

Community
  • 1
  • 1
  • I've reconsidered using this information as of now, but this does seem the most logical when trying to obtain the address. Thanks anyways! – Dylan Oct 19 '16 at 17:48
  • @dylan - No problem, sorry I couldn't be of more help. I was originally going to suggest importing `C` code into `Swift` to use [this](https://developer.apple.com/library/prerelease/content/samplecode/GetPrimaryMACAddress/Introduction/Intro.html) - but obviously that's not the MAC address you're looking for. Doesn't seem they have a Bluetooth version implemented yet. –  Oct 19 '16 at 17:53
  • I was able to get the output, as follows: `Ethernet Address: 00:00:00:00:00:00 (Hardware Port: Bluetooth PAN)`. How can I only subject my output to the address rather than the information with the hardware port and stating "Ethernet Address:" beforehand. Thanks! @MattGalaxy – Dylan Nov 02 '16 at 15:02
  • If encasing the `shell` function call with `readLine` doesn't allow you to capture the output from the command- I'd suggest trying implement a [pipe](https://developer.apple.com/reference/foundation/pipe) (perhaps using the code I linked to in my answer as an example?) Glad I can help though :) –  Nov 02 '16 at 15:57
  • I actually changed mine over to yours in this time, I'm just trying to figure out how to remove the beginning. I can remove the end characters, just nothing before the address. @MattGalaxy – Dylan Nov 02 '16 at 16:01
  • If you're using `substring`, you should be specifying a `range` where the start index is where the first 0 is & the end index is whatever offset you've used to cut the end off –  Nov 02 '16 at 16:25
  • My mind is in a bit of a wrap about this, if I saw how it was wrote out I would probably understand what makes it work, lol. @MattGalaxy – Dylan Nov 02 '16 at 16:34
  • Sorry! On mobile, but I should've linked an answer like [this one](http://stackoverflow.com/a/33733593/6836841). –  Nov 02 '16 at 16:37
  • `startIndex` should be offset to the first 0, & `endIndex` would be that plus the length of a MAC (11) –  Nov 02 '16 at 16:41
  • My start ended up as 18 and end was 34. But I still managed to get the output I liked, thanks! – Dylan Nov 02 '16 at 16:43
  • Okay, last question while I'm here. I defined it as a function with the variables inside, if I need to access them anywhere else in the file do I need to store them outside of the function? Thanks. @MattGalaxy – Dylan Nov 02 '16 at 16:51
  • Test it out! But you're correct. Variables only exist within the scope they're declared in with Swift. –  Nov 02 '16 at 16:58
  • Would you mind if I provide the answer in full and accept that one instead? @MattGalaxy – Dylan Dec 02 '16 at 22:19
  • I mentioned you in the answer. @MattGalaxy – Dylan Dec 03 '16 at 09:24
0

Using a Bash Script

I'd like to thank @MattGalaxy for the suggestion and the assistance shown in the comments below under his answer. Eventually, it all worked out well and here's how I pulled this off. This can work in a Playground or in a macOS application you are building with Xcode.

Here's the code to go along with it:

 import Foundation
 let task = Process()
 task.launchPath = "/usr/bin/env"
 task.arguments = ["networksetup", "-getmacaddress", "en2"]
 let pipe = Pipe()
 task.standardOutput = pipe
 task.standardError = pipe
 task.launch()
 task.waitUntilExit()
 let data = pipe.fileHandleForReading.readDataToEndOfFile()
 let output: String = NSString(data: data, encoding: String.Encoding.utf8.rawValue) as! String

The original was this:

Ethernet Address: XX:XX:XX:XX:XX:XX (Device: en2)

This does say Ethernet address, however, the device en2 is specifically used for Bluetooth, so all this captures is that.

I set the variable bluetoothAddress equal to the output above.

var bluetoothAddress = output

And then just played around until I was able to crunch only the address between these.

let startIndex = bluetoothAddress.index(bluetoothAddress.startIndex, offsetBy: 18)
let endIndex = bluetoothAddress.index(bluetoothAddress.startIndex, offsetBy: 34)
bluetoothAddress = bluetoothAddress[startIndex...endIndex]

And then finally, giving off the output I was requesting for originally in the question:

XX:XX:XX:XX:XX:XX

(Keep in mind, I used placeholder XX's throughout this answer to keep my privacy :P)

Dylan
  • 823
  • 2
  • 9
  • 33