├── 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 |
--------------------------------------------------------------------------------