├── WallpaperSetter ├── Assets.xcassets │ ├── Contents.json │ ├── placeholder.imageset │ │ ├── dark.png │ │ ├── light.png │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ ├── Icon-App-20x20@1x.png │ │ ├── Icon-App-20x20@2x.png │ │ ├── Icon-App-20x20@3x.png │ │ ├── Icon-App-29x29@1x.png │ │ ├── Icon-App-29x29@2x.png │ │ ├── Icon-App-29x29@3x.png │ │ ├── Icon-App-40x40@1x.png │ │ ├── Icon-App-40x40@2x.png │ │ ├── Icon-App-40x40@3x.png │ │ ├── Icon-App-60x60@2x.png │ │ ├── Icon-App-60x60@3x.png │ │ ├── Icon-App-76x76@1x.png │ │ ├── Icon-App-76x76@2x.png │ │ ├── ItunesArtwork@2x.png │ │ ├── Icon-App-83.5x83.5@2x.png │ │ └── Contents.json │ └── AccentColor.colorset │ │ └── Contents.json ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json ├── WallpaperSetterApp.swift ├── WallpaperSetter-Bridging-Header.h ├── WallpaperSetter.entitlements ├── invoke.m ├── ImagePicker.swift └── ContentView.swift ├── .gitignore ├── README.md ├── .github └── workflows │ └── build.yml └── WallpaperSetter.xcodeproj └── project.pbxproj /WallpaperSetter/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /WallpaperSetter/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /WallpaperSetter/Assets.xcassets/placeholder.imageset/dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Skittyblock/WallpaperSetter/HEAD/WallpaperSetter/Assets.xcassets/placeholder.imageset/dark.png -------------------------------------------------------------------------------- /WallpaperSetter/Assets.xcassets/placeholder.imageset/light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Skittyblock/WallpaperSetter/HEAD/WallpaperSetter/Assets.xcassets/placeholder.imageset/light.png -------------------------------------------------------------------------------- /WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Skittyblock/WallpaperSetter/HEAD/WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Skittyblock/WallpaperSetter/HEAD/WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Skittyblock/WallpaperSetter/HEAD/WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Skittyblock/WallpaperSetter/HEAD/WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Skittyblock/WallpaperSetter/HEAD/WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Skittyblock/WallpaperSetter/HEAD/WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Skittyblock/WallpaperSetter/HEAD/WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Skittyblock/WallpaperSetter/HEAD/WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Skittyblock/WallpaperSetter/HEAD/WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Skittyblock/WallpaperSetter/HEAD/WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Skittyblock/WallpaperSetter/HEAD/WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Skittyblock/WallpaperSetter/HEAD/WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Skittyblock/WallpaperSetter/HEAD/WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /WallpaperSetter/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Skittyblock/WallpaperSetter/HEAD/WallpaperSetter/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # xcode 2 | xcuserdata/ 3 | *.xcodeproj/* 4 | !*.xcodeproj/project.pbxproj 5 | !*.xcodeproj/xcshareddata/ 6 | !*.xcworkspace/contents.xcworkspacedata 7 | build/ 8 | 9 | # other 10 | *.DS_Store 11 | -------------------------------------------------------------------------------- /WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Skittyblock/WallpaperSetter/HEAD/WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /WallpaperSetter/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /WallpaperSetter/WallpaperSetterApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WallpaperSetterApp.swift 3 | // WallpaperSetter 4 | // 5 | // Created by Skitty on 9/3/22. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct WallpaperSetterApp: App { 12 | var body: some Scene { 13 | WindowGroup { 14 | ContentView() 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /WallpaperSetter/WallpaperSetter-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | void invoke(SEL selector, id target, void *arg); 6 | void invokeInt(SEL selector, id target, long long arg); 7 | void invokeDouble(SEL selector, id target, double arg); 8 | void invokeAny(SEL selector, id target, id arg); 9 | -------------------------------------------------------------------------------- /WallpaperSetter/Assets.xcassets/placeholder.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "light.png", 5 | "idiom" : "universal" 6 | }, 7 | { 8 | "appearances" : [ 9 | { 10 | "appearance" : "luminosity", 11 | "value" : "dark" 12 | } 13 | ], 14 | "filename" : "dark.png", 15 | "idiom" : "universal" 16 | } 17 | ], 18 | "info" : { 19 | "author" : "xcode", 20 | "version" : 1 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /WallpaperSetter/WallpaperSetter.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.springboard.wallpaper-access 6 | 7 | com.apple.security.app-sandbox 8 | 9 | platform-application 10 | 11 | com.apple.private.security.container-manager 12 | 13 | com.apple.private.security.container-required 14 | 15 | com.apple.private.security.no-container 16 | 17 | com.apple.security.exception.files.absolute-path.read-write 18 | 19 | / 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /WallpaperSetter/invoke.m: -------------------------------------------------------------------------------- 1 | // 2 | // invoke.m 3 | // WallpaperSetter 4 | // 5 | // Created by Skitty on 9/4/22. 6 | // 7 | 8 | #import 9 | 10 | // only way I could find to call setWallpaperMode without crashing was with NSInvocation 11 | 12 | void invoke(SEL selector, id target, void *arg) { 13 | NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[target methodSignatureForSelector:selector]]; 14 | [inv setSelector:selector]; 15 | [inv setTarget:target]; 16 | [inv setArgument:arg atIndex:2]; 17 | [inv invoke]; 18 | } 19 | 20 | void invokeInt(SEL selector, id target, long long arg) { 21 | invoke(selector, target, &arg); 22 | } 23 | void invokeDouble(SEL selector, id target, double arg) { 24 | invoke(selector, target, &arg); 25 | } 26 | void invokeAny(SEL selector, id target, id arg) { 27 | invoke(selector, target, &arg); 28 | } 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WallpaperSetter 2 | iOS application for setting separate light and dark mode wallpapers. Usable with [TrollStore](https://github.com/opa334/TrollStore) on iOS 14-15.1.1. 3 | 4 | ## Building 5 | WallpaperSetter requires the `com.apple.springboard.wallpaper-access` entitlement, meaning you won't be able to codesign it with an Apple Developer account to run on a real device. You will need to use `xcodebuild` to build without codesigning. 6 | ```sh 7 | xcodebuild build CODE_SIGN_IDENTITY= CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO 8 | ``` 9 | To package it, copy the resulting .app in the `build/Release-iphoneos` directory into a `Payload` folder, fakesign it, zip it, and then rename to an ipa file. 10 | ```sh 11 | cd build/Release-iphoneos/ 12 | mkdir Payload 13 | ldid -S../../WallpaperSetter/WallpaperSetter.entitlements WPSetter.app 14 | cp -r WPSetter.app Payload 15 | zip -r WallpaperSetter.ipa Payload 16 | ``` 17 | 18 | Running on the simulator should work fine. 19 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build ipa 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths-ignore: 8 | - '**/*.md' 9 | - '.gitignore' 10 | pull_request: 11 | branches: 12 | - main 13 | paths-ignore: 14 | - '**/*.md' 15 | - '.gitignore' 16 | workflow_dispatch: 17 | 18 | jobs: 19 | build: 20 | runs-on: macos-latest 21 | steps: 22 | - uses: actions/checkout@v2 23 | - name: Setup Xcode 24 | uses: maxim-lobanov/setup-xcode@v1 25 | with: 26 | xcode-version: latest-stable 27 | - name: Build 28 | run: xcodebuild build -scheme WallpaperSetter -configuration Release CODE_SIGN_IDENTITY= CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO BUILD_DIR=${{ github.workspace }}/build 29 | - name: Package ipa 30 | run: | 31 | mkdir Payload 32 | cp -r ${{ github.workspace }}/build/Release-iphoneos/WPSetter.app Payload 33 | wget https://github.com/sbingner/ldid/releases/download/v2.1.4%2B16.g5b8581c/ldid-osx.gz 34 | gunzip ldid-osx.gz 35 | chmod +x ldid-osx 36 | ./ldid-osx -S${{ github.workspace }}/WallpaperSetter/WallpaperSetter.entitlements Payload/WPSetter.app 37 | zip -r WallpaperSetter.ipa Payload 38 | - name: Upload ipa 39 | uses: actions/upload-artifact@v3.1.0 40 | with: 41 | name: WallpaperSetter 42 | path: WallpaperSetter.ipa 43 | if-no-files-found: error 44 | -------------------------------------------------------------------------------- /WallpaperSetter/ImagePicker.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ImagePicker.swift 3 | // WallpaperSetter 4 | // 5 | // Created by Skitty on 9/3/22. 6 | // 7 | 8 | import PhotosUI 9 | import SwiftUI 10 | 11 | struct ImagePicker: UIViewControllerRepresentable { 12 | 13 | @Binding var image: UIImage? 14 | 15 | func makeUIViewController(context: Context) -> PHPickerViewController { 16 | var config = PHPickerConfiguration() 17 | config.filter = .images 18 | let picker = PHPickerViewController(configuration: config) 19 | picker.delegate = context.coordinator 20 | return picker 21 | } 22 | 23 | func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) {} 24 | 25 | func makeCoordinator() -> Coordinator { 26 | Coordinator(self) 27 | } 28 | 29 | class Coordinator: NSObject, PHPickerViewControllerDelegate { 30 | let parent: ImagePicker 31 | 32 | init(_ parent: ImagePicker) { 33 | self.parent = parent 34 | } 35 | 36 | func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { 37 | picker.dismiss(animated: true) 38 | 39 | guard let provider = results.first?.itemProvider else { return } 40 | 41 | if provider.canLoadObject(ofClass: UIImage.self) { 42 | provider.loadObject(ofClass: UIImage.self) { image, _ in 43 | self.parent.image = image as? UIImage 44 | } 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /WallpaperSetter/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Icon-App-20x20@2x.png", 5 | "idiom" : "iphone", 6 | "scale" : "2x", 7 | "size" : "20x20" 8 | }, 9 | { 10 | "filename" : "Icon-App-20x20@3x.png", 11 | "idiom" : "iphone", 12 | "scale" : "3x", 13 | "size" : "20x20" 14 | }, 15 | { 16 | "filename" : "Icon-App-29x29@1x.png", 17 | "idiom" : "iphone", 18 | "scale" : "1x", 19 | "size" : "29x29" 20 | }, 21 | { 22 | "filename" : "Icon-App-29x29@2x.png", 23 | "idiom" : "iphone", 24 | "scale" : "2x", 25 | "size" : "29x29" 26 | }, 27 | { 28 | "filename" : "Icon-App-29x29@3x.png", 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "29x29" 32 | }, 33 | { 34 | "filename" : "Icon-App-40x40@2x.png", 35 | "idiom" : "iphone", 36 | "scale" : "2x", 37 | "size" : "40x40" 38 | }, 39 | { 40 | "filename" : "Icon-App-40x40@3x.png", 41 | "idiom" : "iphone", 42 | "scale" : "3x", 43 | "size" : "40x40" 44 | }, 45 | { 46 | "filename" : "Icon-App-60x60@2x.png", 47 | "idiom" : "iphone", 48 | "scale" : "2x", 49 | "size" : "60x60" 50 | }, 51 | { 52 | "filename" : "Icon-App-60x60@3x.png", 53 | "idiom" : "iphone", 54 | "scale" : "3x", 55 | "size" : "60x60" 56 | }, 57 | { 58 | "filename" : "Icon-App-20x20@1x.png", 59 | "idiom" : "ipad", 60 | "scale" : "1x", 61 | "size" : "20x20" 62 | }, 63 | { 64 | "filename" : "Icon-App-20x20@2x.png", 65 | "idiom" : "ipad", 66 | "scale" : "2x", 67 | "size" : "20x20" 68 | }, 69 | { 70 | "filename" : "Icon-App-29x29@1x.png", 71 | "idiom" : "ipad", 72 | "scale" : "1x", 73 | "size" : "29x29" 74 | }, 75 | { 76 | "filename" : "Icon-App-29x29@2x.png", 77 | "idiom" : "ipad", 78 | "scale" : "2x", 79 | "size" : "29x29" 80 | }, 81 | { 82 | "filename" : "Icon-App-40x40@1x.png", 83 | "idiom" : "ipad", 84 | "scale" : "1x", 85 | "size" : "40x40" 86 | }, 87 | { 88 | "filename" : "Icon-App-40x40@2x.png", 89 | "idiom" : "ipad", 90 | "scale" : "2x", 91 | "size" : "40x40" 92 | }, 93 | { 94 | "filename" : "Icon-App-76x76@1x.png", 95 | "idiom" : "ipad", 96 | "scale" : "1x", 97 | "size" : "76x76" 98 | }, 99 | { 100 | "filename" : "Icon-App-76x76@2x.png", 101 | "idiom" : "ipad", 102 | "scale" : "2x", 103 | "size" : "76x76" 104 | }, 105 | { 106 | "filename" : "Icon-App-83.5x83.5@2x.png", 107 | "idiom" : "ipad", 108 | "scale" : "2x", 109 | "size" : "83.5x83.5" 110 | }, 111 | { 112 | "filename" : "ItunesArtwork@2x.png", 113 | "idiom" : "ios-marketing", 114 | "scale" : "1x", 115 | "size" : "1024x1024" 116 | } 117 | ], 118 | "info" : { 119 | "author" : "xcode", 120 | "version" : 1 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /WallpaperSetter/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // WallpaperSetter 4 | // 5 | // Created by Skitty on 9/3/22. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ContentView: View { 11 | 12 | enum WallpaperLoction: Int { 13 | case lockScreen = 1 14 | case homeScreen = 2 15 | case both = 3 16 | } 17 | 18 | @State private var settingDarkImage: Bool = false 19 | @State private var inputImage: UIImage? 20 | 21 | @State private var hasLightImage: Bool = false 22 | @State private var hasDarkImage: Bool = false 23 | 24 | @State private var lightImage = UIImage(named: "placeholder")! 25 | @State private var darkImage = UIImage(named: "placeholder")! 26 | 27 | @State private var perspectiveZoom: Bool = true 28 | @State private var downscaleImages: Bool = false 29 | 30 | @State private var showingImagePicker: Bool = false 31 | @State private var showingLocationSelect: Bool = false 32 | @State private var showingSelectAlert: Bool = false 33 | @State private var showingErrorAlert: Bool = false 34 | 35 | private static var frameworkPath: String = { 36 | #if TARGET_OS_SIMULATOR 37 | "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks" 38 | #else 39 | "/System/Library/PrivateFrameworks" 40 | #endif 41 | }() 42 | 43 | var body: some View { 44 | NavigationView { 45 | List { 46 | Section { 47 | HStack(spacing: 0) { 48 | Spacer() 49 | Image(uiImage: lightImage) 50 | .resizable() 51 | .scaledToFill() 52 | .frame( 53 | width: UIScreen.main.bounds.width * (244 / UIScreen.main.bounds.height), 54 | height: 244 55 | ) 56 | .clipped() 57 | .border(Color(UIColor.quaternarySystemFill)) 58 | 59 | Rectangle() 60 | .foregroundColor(.clear) 61 | .frame(width: 12) // fix for spacing bug not centering 62 | 63 | Image(uiImage: darkImage) 64 | .resizable() 65 | .scaledToFill() 66 | .frame( 67 | width: UIScreen.main.bounds.width * (244 / UIScreen.main.bounds.height), 68 | height: 244 69 | ) 70 | .clipped() 71 | .border(Color(UIColor.quaternarySystemFill)) 72 | Spacer() 73 | } 74 | .padding(.vertical) 75 | Toggle("Perspective Zoom", isOn: $perspectiveZoom) 76 | // Toggle("Downscale Images", isOn: $downscaleImages) // I don't think this is really necessary 77 | } 78 | Section { 79 | Button("Set Light Wallpaper") { 80 | settingDarkImage = false 81 | showingImagePicker = true 82 | } 83 | Button("Set Dark Wallpaper") { 84 | settingDarkImage = true 85 | showingImagePicker = true 86 | } 87 | } 88 | Section { 89 | if #available(iOS 15.0, *) { 90 | Button("Set Wallpaper") { 91 | showingLocationSelect = true 92 | } 93 | .confirmationDialog("Select location", isPresented: $showingLocationSelect, titleVisibility: .hidden) { 94 | Button("Home Screen") { 95 | setWallpaper(location: .homeScreen) 96 | } 97 | Button("Lock Screen") { 98 | setWallpaper(location: .lockScreen) 99 | } 100 | Button("Both") { 101 | setWallpaper(location: .both) 102 | } 103 | } 104 | } else { 105 | Button("Set Wallpaper") { 106 | showingLocationSelect = true 107 | } 108 | .actionSheet(isPresented: $showingLocationSelect) { 109 | ActionSheet( 110 | title: Text("Select location"), 111 | buttons: [ 112 | .default(Text("Home Screen")) { 113 | setWallpaper(location: .homeScreen) 114 | }, 115 | .default(Text("Lock Screen")) { 116 | setWallpaper(location: .lockScreen) 117 | }, 118 | .default(Text("Both")) { 119 | setWallpaper(location: .both) 120 | }, 121 | .cancel() 122 | ] 123 | ) 124 | } 125 | } 126 | } 127 | } 128 | .listStyle(InsetGroupedListStyle()) 129 | .navigationTitle("WallpaperSetter") 130 | .navigationBarTitleDisplayMode(.inline) 131 | .sheet(isPresented: $showingImagePicker) { 132 | ImagePicker(image: $inputImage) 133 | } 134 | .modifier(ContentViewAlerts(showingSelectAlert: $showingSelectAlert, showingErrorAlert: $showingErrorAlert)) 135 | .onChange(of: inputImage) { _ in loadImage() } 136 | .onAppear { 137 | loadWallpapers() 138 | } 139 | } 140 | } 141 | 142 | // load current wallpaper(s) 143 | // requires read perms for /var/mobile/Library/ 144 | func loadWallpapers() { 145 | func exists(_ path: String) -> Bool { 146 | FileManager.default.fileExists(atPath: path) 147 | } 148 | 149 | let lightData: NSData? 150 | let darkData: NSData? 151 | 152 | if exists("/var/mobile/Library/SpringBoard/HomeBackground.cpbitmap") { 153 | lightData = NSData(contentsOfFile: "/var/mobile/Library/SpringBoard/HomeBackground.cpbitmap") 154 | if exists("/var/mobile/Library/SpringBoard/HomeBackgrounddark.cpbitmap") { 155 | darkData = NSData(contentsOfFile: "/var/mobile/Library/SpringBoard/HomeBackgrounddark.cpbitmap") 156 | } else { 157 | darkData = lightData 158 | } 159 | } else if exists("/var/mobile/Library/SpringBoard/LockBackground.cpbitmap") { 160 | lightData = NSData(contentsOfFile: "/var/mobile/Library/SpringBoard/LockBackground.cpbitmap") 161 | if exists("/var/mobile/Library/SpringBoard/LockBackgrounddark.cpbitmap") { 162 | darkData = NSData(contentsOfFile: "/var/mobile/Library/SpringBoard/LockBackgrounddark.cpbitmap") 163 | } else { 164 | darkData = lightData 165 | } 166 | } else { 167 | lightData = nil 168 | darkData = nil 169 | } 170 | 171 | guard let lightData = lightData, let darkData = darkData else { 172 | return 173 | } 174 | 175 | // load CPBitmapCreateImagesFromData 176 | let appSupport = dlopen(Self.frameworkPath + "/AppSupport.framework/AppSupport", RTLD_LAZY) 177 | defer { 178 | dlclose(appSupport) 179 | } 180 | guard 181 | let pointer = dlsym(appSupport, "CPBitmapCreateImagesFromData"), 182 | let CPBitmapCreateImagesFromData = unsafeBitCast( 183 | pointer, 184 | to: (@convention(c) (_: NSData, _: UnsafeMutableRawPointer?, _: Int, _: UnsafeMutableRawPointer?) -> Unmanaged)?.self 185 | ) 186 | else { 187 | return 188 | } 189 | 190 | // convert cpbitmap data to UIImage 191 | func bitmapDataToImage(data: NSData) -> UIImage? { 192 | let imageArray: [AnyObject]? = CPBitmapCreateImagesFromData(data, nil, 1, nil).takeRetainedValue() as [AnyObject] 193 | guard 194 | let imageArray = imageArray, 195 | imageArray.count > 0 196 | else { 197 | return nil 198 | } 199 | return UIImage(cgImage: imageArray[0] as! CGImage) 200 | } 201 | 202 | if let image = bitmapDataToImage(data: lightData) { 203 | lightImage = image 204 | hasLightImage = true 205 | } 206 | if let image = bitmapDataToImage(data: darkData) { 207 | darkImage = image 208 | hasDarkImage = true 209 | } 210 | } 211 | 212 | // load inputImage from picker 213 | func loadImage() { 214 | guard let inputImage = inputImage else { 215 | return 216 | } 217 | self.inputImage = nil 218 | if settingDarkImage { 219 | darkImage = downscaleImages ? downscale(image: inputImage) : inputImage 220 | hasDarkImage = true 221 | } else { 222 | lightImage = downscaleImages ? downscale(image: inputImage) : inputImage 223 | hasLightImage = true 224 | } 225 | } 226 | 227 | func downscale(image: UIImage) -> UIImage { 228 | let factor = 1024 / image.size.height 229 | let size = CGSize(width: image.size.width * factor, height: 1024) 230 | 231 | UIGraphicsBeginImageContext(size) 232 | image.draw(in: CGRect(origin: .zero, size: size)) 233 | let newImage = UIGraphicsGetImageFromCurrentImageContext() 234 | UIGraphicsEndImageContext() 235 | 236 | return newImage ?? image 237 | } 238 | 239 | func setWallpaper(location: WallpaperLoction) { 240 | // ensure a wallpaper has been chosen 241 | if !hasLightImage && hasDarkImage { 242 | lightImage = darkImage 243 | hasLightImage = true 244 | } 245 | guard hasLightImage else { 246 | showingSelectAlert = true 247 | return 248 | } 249 | if !hasDarkImage { 250 | darkImage = lightImage 251 | hasDarkImage = true 252 | } 253 | 254 | // load private frameworks 255 | let sbFoundation = dlopen(Self.frameworkPath + "/SpringBoardFoundation.framework/SpringBoardFoundation", RTLD_LAZY) 256 | let sbUIServices = dlopen(Self.frameworkPath + "/SpringBoardUIServices.framework/SpringBoardUIServices", RTLD_LAZY) 257 | 258 | defer { 259 | dlclose(sbFoundation) 260 | dlclose(sbUIServices) 261 | } 262 | 263 | guard 264 | let SBFWallpaperOptions = NSClassFromString("SBFWallpaperOptions"), 265 | let pointer = dlsym(sbUIServices, "SBSUIWallpaperSetImages"), 266 | let SBSUIWallpaperSetImages = unsafeBitCast( 267 | pointer, 268 | to: (@convention(c) (_: NSDictionary, _: NSDictionary, _: Int, _: Int) -> Int)?.self 269 | ) 270 | else { 271 | showingErrorAlert = true 272 | return 273 | } 274 | 275 | // set wallpaper options 276 | let setModeSelector = NSSelectorFromString("setWallpaperMode:") 277 | let setParallaxSelector = NSSelectorFromString("setParallaxFactor:") 278 | let setNameSelector = NSSelectorFromString("setName:") 279 | 280 | let lightOptions = SBFWallpaperOptions.alloc() 281 | invokeInt(setModeSelector, lightOptions, 1) 282 | invokeDouble(setParallaxSelector, lightOptions, perspectiveZoom ? 1 : 0) 283 | invokeAny(setNameSelector, lightOptions, NSString("1234.WallpaperLoader Light")) 284 | 285 | let darkOptions = SBFWallpaperOptions.alloc() 286 | invokeInt(setModeSelector, darkOptions, 2) 287 | invokeDouble(setParallaxSelector, darkOptions, perspectiveZoom ? 1 : 0) 288 | invokeAny(setNameSelector, darkOptions, NSString("1234.WallpaperLoader Dark")) 289 | 290 | let imagesDict = [ 291 | "light": lightImage, 292 | "dark": darkImage 293 | ] 294 | 295 | let optionsDict = [ 296 | "light" : lightOptions, 297 | "dark": darkOptions 298 | ] 299 | 300 | // set wallpaper 301 | _ = SBSUIWallpaperSetImages( 302 | NSDictionary(dictionary: imagesDict), 303 | NSDictionary(dictionary: optionsDict), 304 | location.rawValue, 305 | UIUserInterfaceStyle.dark.rawValue 306 | ) 307 | } 308 | } 309 | 310 | struct ContentViewAlerts: ViewModifier { 311 | 312 | @Binding var showingSelectAlert: Bool 313 | @Binding var showingErrorAlert: Bool 314 | 315 | func body(content: Content) -> some View { 316 | if #available(iOS 15.0, *) { 317 | content 318 | .alert("Select Wallpapers", isPresented: $showingSelectAlert) { 319 | Button("OK", role: .cancel) { 320 | showingSelectAlert = false 321 | } 322 | } message: { 323 | Text("Please select a wallpaper before setting.") 324 | } 325 | .alert("Failed", isPresented: $showingErrorAlert) { 326 | Button("OK", role: .cancel) { 327 | showingSelectAlert = false 328 | } 329 | } message: { 330 | Text("Encountered an error when setting wallpaper.") 331 | } 332 | } else { 333 | content 334 | .alert(isPresented: $showingSelectAlert) { 335 | Alert( 336 | title: Text("Select Wallpapers"), 337 | message: Text("Please select a wallpaper before setting.") 338 | ) 339 | } 340 | .alert(isPresented: $showingErrorAlert) { 341 | Alert( 342 | title: Text("Failed"), 343 | message: Text("Encountered an error when setting wallpaper.") 344 | ) 345 | } 346 | } 347 | } 348 | } 349 | 350 | struct ContentView_Previews: PreviewProvider { 351 | static var previews: some View { 352 | ContentView() 353 | } 354 | } 355 | -------------------------------------------------------------------------------- /WallpaperSetter.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 55; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | FBD011B828C446780056A7EB /* WallpaperSetterApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBD011B728C446780056A7EB /* WallpaperSetterApp.swift */; }; 11 | FBD011BA28C446780056A7EB /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBD011B928C446780056A7EB /* ContentView.swift */; }; 12 | FBD011BC28C446790056A7EB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FBD011BB28C446790056A7EB /* Assets.xcassets */; }; 13 | FBD011BF28C446790056A7EB /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FBD011BE28C446790056A7EB /* Preview Assets.xcassets */; }; 14 | FBD011C628C44E300056A7EB /* ImagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBD011C528C44E300056A7EB /* ImagePicker.swift */; }; 15 | FBD011CD28C4DBB40056A7EB /* invoke.m in Sources */ = {isa = PBXBuildFile; fileRef = FBD011CC28C4DBB40056A7EB /* invoke.m */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXFileReference section */ 19 | FBD011B428C446780056A7EB /* WPSetter.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WPSetter.app; sourceTree = BUILT_PRODUCTS_DIR; }; 20 | FBD011B728C446780056A7EB /* WallpaperSetterApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WallpaperSetterApp.swift; sourceTree = ""; }; 21 | FBD011B928C446780056A7EB /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 22 | FBD011BB28C446790056A7EB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 23 | FBD011BE28C446790056A7EB /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 24 | FBD011C528C44E300056A7EB /* ImagePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePicker.swift; sourceTree = ""; }; 25 | FBD011C728C4536A0056A7EB /* WallpaperSetter.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WallpaperSetter.entitlements; sourceTree = ""; }; 26 | FBD011C928C4D99C0056A7EB /* WallpaperSetter-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WallpaperSetter-Bridging-Header.h"; sourceTree = ""; }; 27 | FBD011CC28C4DBB40056A7EB /* invoke.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = invoke.m; sourceTree = ""; }; 28 | /* End PBXFileReference section */ 29 | 30 | /* Begin PBXFrameworksBuildPhase section */ 31 | FBD011B128C446780056A7EB /* Frameworks */ = { 32 | isa = PBXFrameworksBuildPhase; 33 | buildActionMask = 2147483647; 34 | files = ( 35 | ); 36 | runOnlyForDeploymentPostprocessing = 0; 37 | }; 38 | /* End PBXFrameworksBuildPhase section */ 39 | 40 | /* Begin PBXGroup section */ 41 | FBD011AB28C446780056A7EB = { 42 | isa = PBXGroup; 43 | children = ( 44 | FBD011B628C446780056A7EB /* WallpaperSetter */, 45 | FBD011B528C446780056A7EB /* Products */, 46 | ); 47 | sourceTree = ""; 48 | }; 49 | FBD011B528C446780056A7EB /* Products */ = { 50 | isa = PBXGroup; 51 | children = ( 52 | FBD011B428C446780056A7EB /* WPSetter.app */, 53 | ); 54 | name = Products; 55 | sourceTree = ""; 56 | }; 57 | FBD011B628C446780056A7EB /* WallpaperSetter */ = { 58 | isa = PBXGroup; 59 | children = ( 60 | FBD011B728C446780056A7EB /* WallpaperSetterApp.swift */, 61 | FBD011B928C446780056A7EB /* ContentView.swift */, 62 | FBD011C528C44E300056A7EB /* ImagePicker.swift */, 63 | FBD011CC28C4DBB40056A7EB /* invoke.m */, 64 | FBD011C928C4D99C0056A7EB /* WallpaperSetter-Bridging-Header.h */, 65 | FBD011C728C4536A0056A7EB /* WallpaperSetter.entitlements */, 66 | FBD011BB28C446790056A7EB /* Assets.xcassets */, 67 | FBD011BD28C446790056A7EB /* Preview Content */, 68 | ); 69 | path = WallpaperSetter; 70 | sourceTree = ""; 71 | }; 72 | FBD011BD28C446790056A7EB /* Preview Content */ = { 73 | isa = PBXGroup; 74 | children = ( 75 | FBD011BE28C446790056A7EB /* Preview Assets.xcassets */, 76 | ); 77 | path = "Preview Content"; 78 | sourceTree = ""; 79 | }; 80 | /* End PBXGroup section */ 81 | 82 | /* Begin PBXNativeTarget section */ 83 | FBD011B328C446780056A7EB /* WallpaperSetter */ = { 84 | isa = PBXNativeTarget; 85 | buildConfigurationList = FBD011C228C446790056A7EB /* Build configuration list for PBXNativeTarget "WallpaperSetter" */; 86 | buildPhases = ( 87 | FBD011B028C446780056A7EB /* Sources */, 88 | FBD011B128C446780056A7EB /* Frameworks */, 89 | FBD011B228C446780056A7EB /* Resources */, 90 | ); 91 | buildRules = ( 92 | ); 93 | dependencies = ( 94 | ); 95 | name = WallpaperSetter; 96 | productName = WallpaperSetter; 97 | productReference = FBD011B428C446780056A7EB /* WPSetter.app */; 98 | productType = "com.apple.product-type.application"; 99 | }; 100 | /* End PBXNativeTarget section */ 101 | 102 | /* Begin PBXProject section */ 103 | FBD011AC28C446780056A7EB /* Project object */ = { 104 | isa = PBXProject; 105 | attributes = { 106 | BuildIndependentTargetsInParallel = 1; 107 | LastSwiftUpdateCheck = 1340; 108 | LastUpgradeCheck = 1340; 109 | TargetAttributes = { 110 | FBD011B328C446780056A7EB = { 111 | CreatedOnToolsVersion = 13.4.1; 112 | LastSwiftMigration = 1340; 113 | }; 114 | }; 115 | }; 116 | buildConfigurationList = FBD011AF28C446780056A7EB /* Build configuration list for PBXProject "WallpaperSetter" */; 117 | compatibilityVersion = "Xcode 13.0"; 118 | developmentRegion = en; 119 | hasScannedForEncodings = 0; 120 | knownRegions = ( 121 | en, 122 | Base, 123 | ); 124 | mainGroup = FBD011AB28C446780056A7EB; 125 | productRefGroup = FBD011B528C446780056A7EB /* Products */; 126 | projectDirPath = ""; 127 | projectRoot = ""; 128 | targets = ( 129 | FBD011B328C446780056A7EB /* WallpaperSetter */, 130 | ); 131 | }; 132 | /* End PBXProject section */ 133 | 134 | /* Begin PBXResourcesBuildPhase section */ 135 | FBD011B228C446780056A7EB /* Resources */ = { 136 | isa = PBXResourcesBuildPhase; 137 | buildActionMask = 2147483647; 138 | files = ( 139 | FBD011BF28C446790056A7EB /* Preview Assets.xcassets in Resources */, 140 | FBD011BC28C446790056A7EB /* Assets.xcassets in Resources */, 141 | ); 142 | runOnlyForDeploymentPostprocessing = 0; 143 | }; 144 | /* End PBXResourcesBuildPhase section */ 145 | 146 | /* Begin PBXSourcesBuildPhase section */ 147 | FBD011B028C446780056A7EB /* Sources */ = { 148 | isa = PBXSourcesBuildPhase; 149 | buildActionMask = 2147483647; 150 | files = ( 151 | FBD011C628C44E300056A7EB /* ImagePicker.swift in Sources */, 152 | FBD011CD28C4DBB40056A7EB /* invoke.m in Sources */, 153 | FBD011BA28C446780056A7EB /* ContentView.swift in Sources */, 154 | FBD011B828C446780056A7EB /* WallpaperSetterApp.swift in Sources */, 155 | ); 156 | runOnlyForDeploymentPostprocessing = 0; 157 | }; 158 | /* End PBXSourcesBuildPhase section */ 159 | 160 | /* Begin XCBuildConfiguration section */ 161 | FBD011C028C446790056A7EB /* Debug */ = { 162 | isa = XCBuildConfiguration; 163 | buildSettings = { 164 | ALWAYS_SEARCH_USER_PATHS = NO; 165 | CLANG_ANALYZER_NONNULL = YES; 166 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 167 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 168 | CLANG_ENABLE_MODULES = YES; 169 | CLANG_ENABLE_OBJC_ARC = YES; 170 | CLANG_ENABLE_OBJC_WEAK = YES; 171 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 172 | CLANG_WARN_BOOL_CONVERSION = YES; 173 | CLANG_WARN_COMMA = YES; 174 | CLANG_WARN_CONSTANT_CONVERSION = YES; 175 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 176 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 177 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 178 | CLANG_WARN_EMPTY_BODY = YES; 179 | CLANG_WARN_ENUM_CONVERSION = YES; 180 | CLANG_WARN_INFINITE_RECURSION = YES; 181 | CLANG_WARN_INT_CONVERSION = YES; 182 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 183 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 184 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 185 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 186 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 187 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 188 | CLANG_WARN_STRICT_PROTOTYPES = YES; 189 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 190 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 191 | CLANG_WARN_UNREACHABLE_CODE = YES; 192 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 193 | COPY_PHASE_STRIP = NO; 194 | DEBUG_INFORMATION_FORMAT = dwarf; 195 | ENABLE_STRICT_OBJC_MSGSEND = YES; 196 | ENABLE_TESTABILITY = YES; 197 | GCC_C_LANGUAGE_STANDARD = gnu11; 198 | GCC_DYNAMIC_NO_PIC = NO; 199 | GCC_NO_COMMON_BLOCKS = YES; 200 | GCC_OPTIMIZATION_LEVEL = 0; 201 | GCC_PREPROCESSOR_DEFINITIONS = ( 202 | "DEBUG=1", 203 | "$(inherited)", 204 | ); 205 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 206 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 207 | GCC_WARN_UNDECLARED_SELECTOR = YES; 208 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 209 | GCC_WARN_UNUSED_FUNCTION = YES; 210 | GCC_WARN_UNUSED_VARIABLE = YES; 211 | IPHONEOS_DEPLOYMENT_TARGET = 15.5; 212 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 213 | MTL_FAST_MATH = YES; 214 | ONLY_ACTIVE_ARCH = YES; 215 | SDKROOT = iphoneos; 216 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 217 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 218 | }; 219 | name = Debug; 220 | }; 221 | FBD011C128C446790056A7EB /* Release */ = { 222 | isa = XCBuildConfiguration; 223 | buildSettings = { 224 | ALWAYS_SEARCH_USER_PATHS = NO; 225 | CLANG_ANALYZER_NONNULL = YES; 226 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 227 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 228 | CLANG_ENABLE_MODULES = YES; 229 | CLANG_ENABLE_OBJC_ARC = YES; 230 | CLANG_ENABLE_OBJC_WEAK = YES; 231 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 232 | CLANG_WARN_BOOL_CONVERSION = YES; 233 | CLANG_WARN_COMMA = YES; 234 | CLANG_WARN_CONSTANT_CONVERSION = YES; 235 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 236 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 237 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 238 | CLANG_WARN_EMPTY_BODY = YES; 239 | CLANG_WARN_ENUM_CONVERSION = YES; 240 | CLANG_WARN_INFINITE_RECURSION = YES; 241 | CLANG_WARN_INT_CONVERSION = YES; 242 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 243 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 244 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 245 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 246 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 247 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 248 | CLANG_WARN_STRICT_PROTOTYPES = YES; 249 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 250 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 251 | CLANG_WARN_UNREACHABLE_CODE = YES; 252 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 253 | COPY_PHASE_STRIP = NO; 254 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 255 | ENABLE_NS_ASSERTIONS = NO; 256 | ENABLE_STRICT_OBJC_MSGSEND = YES; 257 | GCC_C_LANGUAGE_STANDARD = gnu11; 258 | GCC_NO_COMMON_BLOCKS = YES; 259 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 260 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 261 | GCC_WARN_UNDECLARED_SELECTOR = YES; 262 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 263 | GCC_WARN_UNUSED_FUNCTION = YES; 264 | GCC_WARN_UNUSED_VARIABLE = YES; 265 | IPHONEOS_DEPLOYMENT_TARGET = 15.5; 266 | MTL_ENABLE_DEBUG_INFO = NO; 267 | MTL_FAST_MATH = YES; 268 | SDKROOT = iphoneos; 269 | SWIFT_COMPILATION_MODE = wholemodule; 270 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 271 | VALIDATE_PRODUCT = YES; 272 | }; 273 | name = Release; 274 | }; 275 | FBD011C328C446790056A7EB /* Debug */ = { 276 | isa = XCBuildConfiguration; 277 | buildSettings = { 278 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 279 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 280 | CLANG_ENABLE_MODULES = YES; 281 | CODE_SIGN_ENTITLEMENTS = WallpaperSetter/WallpaperSetter.entitlements; 282 | CODE_SIGN_STYLE = Manual; 283 | CURRENT_PROJECT_VERSION = 1; 284 | DEVELOPMENT_ASSET_PATHS = "\"WallpaperSetter/Preview Content\""; 285 | DEVELOPMENT_TEAM = ""; 286 | ENABLE_PREVIEWS = YES; 287 | GENERATE_INFOPLIST_FILE = YES; 288 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 289 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 290 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 291 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 292 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 293 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 294 | LD_RUNPATH_SEARCH_PATHS = ( 295 | "$(inherited)", 296 | "@executable_path/Frameworks", 297 | ); 298 | MARKETING_VERSION = 1.0.1; 299 | PRODUCT_BUNDLE_IDENTIFIER = xyz.skitty.WallpaperSetter; 300 | PRODUCT_NAME = WPSetter; 301 | PROVISIONING_PROFILE_SPECIFIER = ""; 302 | SWIFT_EMIT_LOC_STRINGS = YES; 303 | SWIFT_OBJC_BRIDGING_HEADER = "WallpaperSetter/WallpaperSetter-Bridging-Header.h"; 304 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 305 | SWIFT_VERSION = 5.0; 306 | TARGETED_DEVICE_FAMILY = "1,2"; 307 | }; 308 | name = Debug; 309 | }; 310 | FBD011C428C446790056A7EB /* Release */ = { 311 | isa = XCBuildConfiguration; 312 | buildSettings = { 313 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 314 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 315 | CLANG_ENABLE_MODULES = YES; 316 | CODE_SIGN_ENTITLEMENTS = WallpaperSetter/WallpaperSetter.entitlements; 317 | CODE_SIGN_STYLE = Manual; 318 | CURRENT_PROJECT_VERSION = 1; 319 | DEVELOPMENT_ASSET_PATHS = "\"WallpaperSetter/Preview Content\""; 320 | DEVELOPMENT_TEAM = ""; 321 | ENABLE_PREVIEWS = YES; 322 | GENERATE_INFOPLIST_FILE = YES; 323 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 324 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 325 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 326 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 327 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 328 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 329 | LD_RUNPATH_SEARCH_PATHS = ( 330 | "$(inherited)", 331 | "@executable_path/Frameworks", 332 | ); 333 | MARKETING_VERSION = 1.0.1; 334 | PRODUCT_BUNDLE_IDENTIFIER = xyz.skitty.WallpaperSetter; 335 | PRODUCT_NAME = WPSetter; 336 | PROVISIONING_PROFILE_SPECIFIER = ""; 337 | SWIFT_EMIT_LOC_STRINGS = YES; 338 | SWIFT_OBJC_BRIDGING_HEADER = "WallpaperSetter/WallpaperSetter-Bridging-Header.h"; 339 | SWIFT_VERSION = 5.0; 340 | TARGETED_DEVICE_FAMILY = "1,2"; 341 | }; 342 | name = Release; 343 | }; 344 | /* End XCBuildConfiguration section */ 345 | 346 | /* Begin XCConfigurationList section */ 347 | FBD011AF28C446780056A7EB /* Build configuration list for PBXProject "WallpaperSetter" */ = { 348 | isa = XCConfigurationList; 349 | buildConfigurations = ( 350 | FBD011C028C446790056A7EB /* Debug */, 351 | FBD011C128C446790056A7EB /* Release */, 352 | ); 353 | defaultConfigurationIsVisible = 0; 354 | defaultConfigurationName = Release; 355 | }; 356 | FBD011C228C446790056A7EB /* Build configuration list for PBXNativeTarget "WallpaperSetter" */ = { 357 | isa = XCConfigurationList; 358 | buildConfigurations = ( 359 | FBD011C328C446790056A7EB /* Debug */, 360 | FBD011C428C446790056A7EB /* Release */, 361 | ); 362 | defaultConfigurationIsVisible = 0; 363 | defaultConfigurationName = Release; 364 | }; 365 | /* End XCConfigurationList section */ 366 | }; 367 | rootObject = FBD011AC28C446780056A7EB /* Project object */; 368 | } 369 | --------------------------------------------------------------------------------