Skip to content

Commit

Permalink
Ask for Location Services on macOS 14 Sonoma and Later (due to the ch…
Browse files Browse the repository at this point in the history
…ange made by Apple)
  • Loading branch information
nolze committed Oct 29, 2023
1 parent b145cab commit 27718da
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 6 deletions.
1 change: 1 addition & 0 deletions Tiny Wi-Fi Analyzer.spec
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,6 @@ app = BUNDLE(
"CFBundleShortVersionString": "0.2.0",
"CFBundleVersion": "0.2.0",
"NSHighResolutionCapable": True,
"NSLocationWhenInUseUsageDescription": "On macOS 14 Sonoma and Later, Location Services permission is required to get Wi-Fi SSIDs.",
},
)
19 changes: 18 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pyobjc-core = "~10.0"
pyobjc-framework-cocoa = "~10.0"
pyobjc-framework-CoreWLAN = "~10.0"
pyobjc-framework-WebKit = "~10.0"
pyobjc-framework-corelocation = "^10.0"

[tool.poetry.dev-dependencies]
pyinstaller = "^5.13"
Expand Down
71 changes: 66 additions & 5 deletions tiny_wifi_analyzer/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,20 @@
import logging
import os.path
import queue
import stat
import threading
from time import sleep

# NOTE: https://github.com/r0x0r/pywebview/issues/496
from objc import super, nil, registerMetaDataForSelector # pylint: disable=unused-import # noqa F401

from objc import (
super,
nil,
registerMetaDataForSelector,
) # pylint: disable=unused-import # noqa F401

import AppKit
import Foundation
import CoreLocation
import CoreWLAN
import webview

Expand All @@ -32,8 +40,10 @@ def __init__(self, channel):
self.channel_width = channel.channelWidth()

def __repr__(self):
return "<CWChannel> [channel_band={}, channel_number={}, channel_width={}]".format(
self.channel_band, self.channel_number, self.channel_width
return (
"<CWChannel> [channel_band={}, channel_number={}, channel_width={}]".format(
self.channel_band, self.channel_number, self.channel_width
)
)


Expand Down Expand Up @@ -133,8 +143,59 @@ def on_closing():
is_closing = True


class LocationManagerDelegate(AppKit.NSObject):
def locationManagerDidChangeAuthorization_(self, manager):
status = manager.authorizationStatus()
if status in [
CoreLocation.kCLAuthorizationStatusDenied,
CoreLocation.kCLAuthorizationStatusNotDetermined,
]:
self.show_dialog()

def show_dialog(self):
alert = AppKit.NSAlert.alloc().init()
alert.setMessageText_(f"Location Services are disabled")
alert.setInformativeText_(
"On macOS 14 Sonoma and Later, Location Services permission is required to get Wi-Fi SSIDs.\n"
+ "Please enable Location Services in System Preferences > Security & Privacy > Privacy > Location Services."
)
alert.addButtonWithTitle_("Open Preferences")
alert.addButtonWithTitle_("OK")
response = alert.runModal()
if response == AppKit.NSAlertFirstButtonReturn:
AppKit.NSWorkspace.sharedWorkspace().openURL_(
Foundation.NSURL.URLWithString_(
"x-apple.systempreferences:com.apple.preference.security?Privacy_LocationServices"
)
)
AppKit.NSApplication.sharedApplication().terminate_(None)


def request_location_permission():
location_manager = CoreLocation.CLLocationManager.alloc().init().retain()
delegate = LocationManagerDelegate.alloc().init().retain()
location_manager.setDelegate_(delegate)
# location_manager.delegate()
# location_manager.startUpdatingLocation()
location_manager.requestWhenInUseAuthorization()
for i in range(100):
status = location_manager.authorizationStatus()
if not status == 0:
break
sleep(0.01)


def main():
index_html = os.path.join(os.path.dirname(__file__), 'view/index.html')
# NOTE: Sonoma (macOS 11) and later requires location permission to read Wi-Fi SSIDs.
os_version = AppKit.NSAppKitVersionNumber
# print(os_version, AppKit.NSAppKitVersionNumber13_1)
if os_version > AppKit.NSAppKitVersionNumber13_1:
request_location_permission()

# Bring the app to the foreground
AppKit.NSApplication.sharedApplication().activateIgnoringOtherApps_(True)

index_html = os.path.join(os.path.dirname(__file__), "view/index.html")
window = webview.create_window("Tiny Wi-Fi Analyzer", index_html)
window.events.closing += on_closing
webview.start(startup, window, debug=True)
Expand Down

0 comments on commit 27718da

Please sign in to comment.