From ce43154c474dd1f0a28017e198d940e8cab32fde Mon Sep 17 00:00:00 2001 From: Vladimir Ryabtsev Date: Sun, 30 Nov 2025 22:33:01 -0800 Subject: [PATCH 1/4] Improve Readme: - Progress bar - Creating backups - New options --- .gitignore | 1 + README.md | 43 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 7158f2c..fd9e9fe 100644 --- a/.gitignore +++ b/.gitignore @@ -213,3 +213,4 @@ __marimo__/ .scratches/ tests/.data/ test-results/ +src/ios_backup/_version.py diff --git a/README.md b/README.md index 960a44c..3de3c73 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,8 @@ python -m ios_backup export \ [--domain ] \ [--namespace ] \ [--path ] \ - [--restore-modified-dates] + [--restore-dates] + [--restore-symlinks] [--ignore-missing] ``` @@ -61,7 +62,11 @@ All values are interpreted as prefixes, full match is not required. database, but not present in the backup). Useful for incomplete or corrupted backups. `--restore-dates` – restore dates and times of files as they were on -the original device. +the original device. + +`--restore-symlinks` – restore symbolic links from backup. This has questionable +value, as links will point to non-existent locations on your system, but may be +useful for research purposes. ## Advanced usage @@ -89,7 +94,7 @@ query = """ """ content = Backup.parse(db.buffered_query(query), parse_metadata=True) -backup.export(content, 'tests/.data/exported_videos', restore_modified_dates=True) +backup.export(content, 'path/to/exported_videos', restore_modified_dates=True) ``` Process specific files based on query: @@ -122,6 +127,12 @@ for record in Backup.parse(rows): # Do something with the data. ``` +## Progress bar + +Export usually runs quite fast on SSD storage, but may take longer on HDDs. +To get a sense of progress, you can install [tqdm](https://github.com/tqdm/tqdm) module. If tqdm is found in the executing Python environment and if `total_count` is provided to `Backup.export()` (true for CLI use), it will be +used to produce a progress bar in the terminal interface. + ## Relation to `unback()` iOS function Unback function was broken by Apple at around version 10 of iOS, and hence @@ -133,3 +144,29 @@ While this module does not provide 100% equivalemnt of `unback()`'s output, it does an honest export of entire backup content and will suit for cases when you need to browse the content or simply extract photos, videos, or other applications' files. + +## Creating backups + +### MacOS +- Connect device with a USB cable. +- If connecting first time, click "Allow" in the pop-up window, tap "Trust" on the device and enter your passcode. +- Open Finder and select your device on the side panel. +- Click "Back Up Now" on "General" tab. +- Click on the option to **not** encrypt the backup as the module does not support encrypted backups. + +### Windows +- Download and install the Apple Devices app from the Microsoft Store. +- Connect your device to your PC with a USB or USB-C cable. +- If prompted, tap "Trust" on your device and enter your passcode. +- Open the Apple Devices app and select your device from the sidebar. +- Click "Backup" in the "Backups" section. +- Do not select the option for encryption as the module does not support encrypted backups. +- Click "Back Up Now". + +### Linux/Unix/MacOS/* +- Install [libimobiledevice](https://libimobiledevice.org/) libraries according to the project's instructions. +- Connect the device with a USB cable. +- Run `idevicebackup2 backup --full /path/to/your/backup/folder` +- Tap "Trust" on the device and enter passcode when prompted. + +* Libraries are cross-platform, although on MacOS and Windows there are more user-friendly options. From 0fa66e10e2d49313d0ab98d0394fa1b7d5d2b9d7 Mon Sep 17 00:00:00 2001 From: Vladimir Ryabtsev Date: Sun, 30 Nov 2025 23:13:52 -0800 Subject: [PATCH 2/4] More about the DB --- README.md | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 3de3c73..a089fd4 100644 --- a/README.md +++ b/README.md @@ -18,9 +18,7 @@ content, they use Apple's private API that can be discontinued at any point. Syntax: ```bash -python -m ios_backup export \ - --backup-path \ - --output-path \ +python -m ios_backup export \ [--domain ] \ [--namespace ] \ [--path ] \ @@ -29,14 +27,10 @@ python -m ios_backup export \ [--ignore-missing] ``` - ### Export entire backup -```bash -% python -m ios_backup export \ - --backup-path iosbackup/path \ - --output-path export/path \ - --restore-dates +```shell +python -m ios_backup export iosbackup/path export/path --restore-dates ``` ### Filtering @@ -47,19 +41,24 @@ Each file in an iOS backup has the following attributes: for example, `AppDomain`, `CameraRollDomain`. - Namespace: a level of hierarchy under the domain. For example, content of applications will live in `AppDomain` will have namespaces such as `com.mojang.minecraftpe` or `com.apple.iBooks`. -- Relative path: path in the application's directory. +- Relative path: path in the application's sandbox. When exporting the backup, these attributes form a directory tree with layers in the above order, for example, `AppDomain/com.mojang.minecraftpe/Documents/games/com.mojang/Screenshots`. If you need to export only specific content, you can achive that with filtering keys: -`% ... --domain AppDomain --namespace com.mojang.minecraftpe --path Documents/games/com.mojang/minecraftWorlds` +```shell +python -m ios_backup export \ + --domain AppDomain \ + --namespace com.mojang.minecraftpe \ + --path Documents/games/com.mojang/minecraftWorlds +``` All values are interpreted as prefixes, full match is not required. ### Other options `--ignore-missing` – do not fail on missing files (those defined in the -database, but not present in the backup). Useful for incomplete or corrupted backups. +database, but not present in the backup). Useful for incomplete or corrupted backups. Try it if you experience problems. `--restore-dates` – restore dates and times of files as they were on the original device. @@ -74,7 +73,7 @@ useful for research purposes. The below example shows how to use a custom query to process backup content. -Create Backup object and obtain the DB: +In a Python script, create a Backup object and obtain the DB: ```python from ios_backup import Backup @@ -84,6 +83,24 @@ backup = Backup(backup_path) db = backup.db ``` +Use an SQLite client/browser to explore content of Manifest.db. IDEs like +PyCharm and VS Code have built-in modules or extensions for that, or you +can use [SQLite shell](https://sqlite.org/cli.html) for CLI experience. +There is simply a single table: + +```sql +CREATE TABLE Files ( + fileID TEXT PRIMARY KEY, + domain TEXT, + relativePath TEXT, + flags INTEGER, + file BLOB +); +``` + +After you realized your specific needs, you can export your slice of content +or process it in other way. + Export content based on a specific query: ```python From 6870bd50af314497b89c570a86f375bb1350a395 Mon Sep 17 00:00:00 2001 From: Vladimir Ryabtsev Date: Sun, 30 Nov 2025 23:18:57 -0800 Subject: [PATCH 3/4] Minor --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a089fd4..a2fb3d8 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,8 @@ query = """ where domain = 'CameraRollDomain' and relativePath like 'Media/DCIM/%.MOV' """ -content = Backup.parse(db.buffered_query(query), parse_metadata=True) +raw_content = db.buffered_query(query) +content = Backup.parse(raw_content, parse_metadata=True) backup.export(content, 'path/to/exported_videos', restore_modified_dates=True) ``` From 145942cdd7020bdf0a76e6092baf69c572b3f4fc Mon Sep 17 00:00:00 2001 From: Vladimir Ryabtsev Date: Sun, 30 Nov 2025 23:26:51 -0800 Subject: [PATCH 4/4] Minor --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a2fb3d8..22d0b15 100644 --- a/README.md +++ b/README.md @@ -185,6 +185,6 @@ applications' files. - Install [libimobiledevice](https://libimobiledevice.org/) libraries according to the project's instructions. - Connect the device with a USB cable. - Run `idevicebackup2 backup --full /path/to/your/backup/folder` -- Tap "Trust" on the device and enter passcode when prompted. +- Tap "Trust" on the device and enter the passcode when prompted. -* Libraries are cross-platform, although on MacOS and Windows there are more user-friendly options. +*Libraries are cross-platform, although on MacOS and Windows you may find the "official" tools more user-friendly.