Skip to content

Instantly share code, notes, and snippets.

@gfreezy
Last active September 23, 2022 14:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gfreezy/404484168f5b390deb617914d8751fce to your computer and use it in GitHub Desktop.
Save gfreezy/404484168f5b390deb617914d8751fce to your computer and use it in GitHub Desktop.
Copy privileges from simulator to xcode preview & copy photos from simulator to preview
"""
Use the following code in xcode preview to get the simulator path. Xcode preview does not support print or log to console.
So you need to use a `Text` view to show the path.
`
NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, .userDomainMask, true)
`
"""
import pathlib
import subprocess
import re
import sqlite3
import pathlib
def sh(cmd):
print(repr(cmd))
return subprocess.check_output(cmd, shell=True).decode("utf-8")
# use real path to replace
preview_application_path = "~/Library/Developer/Xcode/UserData/Previews/Simulator Devices/EA68C49D-0821-4491-B1FA-4BB45B712980/data/Containers/Data/Application/23C8E2B1-57DE-4FE6-AC94-99DEA017FFC5/Library/Application Support"
preview_id = re.findall(r"Previews/Simulator Devices/(.*?)/", preview_application_path)[
0
]
output = sh("xcrun simctl list | grep Booted").strip()
simulator_id = re.findall(r"\((.*?)\)", output)[0]
print(f"preview_id: {preview_id}, simulator_id: {simulator_id}")
simulator_prefix = pathlib.Path(
f"~/Library/Developer/CoreSimulator/Devices/{simulator_id}/data/"
).expanduser()
preview_prefix = pathlib.Path(
f"~/Library/Developer/Xcode/UserData/Previews/Simulator Devices/{preview_id}/data/"
).expanduser()
privacy_db = "Library/TCC/TCC.db"
simulator_privacy_db = simulator_prefix / privacy_db
preview_privacy_db = preview_prefix / privacy_db
photos_path = "Media/DCIM/100APPLE"
simulator_photos_dir = simulator_prefix / photos_path
preview_photos_dir = preview_prefix / photos_path
photos_meta_path = "Media/PhotoData"
simulator_photos_meta_dir = simulator_prefix / photos_meta_path
preview_photos_meta_dir = preview_prefix / photos_meta_path
tccs = [
"kTCCServiceMicrophone",
"kTCCServiceAppleEvents",
"kTCCServiceAddressBook",
"kTCCServiceAppleEvents",
"kTCCServiceBluetoothAlways",
"kTCCServiceCalendar",
"kTCCServiceCamera",
"kTCCServiceContactsFull",
"kTCCServiceContactsLimited",
"kTCCServiceFileProviderDomain",
"kTCCServiceFileProviderPresence",
"kTCCServiceLocation",
"kTCCServiceMediaLibrary",
"kTCCServiceMicrophone",
"kTCCServiceMotion",
"kTCCServicePhotos",
"kTCCServicePhotosAdd",
"kTCCServicePrototype3Rights",
"kTCCServicePrototype4Rights",
"kTCCServiceReminders",
"kTCCServiceScreenCapture",
"kTCCServiceSiri",
"kTCCServiceSpeechRecognition",
"kTCCServiceSystemPolicyDesktopFolder",
"kTCCServiceSystemPolicyDeveloperFiles",
"kTCCServiceSystemPolicyDocumentsFolder",
"kTCCServiceSystemPolicyDownloadsFolder",
"kTCCServiceSystemPolicyNetworkVolumes",
"kTCCServiceSystemPolicyRemovableVolumes",
"kTCCServiceSystemPolicySysAdminFiles",
"kTCCServiceWillow",
"kTCCServiceSystemPolicyAllFiles",
"kTCCServicePostEvent",
"kTCCServiceListenEvent",
"kTCCServiceDeveloperTool",
"kTCCServiceLiverpool",
"kTCCServiceUbiquity",
"kTCCServiceShareKit",
"kTCCServiceLinkedIn",
"kTCCServiceTwitter",
"kTCCServiceFacebook",
"kTCCServiceSinaWeibo",
"kTCCServiceTencentWeibo",
]
def safe(path: pathlib.Path):
return str(path).replace(" ", "\\ ")
def sync_privacy_rows_from_simulator_to_preview(simulator: str, preivew: str):
conn = sqlite3.connect(simulator)
c = conn.cursor()
tcc_conditions = ",".join(map(lambda t: f'"{t}"', tccs))
c.execute(f"SELECT * FROM access WHERE service in ({tcc_conditions})")
rows = c.fetchall()
conn.close()
# print(rows)
conn = sqlite3.connect(preivew)
c = conn.cursor()
c.execute(f"DELETE FROM access WHERE service in ({tcc_conditions})")
c.executemany(
"INSERT INTO access VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", rows
)
conn.commit()
conn.close()
def sync_photos_from_simulator_to_preview():
sh(
f"rm -rf {safe(preview_photos_dir)} && cp -r {safe(simulator_photos_dir)} {safe(preview_photos_dir)}"
)
sh(
f"rm -rf {safe(preview_photos_meta_dir)} && cp -r {safe(simulator_photos_meta_dir)} {safe(preview_photos_meta_dir)}"
)
sync_privacy_rows_from_simulator_to_preview(simulator_privacy_db, preview_privacy_db)
sync_photos_from_simulator_to_preview()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment