AppleScriptから住所ジオコーダー/逆住所ジオコーダーの機能にアクセスして日常的に利用していますが、セキュリティ機能の強化によって旧来の機能にアクセスできなくなりつつあります。
住所ジオコーダー系の機能については、さまざまな方法でアクセスできるようにしてきましたが、どうやらmacOS 27あたりでさらにセキュリティ縛りがきつくなることが想定されます。
さまざまな方法を検討した結果、
・SwiftでCLIツールを作ってAppleScriptバンドル内に入れてdo shell scriptコマンドで呼び出す
これは実際にNFCタグの操作Scriptを作った際に試した方法です。問題はないのですが、これだと実行できないAppleScriptの実行環境もあるので、なるべく1つのAppleScript内で完結したいところです。
・AppleScript内に文字列でSwiftのプログラムを記述し、do shell scriptコマンド経由で「swift」(/usr/bin/swift)を呼び出して実行させる
今回はこれを採用してみました。AppleScript実行プログラム側のセキュリティ設定次第ですが、環境を選ばずに実行できるはずです。なお、Script Debugger上では動作しません。
| AppleScript名:住所から緯度、経度を返す(Swift版).scpt |
| — – Created by: Takaaki Naganoya – Created on: 2026/03/16 — – Copyright © 2026 Piyomaru Software, All Rights Reserved — set myAddress to "東京都新宿区西新宿2丁目8−1" set gRes to my geocode(myAddress) set {aLat, Along} to parseByDelim(gRes, "|") of me –> {"35.6894863", "139.6917052"} on geocode(addressString) set swiftSource to " import CoreLocation import Foundation let address = \"$TARGET$\" geocoder.geocodeAddressString(address) { placemarks, error in resultString = \"\\(loc.coordinate.latitude)|\\(loc.coordinate.longitude)\" } else { resultString = \"Error: \\(error?.localizedDescription ?? \"Unknown\")\" } completed = true } // 5秒間、結果を待機しながらランループを回す } print(resultString) return my runSwift(swiftSource, addressString) end geocode on runSwift(source, targetValue) set finalCode to my replaceText("$TARGET$", targetValue, source) try — ヒアドキュメントで実行 return do shell script "swift – <<’EOF’" & return & finalCode & return & "EOF" on error errMsg return "実行エラー: " & errMsg end try end runSwift on replaceText(s, r, t) set AppleScript’s text item delimiters to s set textItems to every text item of t set AppleScript’s text item delimiters to r set res to textItems as string set AppleScript’s text item delimiters to "" return res end replaceText on parseByDelim(aData, aDelim) set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to aDelim set dList to text items of aData set AppleScript’s text item delimiters to curDelim return dList end parseByDelim |
| AppleScript名:緯度経度から住所を返す(Swift版).scpt |
| — – Created by: Takaaki Naganoya – Created on: 2026/03/16 — – Copyright © 2026 Piyomaru Software, All Rights Reserved — — サンプル座標(東京都庁付近) set myCoords to "35.6894863|139.6917052" set gRes to my reverseGeocode(myCoords) –> "東京都新宿区東京都庁" ——————————————————— — ハンドラ: 緯度|経度 -> 住所 ——————————————————— on reverseGeocode(latLonString) set swiftSource to " import CoreLocation import Foundation let input = \"$TARGET$\" guard parts.count == 2, let lon = Double(parts[1].trimmingCharacters(in: .whitespaces)) else { print(\"Error: Invalid input format\") exit(1) } let location = CLLocation(latitude: lat, longitude: lon) geocoder.reverseGeocodeLocation(location) { placemarks, error in // 都道府県 + 市区町村 + 地番・ビル名などを結合 let addr = \"\\(p.administrativeArea ?? \"\")\\(p.locality ?? \"\")\\(p.name ?? \"\")\" resultString = addr } else { resultString = \"Error: \\(error?.localizedDescription ?? \"Unknown\")\" } completed = true } // 5秒間、結果が返るまでランループを回す } print(resultString) return my runSwift(swiftSource, latLonString) end reverseGeocode ——————————————————— — Swift実行サブシステム ——————————————————— on runSwift(source, targetValue) set finalCode to my replaceText("$TARGET$", targetValue, source) try — ファイルを作らず標準入力から実行 return do shell script "swift – <<’EOF’" & return & finalCode & return & "EOF" on error errMsg return "Error: " & errMsg end try end runSwift on replaceText(s, r, t) set AppleScript’s text item delimiters to s set textItems to every text item of t set AppleScript’s text item delimiters to r set res to textItems as string set AppleScript’s text item delimiters to "" return res end replaceText |
