├── .github └── workflows │ └── build.yml ├── .gitignore ├── README.md ├── Tweak ├── LookinLoader.plist ├── LookinLoader.xm ├── Makefile ├── control └── layout │ └── Library │ ├── LookinLoader │ └── LookinServer │ └── PreferenceLoader │ └── Preferences │ ├── LookinLoader.plist │ ├── logo.png │ ├── logo@2x.png │ └── logo@3x.png └── UPSTREAM_COMMIT /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build LookinServer when upstream or local code changes 2 | 3 | on: 4 | push: # Trigger on push to any branch 5 | workflow_dispatch: # Manual trigger 6 | schedule: # Daily check once 7 | - cron: "0 3 * * *" # 03:00 UTC ≈ 20:00 Vancouver 8 | 9 | env: 10 | LOOKIN_DEMO_PATH: LookinDemo/OC_Pod 11 | DEMO_SCHEME: LookinDemoOC 12 | 13 | jobs: 14 | detect: 15 | runs-on: ubuntu-latest 16 | outputs: 17 | upstream_changed: ${{ steps.set.outputs.up_changed }} 18 | sha: ${{ steps.set.outputs.sha }} 19 | local_changed: ${{ steps.filter.outputs.build }} 20 | should_build: ${{ steps.set.outputs.should }} 21 | 22 | steps: 23 | - uses: actions/checkout@v4 24 | 25 | # ① Get the latest commit SHA from QMUI/LookinServer 26 | - name: Fetch upstream SHA 27 | id: upstream 28 | run: | 29 | SHA=$(git ls-remote https://github.com/QMUI/LookinServer.git refs/heads/main | cut -f1) 30 | echo "sha=$SHA" >> $GITHUB_OUTPUT 31 | 32 | # ② Path filtering: Check if local repo changed 33 | - name: Filter local changes 34 | id: filter 35 | uses: dorny/paths-filter@v3 36 | with: 37 | list-files: shell 38 | filters: | 39 | build: 40 | - 'Tweak/**' 41 | - 'Makefile' 42 | - '.github/workflows/**' 43 | 44 | # ③ Calculate the overall build flag 45 | - name: Decide build flags 46 | id: set 47 | run: | 48 | STORED=$(cat UPSTREAM_COMMIT 2>/dev/null || echo none) 49 | UP_CHANGED=false 50 | [[ "$STORED" != "${{ steps.upstream.outputs.sha }}" ]] && UP_CHANGED=true 51 | 52 | SHOULD=$([[ "$UP_CHANGED" == true || "${{ steps.filter.outputs.build }}" == 'true' ]] && echo true || echo false) 53 | 54 | echo "up_changed=$UP_CHANGED" >>$GITHUB_OUTPUT 55 | echo "sha=${{ steps.upstream.outputs.sha }}" >>$GITHUB_OUTPUT 56 | echo "should=$SHOULD" >>$GITHUB_OUTPUT 57 | 58 | build: 59 | needs: detect 60 | if: needs.detect.outputs.should_build == 'true' 61 | runs-on: macos-latest 62 | strategy: 63 | matrix: { scheme: [rootful, rootless] } 64 | 65 | env: 66 | LS_CHANGED: ${{ needs.detect.outputs.upstream_changed }} 67 | 68 | steps: 69 | - uses: actions/checkout@v4 70 | 71 | - name: Clone upstream @sha 72 | if: env.LS_CHANGED == 'true' 73 | run: | 74 | git clone --depth=1 https://github.com/QMUI/LookinServer.git upstream 75 | # Check out the exact commit for consistency 76 | cd upstream && git checkout ${{ needs.detect.outputs.sha }} 77 | 78 | - name: Install CocoaPods & pod install 79 | if: env.LS_CHANGED == 'true' 80 | uses: maxim-lobanov/setup-cocoapods@v1 81 | with: 82 | version: latest 83 | 84 | - name: pod install (LookinDemo) 85 | if: env.LS_CHANGED == 'true' 86 | working-directory: upstream/${{ env.LOOKIN_DEMO_PATH }} 87 | run: pod install 88 | 89 | - name: xcodebuild archive LookinDemoOC 90 | if: env.LS_CHANGED == 'true' 91 | working-directory: upstream/${{ env.LOOKIN_DEMO_PATH }} 92 | run: | 93 | xcodebuild archive \ 94 | -workspace "${{ env.DEMO_SCHEME }}.xcworkspace" \ 95 | -scheme "${{ env.DEMO_SCHEME }}" \ 96 | -configuration Release \ 97 | -sdk iphoneos \ 98 | -destination 'generic/platform=iOS' \ 99 | BUILD_LIBRARIES_FOR_DISTRIBUTION=YES \ 100 | SKIP_INSTALL=NO \ 101 | CODE_SIGNING_ALLOWED=NO \ 102 | CODE_SIGNING_REQUIRED=NO \ 103 | CODE_SIGN_IDENTITY="" \ 104 | -archivePath build/${{ env.DEMO_SCHEME }}.xcarchive 105 | 106 | - name: Copy LookinServer binary 107 | if: env.LS_CHANGED == 'true' 108 | run: | 109 | SRC=upstream/${{ env.LOOKIN_DEMO_PATH }}/build/${{ env.DEMO_SCHEME }}.xcarchive/Products/Applications/${{ env.DEMO_SCHEME }}.app/Frameworks/LookinServer.framework/LookinServer 110 | test -f "$SRC" || { echo "Binary not found"; exit 1; } 111 | cp -f "$SRC" Tweak/layout/Library/LookinLoader/LookinServer 112 | 113 | - name: Cache Theos 114 | uses: actions/cache@v3 115 | with: 116 | path: theos 117 | key: ${{ runner.os }}-theos-${{ hashFiles('**/Makefile') }} 118 | restore-keys: ${{ runner.os }}-theos- 119 | 120 | - uses: Randomblock1/theos-action@v1 121 | - name: Configure Theos env 122 | run: | 123 | echo "ARCHS=arm64 arm64e" >> $GITHUB_ENV 124 | if [[ "${{ matrix.scheme }}" == "rootless" ]]; then 125 | echo "THEOS_PACKAGE_SCHEME=rootless" >> $GITHUB_ENV 126 | fi 127 | 128 | - name: make package 129 | run: make -C Tweak clean package FINALPACKAGE=1 130 | 131 | - uses: actions/upload-artifact@v4 132 | with: 133 | name: ${{ matrix.scheme }}-deb 134 | path: Tweak/packages/*.deb 135 | 136 | - name: Commit updated LookinServer + SHA 137 | if: env.LS_CHANGED == 'true' && matrix.scheme == 'rootless' 138 | run: | 139 | echo "${{ needs.detect.outputs.sha }}" > UPSTREAM_COMMIT 140 | git config user.name github-actions 141 | git config user.email github-actions@github.com 142 | git add UPSTREAM_COMMIT Tweak/layout/Library/LookinLoader/LookinServer 143 | git commit -m "chore: update LookinServer to ${{ needs.detect.outputs.sha }}" 144 | git push 145 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | packages 2 | .DS_Store 3 | .theos 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LookinLoader, a Tweak for LookinSever 2 | 3 | LookinLoader lets you choose specific applications where you want to observe the view hierarchy via LookinServer. 4 | It uses the AltList library for app selection within the Settings pane (loaded by PreferenceLoader), replacing the older AppList. 5 | Download the correct `.deb` package from the [Action page](https://github.com/retX0/LookinLoader/actions): install the rootful version for rootful jailbreaks, or the rootless version for rootless jailbreaks. 6 | For further information about Lookin itself, please visit the official website: http://lookin.work. 7 | 8 | References: 9 | 1. [Reveal-Loader](https://github.com/jkyin/Reveal-Loader) 10 | 2. [Lookin](https://lookin.work/) 11 | 3. [AltList](https://github.com/opa334/AltList/) 12 | 13 | -------------------------------------------------------------------------------- /Tweak/LookinLoader.plist: -------------------------------------------------------------------------------- 1 | { Filter = { Bundles = ( "com.apple.UIKit",); }; } 2 | -------------------------------------------------------------------------------- /Tweak/LookinLoader.xm: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------- 2 | // LookinLoader.xm – single source compatible with rootful & rootless 3 | // ----------------------------------------------------------- 4 | // • Uses ROOT_PATH_NS when is present (rootless build). 5 | // • Falls back to plain paths when building rootful. 6 | // ----------------------------------------------------------- 7 | 8 | #include 9 | #include 10 | 11 | // Conditionally include (only present when building rootless). 12 | #if __has_include() 13 | #import 14 | #define LL_PATH(p) ROOT_PATH_NS(p) // /var/jb/... at runtime 15 | #else 16 | #define LL_PATH(p) @(p) // direct path for rootful 17 | #endif 18 | 19 | 20 | %ctor { 21 | @autoreleasepool { 22 | NSLog(@"[LookinLoader] Skipping injection into SpringBoard"); 23 | 24 | NSString *bundleID = [[NSBundle mainBundle] bundleIdentifier]; 25 | if ([bundleID isEqualToString:@"com.apple.springboard"]) { 26 | return; 27 | } 28 | 29 | BOOL enabled = NO; 30 | NSString *globalPrefsPath = @"/var/mobile/Library/Preferences/dev.ret0.lookinloader.plist"; 31 | NSDictionary *prefsDict = [NSDictionary dictionaryWithContentsOfFile:globalPrefsPath]; 32 | NSArray *enabledApps = [prefsDict objectForKey:@"enabledApps"]; 33 | 34 | if (enabledApps && [enabledApps containsObject:bundleID]) { 35 | enabled = YES; 36 | } 37 | 38 | if (!enabled) { 39 | return; 40 | } 41 | 42 | NSString *libPath = LL_PATH(@"/Library/LookinLoader/LookinServer"); 43 | if ([[NSFileManager defaultManager] fileExistsAtPath:libPath]) { 44 | dlopen(libPath.UTF8String, RTLD_NOW); 45 | NSLog(@"[LookinLoader] Loaded %@", libPath); 46 | } else { 47 | NSLog(@"[LookinLoader] Library not found at %@", libPath); 48 | } 49 | } 50 | } 51 | 52 | -------------------------------------------------------------------------------- /Tweak/Makefile: -------------------------------------------------------------------------------- 1 | # ----------------------------------------------------------- 2 | # LookinLoader – Theos build configuration (rootful + rootless) 3 | # ----------------------------------------------------------- 4 | # Usage examples 5 | # make package # ➜ rootful (Architecture: iphoneos-arm) 6 | # make package ROOTLESS=1 # ➜ rootless (Architecture: iphoneos-arm64) 7 | # ----------------------------------------------------------- 8 | 9 | ROOTLESS ?= 0 # 0 = rootful │ 1 = rootless 10 | 11 | # ─── Packaging scheme & arch label ───────────────────────── 12 | ifeq ($(ROOTLESS),1) 13 | THEOS_PACKAGE_SCHEME = rootless # /var/jb layout 14 | PACKAGE_ARCH := iphoneos-arm64 15 | else 16 | PACKAGE_ARCH := iphoneos-arm 17 | endif 18 | export PACKAGE_ARCH # pass to sub‑makes/env 19 | 20 | # ─── Build target & flags ───────────────────────────────── 21 | ARCHS = arm64 arm64e # 64‑bit only 22 | TARGET = iphone:clang:latest:14.0 # iOS 14+ is safe for rootful 23 | ifeq ($(THEOS_PACKAGE_SCHEME),rootless) 24 | TARGET = iphone:clang:latest:15.0 # iOS 15+ needed by rootless 25 | endif 26 | 27 | include $(THEOS)/makefiles/common.mk 28 | 29 | TWEAK_NAME = LookinLoader 30 | LookinLoader_FILES = LookinLoader.xm 31 | 32 | include $(THEOS_MAKE_PATH)/tweak.mk 33 | 34 | # ─── Inject the correct Architecture into control ───────── 35 | # We keep a template named "control.in" with a placeholder. 36 | # before‑package is the last hook before dpkg-deb runs. 37 | 38 | before-package:: gen-control sign-lookinserver 39 | 40 | LOOKIN_SRC := layout/Library/LookinLoader/LookinServer 41 | LOOKIN_DST := $(if $(filter $(THEOS_PACKAGE_SCHEME),rootless),\ 42 | $(THEOS_STAGING_DIR)/var/jb/Library/LookinLoader,\ 43 | $(THEOS_STAGING_DIR)/Library/LookinLoader) 44 | 45 | sign-lookinserver: 46 | @echo "[build] › preparing LookinServer …" 47 | @mkdir -p $(LOOKIN_DST) 48 | @cp -f $(LOOKIN_SRC) $(LOOKIN_DST)/ 49 | @ldid -e $(LOOKIN_DST)/LookinServer >/dev/null 2>&1 || \ 50 | { echo "[build] › ad-hoc signing LookinServer"; \ 51 | ldid -S $(LOOKIN_DST)/LookinServer; } 52 | 53 | gen-control: 54 | @echo "[build] > Writing Architecture $(PACKAGE_ARCH) into DEBIAN/control" 55 | @sed 's/^Architecture:.*/Architecture: $(PACKAGE_ARCH)/' control > $(THEOS_STAGING_DIR)/DEBIAN/control 56 | 57 | # ─── Post‑install helper ────────────────────────────────── 58 | after-install:: 59 | install.exec "killall -9 SpringBoard" 60 | 61 | -------------------------------------------------------------------------------- /Tweak/control: -------------------------------------------------------------------------------- 1 | Package: dev.ret0.lookinloader 2 | Name: LookinLoader 3 | Depends: mobilesubstrate (>= 0.9.5000), preferenceloader (>= 2.2.3), com.opa334.altlist (>=1.0.11) 4 | Version: 1.1 5 | Architecture: iphoneos-arm 6 | Description: Lookin Loader – see https://github.com/retX0/LookinLoader for details. 7 | Maintainer: retX0 8 | Author: retX0 9 | Section: Tweaks 10 | -------------------------------------------------------------------------------- /Tweak/layout/Library/LookinLoader/LookinServer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/retX0/LookinLoader/f67e3d42807e5d3258b13b742e64e78722f85de6/Tweak/layout/Library/LookinLoader/LookinServer -------------------------------------------------------------------------------- /Tweak/layout/Library/PreferenceLoader/Preferences/LookinLoader.plist: -------------------------------------------------------------------------------- 1 | { 2 | entry = { 3 | cell = PSLinkCell; 4 | label = Lookin; 5 | icon = "logo.png"; 6 | 7 | items = ( 8 | { 9 | bundle = AltList; 10 | cell = PSLinkListCell; 11 | detail = ATLApplicationListMultiSelectionController; 12 | overridePrincipalClass = 1; 13 | isController = 1; 14 | 15 | defaults = "dev.ret0.lookinloader"; 16 | key = "enabledApps"; 17 | 18 | label = "Enabled Applications"; 19 | 20 | useSearchBar = 1; 21 | hideSearchBarWhileScrolling = 1; 22 | defaultApplicationSwitchValue = 0; 23 | showIdentifiersAsSubtitle = 1; 24 | 25 | sections = ( 26 | { 27 | sectionType = User; 28 | }, 29 | { 30 | sectionType = System; 31 | }, 32 | ); 33 | }, 34 | { 35 | cell = PSGroupCell; 36 | footerText = "This tweak is not officially supported. For more information about Lookin.app and runtime debugging see https://lookin.work"; 37 | }, 38 | { 39 | cell = PSGroupCell; 40 | footerText = ""; 41 | }, 42 | ); 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /Tweak/layout/Library/PreferenceLoader/Preferences/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/retX0/LookinLoader/f67e3d42807e5d3258b13b742e64e78722f85de6/Tweak/layout/Library/PreferenceLoader/Preferences/logo.png -------------------------------------------------------------------------------- /Tweak/layout/Library/PreferenceLoader/Preferences/logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/retX0/LookinLoader/f67e3d42807e5d3258b13b742e64e78722f85de6/Tweak/layout/Library/PreferenceLoader/Preferences/logo@2x.png -------------------------------------------------------------------------------- /Tweak/layout/Library/PreferenceLoader/Preferences/logo@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/retX0/LookinLoader/f67e3d42807e5d3258b13b742e64e78722f85de6/Tweak/layout/Library/PreferenceLoader/Preferences/logo@3x.png -------------------------------------------------------------------------------- /UPSTREAM_COMMIT: -------------------------------------------------------------------------------- 1 | 2 | --------------------------------------------------------------------------------