├── Screenshot.jpg ├── LICENSE ├── UnderPillow ├── Assets.xcassets │ ├── Contents.json │ ├── AppIcon.appiconset │ │ ├── icon_16x16.png │ │ ├── icon_32x32.png │ │ ├── icon_128x128.png │ │ ├── icon_16x16@2x.png │ │ ├── icon_256x256.png │ │ ├── icon_32x32@2x.png │ │ ├── icon_512x512.png │ │ ├── icon_128x128-1.png │ │ ├── icon_128x128@2x.png │ │ ├── icon_256x256@2x.png │ │ ├── icon_512x512@2x.png │ │ └── Contents.json │ └── AccentColor.colorset │ │ └── Contents.json ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json ├── UnderPillow.entitlements ├── Info.plist ├── UnderPillowApp.swift └── ContentView.swift ├── UnderPillow.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── project.pbxproj ├── UnderPillowXPC ├── main.swift ├── Info.plist ├── UnderPillowXPCDelegate.swift ├── UnderPillowXPCProtocol.swift └── UnderPillowXPC.swift ├── UnderPillow Finder ├── UnderPillow_Finder.entitlements ├── Info.plist └── FinderSync.swift ├── README.md └── .gitignore /Screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anastasiuspernat/UnderPillow/HEAD/Screenshot.jpg -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2022 Anastasiy Safari 2 | https://anastasiy.com 3 | 4 | License TBD 5 | -------------------------------------------------------------------------------- /UnderPillow/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /UnderPillow/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anastasiuspernat/UnderPillow/HEAD/UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_16x16.png -------------------------------------------------------------------------------- /UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anastasiuspernat/UnderPillow/HEAD/UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_32x32.png -------------------------------------------------------------------------------- /UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anastasiuspernat/UnderPillow/HEAD/UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_128x128.png -------------------------------------------------------------------------------- /UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anastasiuspernat/UnderPillow/HEAD/UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png -------------------------------------------------------------------------------- /UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anastasiuspernat/UnderPillow/HEAD/UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_256x256.png -------------------------------------------------------------------------------- /UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anastasiuspernat/UnderPillow/HEAD/UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png -------------------------------------------------------------------------------- /UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anastasiuspernat/UnderPillow/HEAD/UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_512x512.png -------------------------------------------------------------------------------- /UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_128x128-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anastasiuspernat/UnderPillow/HEAD/UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_128x128-1.png -------------------------------------------------------------------------------- /UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anastasiuspernat/UnderPillow/HEAD/UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png -------------------------------------------------------------------------------- /UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anastasiuspernat/UnderPillow/HEAD/UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png -------------------------------------------------------------------------------- /UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anastasiuspernat/UnderPillow/HEAD/UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png -------------------------------------------------------------------------------- /UnderPillow.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /UnderPillow/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 | -------------------------------------------------------------------------------- /UnderPillow.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /UnderPillowXPC/main.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UnderPillowXPC 3 | // 4 | // Created by Anastasiy on 11/8/22. 5 | // 6 | 7 | import Foundation 8 | 9 | 10 | // Create the delegate for the service. 11 | let delegate = UnderPillowXPCDelegate() 12 | let listener = NSXPCListener.service() 13 | listener.delegate = delegate 14 | listener.resume() 15 | 16 | -------------------------------------------------------------------------------- /UnderPillowXPC/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | XPCService 6 | 7 | ServiceType 8 | Application 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /UnderPillow/UnderPillow.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.disable-library-validation 8 | 9 | com.apple.security.files.user-selected.read-only 10 | 11 | com.apple.security.network.client 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /UnderPillow Finder/UnderPillow_Finder.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.temporary-exception.shared-preference.read-only 6 | 7 | com.apple.finder 8 | 9 | com.apple.security.app-sandbox 10 | 11 | com.apple.security.files.user-selected.read-only 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /UnderPillow Finder/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | LSUIElement 6 | 7 | NSExtension 8 | 9 | NSExtensionAttributes 10 | 11 | NSExtensionPointIdentifier 12 | com.apple.FinderSync 13 | NSExtensionPrincipalClass 14 | $(PRODUCT_MODULE_NAME).FinderSync 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /UnderPillow/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleURLTypes 6 | 7 | 8 | CFBundleTypeRole 9 | Editor 10 | CFBundleURLName 11 | Crispy-Driven-Pixels.UnderPillow 12 | CFBundleURLSchemes 13 | 14 | underpillow 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /UnderPillow/UnderPillowApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UnderPillowApp.swift 3 | // UnderPillowApp 4 | // 5 | // Created by Anastasiy on 11/7/22. 6 | // 7 | 8 | import SwiftUI 9 | import Foundation 10 | 11 | 12 | @main 13 | struct UnderPillowApp: App { 14 | @ObservedObject var viewModel = ListViewModel() 15 | init() { 16 | 17 | } 18 | var body: some Scene { 19 | WindowGroup { 20 | ContentView() 21 | .frame(minWidth: 100, idealWidth: 400, 22 | minHeight: 100, idealHeight: 500, 23 | alignment: .center) 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /UnderPillowXPC/UnderPillowXPCDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UnderPillowXPC.m 3 | // UnderPillowXPC 4 | // 5 | // Created by Anastasiy on 11/8/22. 6 | // 7 | 8 | import Foundation 9 | 10 | class UnderPillowXPCDelegate: NSObject, NSXPCListenerDelegate { 11 | func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool { 12 | newConnection.exportedInterface = NSXPCInterface(with: UnderPillowXPCProtocol.self) 13 | let exportedObject = UnderPillowXPC() 14 | newConnection.exportedObject = exportedObject 15 | newConnection.resume() 16 | return true 17 | } 18 | } 19 | 20 | // 21 | //// This implements the example protocol. Replace the body of this class with the implementation of this service's protocol. 22 | //- (void)upperCaseString:(NSString *)aString withReply:(void (^)(NSString *))reply { 23 | // NSString *response = [aString uppercaseString]; 24 | // reply(response); 25 | //} 26 | 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](https://github.com/anastasiuspernat/DiffusionInfo/blob/main/UnderPillow/Assets.xcassets/AppIcon.appiconset/icon_256x256.png?raw=true) 2 | # UnderPillow 3 | A macOS Finder right-click menu extension that displays diffusion metadata (usually created by Python's Pillow) 4 | 5 | # Features 6 | - Right-click on a .png (or any other image) displays metadata info in macOS Finder 7 | - Click on the metadata to copy it to Clipboard 8 | - Displays **prompt, CFG scale, resolution** etc. added by common AI Art generators 9 | - Supports information from **Webui from AUTOMATIC1111, InvokeUI** etc 10 | 11 | ![](https://github.com/anastasiuspernat/UnderPillow/blob/main/Screenshot.jpg?raw=true) 12 | 13 | # Installation 14 | - Needs Python & Pillow installed on your macOS (will remove this dependancy) 15 | - **Download** from releases 16 | - Move from **Downloads to Applications** 17 | - Run app and **choose folders** you keep your images in 18 | - Go to  System Preferences -> Extensions -> Finder Extensions and enable **UnderPillow Finder** 19 | - You can now use new Finder's UnderPillow toolbar item to add folders to UnderPillow 20 | 21 | # TODO 22 | - Add comments to the code 23 | - Refresh folder in the app when added folders via Finder toolbar item 24 | - Don't display errors on the menu 25 | - Support more PNG data formats 26 | - Drop python requirement 27 | -------------------------------------------------------------------------------- /UnderPillow/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icon_16x16.png", 5 | "idiom" : "mac", 6 | "scale" : "1x", 7 | "size" : "16x16" 8 | }, 9 | { 10 | "filename" : "icon_16x16@2x.png", 11 | "idiom" : "mac", 12 | "scale" : "2x", 13 | "size" : "16x16" 14 | }, 15 | { 16 | "filename" : "icon_32x32.png", 17 | "idiom" : "mac", 18 | "scale" : "1x", 19 | "size" : "32x32" 20 | }, 21 | { 22 | "filename" : "icon_32x32@2x.png", 23 | "idiom" : "mac", 24 | "scale" : "2x", 25 | "size" : "32x32" 26 | }, 27 | { 28 | "filename" : "icon_128x128-1.png", 29 | "idiom" : "mac", 30 | "scale" : "1x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "filename" : "icon_128x128@2x.png", 35 | "idiom" : "mac", 36 | "scale" : "2x", 37 | "size" : "128x128" 38 | }, 39 | { 40 | "filename" : "icon_256x256.png", 41 | "idiom" : "mac", 42 | "scale" : "1x", 43 | "size" : "256x256" 44 | }, 45 | { 46 | "filename" : "icon_256x256@2x.png", 47 | "idiom" : "mac", 48 | "scale" : "2x", 49 | "size" : "256x256" 50 | }, 51 | { 52 | "filename" : "icon_512x512.png", 53 | "idiom" : "mac", 54 | "scale" : "1x", 55 | "size" : "512x512" 56 | }, 57 | { 58 | "filename" : "icon_512x512@2x.png", 59 | "idiom" : "mac", 60 | "scale" : "2x", 61 | "size" : "512x512" 62 | } 63 | ], 64 | "info" : { 65 | "author" : "xcode", 66 | "version" : 1 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /UnderPillowXPC/UnderPillowXPCProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UnderPillowXPCProtocol.h 3 | // UnderPillowXPC 4 | // 5 | // Created by Anastasiy on 11/8/22. 6 | // 7 | 8 | 9 | import Foundation 10 | 11 | // The protocol that this service will vend as its API. This header file will also need to be visible to the process hosting the service. 12 | @objc public protocol UnderPillowXPCProtocol { 13 | // func upperCaseString(_ string: String, withReply reply: @escaping (String) -> Void) 14 | 15 | func getFolders(withReply reply: @escaping (String) -> Void) 16 | func setFolders(_ folders: String, withReply reply: @escaping (Bool) -> Void) 17 | func getDiffusionData(withReply filePath:String, reply: @escaping (String) -> Void) 18 | } 19 | 20 | 21 | /* 22 | To use the service from an application or other process, use NSXPCConnection to establish a connection to the service by doing something like this: 23 | 24 | _connectionToService = [[NSXPCConnection alloc] initWithServiceName:@"Crispy-Driven-Pixels.UnderPillowXPC"]; 25 | _connectionToService.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(UnderPillowXPCProtocol)]; 26 | [_connectionToService resume]; 27 | 28 | Once you have a connection to the service, you can use it like this: 29 | 30 | [[_connectionToService remoteObjectProxy] upperCaseString:@"hello" withReply:^(NSString *aString) { 31 | // We have received a response. Update our text field, but do it on the main thread. 32 | NSLog(@"Result string was: %@", aString); 33 | }]; 34 | 35 | And, when you are finished with the service, clean up the connection like this: 36 | 37 | [_connectionToService invalidate]; 38 | */ 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | 28 | ## App packaging 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | .history/ 38 | 39 | # Swift Package Manager 40 | # 41 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 42 | # Packages/ 43 | # Package.pins 44 | # Package.resolved 45 | # *.xcodeproj 46 | # 47 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 48 | # hence it is not needed unless you have added a package configuration file to your project 49 | # .swiftpm 50 | 51 | .build/ 52 | 53 | # CocoaPods 54 | # 55 | # We recommend against adding the Pods directory to your .gitignore. However 56 | # you should judge for yourself, the pros and cons are mentioned at: 57 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 58 | # 59 | # Pods/ 60 | # 61 | # Add this line if you want to avoid checking in source code from the Xcode workspace 62 | # *.xcworkspace 63 | 64 | # Carthage 65 | # 66 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 67 | # Carthage/Checkouts 68 | 69 | Carthage/Build/ 70 | 71 | # Accio dependency management 72 | Dependencies/ 73 | .accio/ 74 | 75 | # fastlane 76 | # 77 | # It is recommended to not store the screenshots in the git repo. 78 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 79 | # For more information about the recommended setup visit: 80 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 81 | 82 | fastlane/report.xml 83 | fastlane/Preview.html 84 | fastlane/screenshots/**/*.png 85 | fastlane/test_output 86 | 87 | # Code Injection 88 | # 89 | # After new code Injection tools there's a generated folder /iOSInjectionProject 90 | # https://github.com/johnno1962/injectionforxcode 91 | 92 | iOSInjectionProject/ 93 | -------------------------------------------------------------------------------- /UnderPillowXPC/UnderPillowXPC.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UnderPillowXPC.h 3 | // 4 | // Created by Anastasiy on 11/8/22. 5 | // 6 | 7 | import Cocoa 8 | import FinderSync 9 | import ImageIO 10 | import Foundation 11 | 12 | // This object implements the protocol which we have defined. It provides the actual behavior for the service. It is 'exported' by the service to make it available to the process hosting the service over an NSXPCConnection. 13 | class UnderPillowXPC: NSObject, UnderPillowXPCProtocol { 14 | 15 | static let keyFolderSettings = "folderSettings" 16 | static let NotificationFoldersChanged = "FoldersChanged" 17 | static let myServiceName = "Crispy-Driven-Pixels.UnderPillowXPC" 18 | 19 | override init() { 20 | super.init() 21 | } 22 | 23 | func shell(_ command: String) -> String { 24 | let task = Process() 25 | let pipe = Pipe() 26 | 27 | task.standardOutput = pipe 28 | task.standardError = pipe 29 | task.arguments = ["-c", command] 30 | task.launchPath = "/bin/sh" 31 | task.standardInput = nil 32 | task.launch() 33 | 34 | let data = pipe.fileHandleForReading.readDataToEndOfFile() 35 | let output = String(data: data, encoding: .utf8)! 36 | 37 | return output 38 | } 39 | 40 | static func getService() -> UnderPillowXPCProtocol 41 | { 42 | let connection = NSXPCConnection(serviceName: UnderPillowXPC.myServiceName) 43 | connection.remoteObjectInterface = NSXPCInterface(with: UnderPillowXPCProtocol.self) 44 | connection.resume() 45 | 46 | let service = connection.remoteObjectProxyWithErrorHandler { error in 47 | print("Received error:", error) 48 | } as? UnderPillowXPCProtocol 49 | 50 | return service! 51 | } 52 | 53 | func getDiffusionData(withReply filePath:String, reply: @escaping (String) -> Void) { 54 | 55 | // TODO: replace with this when it's working 56 | // var UnderPillow: String = "" 57 | // if let imageSource = CGImageSourceCreateWithURL(URL(string: filePath)! as CFURL, nil) { 58 | // guard let imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) else { 59 | // return reply("") 60 | // } 61 | // if let dict = imageProperties as? [AnyHashable: Any] { 62 | // for (_, value) in dict { 63 | // UnderPillow += value as! String 64 | // } 65 | // } else 66 | // { 67 | // } 68 | // } else 69 | // { 70 | // } 71 | 72 | let UnderPillow: String = shell("python -c 'import sys; from PIL import Image; image = Image.open(\"\(filePath)\"); textinfo = image.text[\"parameters\"] if \"parameters\" in image.text else image.text[\"Dream\"]; print (textinfo);'") 73 | reply(UnderPillow) 74 | } 75 | 76 | 77 | func getFolders(withReply reply: @escaping (String) -> Void) { 78 | let defaults = UserDefaults.standard 79 | let folderSettings = [UnderPillowXPC.keyFolderSettings:defaults.object(forKey: UnderPillowXPC.keyFolderSettings)] 80 | 81 | if let theJSONData = try? JSONSerialization.data( 82 | withJSONObject: folderSettings, 83 | options: []) { 84 | let theJSONText = String(data: theJSONData, 85 | encoding: .utf8) 86 | reply(theJSONText!) 87 | } else 88 | { 89 | reply("{}") 90 | } 91 | 92 | } 93 | 94 | func setFolders(_ folders_dictJSON: String, withReply reply: @escaping (Bool) -> Void) { 95 | 96 | if let data = folders_dictJSON.data(using: .utf8) { 97 | if let folders_dict: NSDictionary = try? JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary ?? [:] { 98 | let userDefaults = UserDefaults.standard 99 | userDefaults.set(folders_dict[UnderPillowXPC.keyFolderSettings], forKey:UnderPillowXPC.keyFolderSettings) 100 | } 101 | } 102 | } 103 | 104 | } 105 | 106 | -------------------------------------------------------------------------------- /UnderPillow/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // UnderPillow 4 | // 5 | // Created by Anastasiy on 11/7/22. 6 | // 7 | 8 | import SwiftUI 9 | import FinderSync 10 | 11 | struct names { 12 | var id = 0 13 | var name = "" 14 | } 15 | 16 | @MainActor public class ListViewModel: ObservableObject { 17 | @Published var items: [String] = [] 18 | } 19 | 20 | struct ContentView: View { 21 | @State var selectKeeper = Set() 22 | @State var removeButtonDisabled = false 23 | @ObservedObject var viewModel = ListViewModel() 24 | 25 | var body: some View { 26 | HStack { 27 | VStack(alignment: .leading) { 28 | List(viewModel.items, id: \.self, selection: $selectKeeper){ name in 29 | Text(name) 30 | } 31 | .onAppear{ 32 | 33 | let service = UnderPillowXPC.getService() 34 | 35 | var folderPaths: [String] = [] 36 | 37 | let sem = DispatchSemaphore(value: 0) 38 | 39 | service.getFolders() { response in 40 | defer { 41 | sem.signal() 42 | } 43 | if let data = response.data(using: .utf8) { 44 | if let dict: NSDictionary = try? JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary ?? [:] { 45 | folderPaths = dict[UnderPillowXPC.keyFolderSettings] as? [String] ?? [] 46 | } 47 | } 48 | } 49 | 50 | if !Thread.isMainThread { 51 | let _ = sem.wait(timeout: .distantFuture) 52 | } else { 53 | while sem.wait(timeout: .now()) == .timedOut { 54 | RunLoop.current.run(mode: .default, before: Date(timeIntervalSinceNow: 0)) 55 | } 56 | } 57 | 58 | viewModel.items = [] 59 | for folderPath in folderPaths { 60 | viewModel.items.append(folderPath) 61 | } 62 | } // List 63 | .frame(maxWidth: .infinity) 64 | .padding(.bottom, 5) 65 | Button(action: { 66 | 67 | selectKeeper.forEach { item in 68 | viewModel.items.removeAll(where: { $0 == item }) 69 | } 70 | setFoldersFromList() 71 | 72 | }, label: { 73 | Text("Remove") 74 | }) // Button 75 | .disabled(removeButtonDisabled) 76 | } // VStack 77 | .padding(.bottom, 10) 78 | .padding(.leading, 10) 79 | .frame(alignment: .leading) 80 | VStack { 81 | Text("Click on the button below to select folders with images") 82 | .padding(.leading, 10) 83 | .padding(.trailing, 10) 84 | Button(action: { 85 | 86 | let dialog = NSOpenPanel(); 87 | 88 | dialog.showsResizeIndicator = true 89 | dialog.showsHiddenFiles = false 90 | dialog.canChooseDirectories = true 91 | dialog.canChooseFiles = false 92 | dialog.canCreateDirectories = false 93 | dialog.allowsMultipleSelection = false 94 | 95 | if (dialog.runModal() == NSApplication.ModalResponse.OK) { 96 | 97 | let newPath = dialog.url?.path; 98 | 99 | if (viewModel.items.firstIndex(where: {$0 == newPath}) == nil) { 100 | 101 | viewModel.items.append(newPath!) 102 | 103 | setFoldersFromList() 104 | } 105 | } else { 106 | // User clicked on "Cancel" 107 | return 108 | } 109 | }, label: { 110 | Text("Select folders") 111 | }) 112 | .padding(.bottom, 50) 113 | Button(action: { 114 | FIFinderSyncController.showExtensionManagementInterface() 115 | }, label: { 116 | Text("Enable Finder Extension") 117 | }) 118 | Spacer() 119 | .frame(height: 40) 120 | Text("Check for new versions and updates:") 121 | .font(.system(size: 11)) 122 | Text("Anastasiy Safari") 123 | .font(.system(size: 11)) 124 | Link("https://anastasiy.com/ai", destination: URL(string: "https://anastasiy.com/ai")!) 125 | .font(.system(size: 11)) 126 | } 127 | } 128 | } 129 | 130 | func setFoldersFromList() { 131 | 132 | let service = UnderPillowXPC.getService() 133 | 134 | let foldersStringsDict: NSMutableDictionary = [UnderPillowXPC.keyFolderSettings:viewModel.items] 135 | 136 | if let theJSONData = try? JSONSerialization.data( 137 | withJSONObject: foldersStringsDict, 138 | options: []) { 139 | 140 | let theJSONText = String(data: theJSONData, 141 | encoding: .utf8) 142 | 143 | service.setFolders( theJSONText! ) { response in 144 | print("Response from XPC service(2):", response) 145 | } 146 | 147 | DistributedNotificationCenter.default().postNotificationName(NSNotification.Name(UnderPillowXPC.NotificationFoldersChanged), object: theJSONText, userInfo: nil, options: [.deliverImmediately]) 148 | } 149 | } 150 | 151 | } 152 | 153 | 154 | struct ContentView_Previews: PreviewProvider { 155 | static var previews: some View { 156 | ContentView() 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /UnderPillow Finder/FinderSync.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FinderSync.swift 3 | // UnderPillow Finder 4 | // 5 | // Created by Anastasiy on 11/7/22. 6 | // 7 | 8 | import Cocoa 9 | import FinderSync 10 | import ImageIO 11 | import Foundation 12 | 13 | class FinderSync: FIFinderSync { 14 | 15 | var currentFile: URL? 16 | var folderUrls: [URL] = [] 17 | 18 | override init() { 19 | super.init() 20 | 21 | FIFinderSyncController.default().directoryURLs = [] 22 | 23 | let service = UnderPillowXPC.getService() 24 | 25 | service.getFolders() { response in 26 | 27 | self.getFoldersFromJSONSettingsAndRefreshFolderURLs(jsonString: response) 28 | 29 | } 30 | 31 | // Set up images for our badge identifiers. For demonstration purposes, this uses off-the-shelf images. 32 | FIFinderSyncController.default().setBadgeImage(NSImage(named: NSImage.colorPanelName)!, label: "Status One" , forBadgeIdentifier: "One") 33 | FIFinderSyncController.default().setBadgeImage(NSImage(named: NSImage.cautionName)!, label: "Status Two", forBadgeIdentifier: "Two") 34 | 35 | DistributedNotificationCenter.default().addObserver(self, selector: #selector(self.foldersChanged(_:)), name: NSNotification.Name(UnderPillowXPC.NotificationFoldersChanged), object: nil) 36 | } 37 | 38 | func getFoldersFromJSONSettingsAndRefreshFolderURLs( jsonString: String ) 39 | { 40 | if let data = jsonString.data(using: .utf8) { 41 | if let foldersSettings: NSDictionary = try? JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary ?? [:] { 42 | let folderPaths: [String] = foldersSettings[UnderPillowXPC.keyFolderSettings] as? [String] ?? [] 43 | self.refreshFolderURLsFrom(folderPaths: folderPaths) 44 | } 45 | } 46 | 47 | } 48 | 49 | func refreshFolderURLsFrom( folderPaths: [String] ) 50 | { 51 | folderUrls = [] 52 | for folderStr in folderPaths 53 | { 54 | folderUrls.append(URL(fileURLWithPath:folderStr)) 55 | } 56 | FIFinderSyncController.default().directoryURLs = Set(folderUrls) 57 | } 58 | 59 | deinit { 60 | DistributedNotificationCenter.default().removeObserver(self, name: NSNotification.Name(UnderPillowXPC.NotificationFoldersChanged), object: nil) 61 | } 62 | 63 | @objc func foldersChanged(_ notification: Notification ) { 64 | 65 | let folderSettingsJSON: String = notification.object as! String 66 | self.getFoldersFromJSONSettingsAndRefreshFolderURLs( jsonString:folderSettingsJSON ); 67 | 68 | } 69 | 70 | 71 | override func beginObservingDirectory(at url: URL) { 72 | // The user is now seeing the container's contents. 73 | // If they see it in more than one view at a time, we're only told once. 74 | // NSLog("beginObservingDirectoryAtURL: %@", url.path as NSString) 75 | } 76 | 77 | 78 | override func endObservingDirectory(at url: URL) { 79 | // The user is no longer seeing the container's contents. 80 | // NSLog("endObservingDirectoryAtURL: %@", url.path as NSString) 81 | } 82 | 83 | override func requestBadgeIdentifier(for url: URL) { 84 | // NSLog("requestBadgeIdentifierForURL: %@", url.path as NSString) 85 | 86 | // For demonstration purposes, this picks one of our two badges, or no badge at all, based on the filename. 87 | // let whichBadge = abs(url.path.hash) % 3 88 | // let badgeIdentifier = ["", "One", "Two"][whichBadge] 89 | // FIFinderSyncController.default().setBadgeIdentifier(badgeIdentifier, for: url) 90 | } 91 | 92 | // MARK: - Menu and toolbar item support 93 | 94 | override var toolbarItemName: String { 95 | return "UnderPillow" 96 | } 97 | 98 | override var toolbarItemToolTip: String { 99 | return "UnderPillow: Click the toolbar item for a menu." 100 | } 101 | 102 | override var toolbarItemImage: NSImage { 103 | return NSApp.applicationIconImage 104 | } 105 | 106 | func shell(_ command: String) -> String { 107 | let task = Process() 108 | let pipe = Pipe() 109 | 110 | task.standardOutput = pipe 111 | task.standardError = pipe 112 | task.arguments = ["-c", command] 113 | task.launchPath = "/bin/sh" 114 | task.standardInput = nil 115 | task.launch() 116 | 117 | let data = pipe.fileHandleForReading.readDataToEndOfFile() 118 | let output = String(data: data, encoding: .utf8)! 119 | 120 | return output 121 | } 122 | 123 | // Note that this also can produce menu items for Finder toolbar 124 | override func menu(for menuKind: FIMenuKind) -> NSMenu? { 125 | // Produce a menu for the extension. 126 | 127 | if (menuKind == .toolbarItemMenu) { 128 | let menu = NSMenu(title: "") 129 | var folderInUnderPillow = false 130 | if let target = FIFinderSyncController.default().targetedURL() { 131 | let existingPaths = folderUrls.compactMap { $0.path } 132 | let currentPath = target.path 133 | if existingPaths.contains(currentPath) { 134 | folderInUnderPillow = true 135 | } 136 | } 137 | if (folderInUnderPillow) 138 | { 139 | let item = menu.addItem(withTitle: "Folder in UnderPillow", action: nil, keyEquivalent: "") 140 | item.isEnabled = false 141 | } else { 142 | menu.addItem(withTitle: "Add folder to UnderPillow", action: #selector(addToUnderPillow(_:)), keyEquivalent: "") 143 | } 144 | menu.addItem(withTitle: "Launch UnderPillow", action: #selector(launchUnderPillow(_:)), keyEquivalent: "") 145 | return menu 146 | } else 147 | if (menuKind == .contextualMenuForItems) { 148 | guard let items = FIFinderSyncController.default().selectedItemURLs(), items.count == 1, let item = items.first, let uti = try? item.resourceValues(forKeys: [.typeIdentifierKey]).typeIdentifier else { 149 | currentFile = nil 150 | return nil 151 | } 152 | 153 | currentFile = item 154 | let menu = NSMenu(title: "") 155 | 156 | let service = UnderPillowXPC.getService() 157 | 158 | var UnderPillow = "" 159 | 160 | let sem = DispatchSemaphore(value: 0) 161 | 162 | service.getDiffusionData(withReply: item.path) { response in 163 | defer { 164 | sem.signal() 165 | } 166 | UnderPillow = response 167 | } 168 | 169 | if !Thread.isMainThread { 170 | let _ = sem.wait(timeout: .distantFuture) 171 | } else { 172 | while sem.wait(timeout: .now()) == .timedOut { 173 | RunLoop.current.run(mode: .default, before: Date(timeIntervalSinceNow: 0)) 174 | } 175 | } 176 | 177 | if (UTTypeConformsTo(uti as CFString, kUTTypeImage)) { 178 | menu.addItem(withTitle: "Under Pillow", action: #selector(copyMenuToClipboard(_:)), keyEquivalent: "") 179 | let lines = UnderPillow.split(whereSeparator: \.isNewline) 180 | for line in lines { 181 | menu.addItem(withTitle: String(line), action: #selector(copyMenuToClipboard(_:)), keyEquivalent: "") 182 | } 183 | } 184 | 185 | return menu 186 | } else { 187 | return nil 188 | } 189 | 190 | } 191 | 192 | @IBAction func addToUnderPillow(_ sender: AnyObject?) { 193 | let target = FIFinderSyncController.default().targetedURL() 194 | 195 | folderUrls.append( URL(fileURLWithPath: target!.path) ); 196 | let urlStrings = folderUrls.compactMap { $0.path } 197 | 198 | let service = UnderPillowXPC.getService() 199 | 200 | let foldersStringsDict: NSMutableDictionary = [UnderPillowXPC.keyFolderSettings:urlStrings] 201 | 202 | if let theJSONData = try? JSONSerialization.data( 203 | withJSONObject: foldersStringsDict, 204 | options: []) { 205 | 206 | let theJSONText = String(data: theJSONData, 207 | encoding: .utf8) 208 | 209 | service.setFolders( theJSONText! ) { response in 210 | print("Response from XPC service(2):", response) 211 | } 212 | } 213 | 214 | FIFinderSyncController.default().directoryURLs = Set(folderUrls) 215 | } 216 | 217 | @IBAction func launchUnderPillow(_ sender: AnyObject?) { 218 | 219 | NSWorkspace.shared.open(URL(string:"underpillow://")!) 220 | 221 | } 222 | 223 | @IBAction func copyMenuToClipboard(_ sender: AnyObject?) { 224 | let item = sender as! NSMenuItem 225 | let pasteboard = NSPasteboard.general 226 | pasteboard.declareTypes([.string], owner: nil) 227 | pasteboard.setString(item.title, forType: .string) 228 | } 229 | 230 | } 231 | 232 | -------------------------------------------------------------------------------- /UnderPillow.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 55; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | DD180E39291AD38500E23D59 /* UnderPillowXPCDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD180E38291AD38500E23D59 /* UnderPillowXPCDelegate.swift */; }; 11 | DD180E3B291AD38500E23D59 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD180E3A291AD38500E23D59 /* main.swift */; }; 12 | DD180E3F291AD38500E23D59 /* UnderPillowXPC.xpc in Embed XPC Services */ = {isa = PBXBuildFile; fileRef = DD180E34291AD38500E23D59 /* UnderPillowXPC.xpc */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 13 | DD180E44291AF1EA00E23D59 /* UnderPillowXPCProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD180E36291AD38500E23D59 /* UnderPillowXPCProtocol.swift */; }; 14 | DD180E45291AF1EA00E23D59 /* UnderPillowXPC.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD180E37291AD38500E23D59 /* UnderPillowXPC.swift */; }; 15 | DD180E46291AF1EA00E23D59 /* UnderPillowXPCDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD180E38291AD38500E23D59 /* UnderPillowXPCDelegate.swift */; }; 16 | DD180E47291AF41D00E23D59 /* UnderPillowXPCProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD180E36291AD38500E23D59 /* UnderPillowXPCProtocol.swift */; }; 17 | DD180E48291AF41D00E23D59 /* UnderPillowXPC.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD180E37291AD38500E23D59 /* UnderPillowXPC.swift */; }; 18 | DD180E49291AF8B800E23D59 /* UnderPillowXPCProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD180E36291AD38500E23D59 /* UnderPillowXPCProtocol.swift */; }; 19 | DD180E4A291AF8B800E23D59 /* UnderPillowXPC.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD180E37291AD38500E23D59 /* UnderPillowXPC.swift */; }; 20 | DD180E4F291B14DF00E23D59 /* UnderPillowXPC.xpc in CopyFiles */ = {isa = PBXBuildFile; fileRef = DD180E34291AD38500E23D59 /* UnderPillowXPC.xpc */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 21 | DDF18A022919D4A700BC2201 /* UnderPillowApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF18A012919D4A700BC2201 /* UnderPillowApp.swift */; }; 22 | DDF18A042919D4A700BC2201 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF18A032919D4A700BC2201 /* ContentView.swift */; }; 23 | DDF18A062919D4AA00BC2201 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDF18A052919D4AA00BC2201 /* Assets.xcassets */; }; 24 | DDF18A092919D4AA00BC2201 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDF18A082919D4AA00BC2201 /* Preview Assets.xcassets */; }; 25 | DDF18A172919D4CC00BC2201 /* FinderSync.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF18A162919D4CC00BC2201 /* FinderSync.swift */; }; 26 | DDF18A1C2919D4CC00BC2201 /* UnderPillow Finder.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = DDF18A142919D4CC00BC2201 /* UnderPillow Finder.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXContainerItemProxy section */ 30 | DD180E3D291AD38500E23D59 /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = DDF189F62919D4A700BC2201 /* Project object */; 33 | proxyType = 1; 34 | remoteGlobalIDString = DD180E33291AD38500E23D59; 35 | remoteInfo = UnderPillowXPC; 36 | }; 37 | DD180E4C291B14AE00E23D59 /* PBXContainerItemProxy */ = { 38 | isa = PBXContainerItemProxy; 39 | containerPortal = DDF189F62919D4A700BC2201 /* Project object */; 40 | proxyType = 1; 41 | remoteGlobalIDString = DD180E33291AD38500E23D59; 42 | remoteInfo = UnderPillowXPC; 43 | }; 44 | DDF18A1A2919D4CC00BC2201 /* PBXContainerItemProxy */ = { 45 | isa = PBXContainerItemProxy; 46 | containerPortal = DDF189F62919D4A700BC2201 /* Project object */; 47 | proxyType = 1; 48 | remoteGlobalIDString = DDF18A132919D4CC00BC2201; 49 | remoteInfo = "UnderPillow Finder"; 50 | }; 51 | /* End PBXContainerItemProxy section */ 52 | 53 | /* Begin PBXCopyFilesBuildPhase section */ 54 | DD180E43291AD38500E23D59 /* Embed XPC Services */ = { 55 | isa = PBXCopyFilesBuildPhase; 56 | buildActionMask = 2147483647; 57 | dstPath = "$(CONTENTS_FOLDER_PATH)/XPCServices"; 58 | dstSubfolderSpec = 16; 59 | files = ( 60 | DD180E3F291AD38500E23D59 /* UnderPillowXPC.xpc in Embed XPC Services */, 61 | ); 62 | name = "Embed XPC Services"; 63 | runOnlyForDeploymentPostprocessing = 0; 64 | }; 65 | DD180E4E291B14CD00E23D59 /* CopyFiles */ = { 66 | isa = PBXCopyFilesBuildPhase; 67 | buildActionMask = 2147483647; 68 | dstPath = "$(CONTENTS_FOLDER_PATH)/XPCServices"; 69 | dstSubfolderSpec = 16; 70 | files = ( 71 | DD180E4F291B14DF00E23D59 /* UnderPillowXPC.xpc in CopyFiles */, 72 | ); 73 | runOnlyForDeploymentPostprocessing = 0; 74 | }; 75 | DDF18A202919D4CC00BC2201 /* Embed App Extensions */ = { 76 | isa = PBXCopyFilesBuildPhase; 77 | buildActionMask = 2147483647; 78 | dstPath = ""; 79 | dstSubfolderSpec = 13; 80 | files = ( 81 | DDF18A1C2919D4CC00BC2201 /* UnderPillow Finder.appex in Embed App Extensions */, 82 | ); 83 | name = "Embed App Extensions"; 84 | runOnlyForDeploymentPostprocessing = 0; 85 | }; 86 | /* End PBXCopyFilesBuildPhase section */ 87 | 88 | /* Begin PBXFileReference section */ 89 | DD180E34291AD38500E23D59 /* UnderPillowXPC.xpc */ = {isa = PBXFileReference; explicitFileType = "wrapper.xpc-service"; includeInIndex = 0; path = UnderPillowXPC.xpc; sourceTree = BUILT_PRODUCTS_DIR; }; 90 | DD180E36291AD38500E23D59 /* UnderPillowXPCProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnderPillowXPCProtocol.swift; sourceTree = ""; }; 91 | DD180E37291AD38500E23D59 /* UnderPillowXPC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnderPillowXPC.swift; sourceTree = ""; }; 92 | DD180E38291AD38500E23D59 /* UnderPillowXPCDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnderPillowXPCDelegate.swift; sourceTree = ""; }; 93 | DD180E3A291AD38500E23D59 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; 94 | DD180E3C291AD38500E23D59 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 95 | DD428DD829355C4300743250 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 96 | DDF189FE2919D4A700BC2201 /* UnderPillow.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UnderPillow.app; sourceTree = BUILT_PRODUCTS_DIR; }; 97 | DDF18A012919D4A700BC2201 /* UnderPillowApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnderPillowApp.swift; sourceTree = ""; }; 98 | DDF18A032919D4A700BC2201 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 99 | DDF18A052919D4AA00BC2201 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 100 | DDF18A082919D4AA00BC2201 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 101 | DDF18A0A2919D4AA00BC2201 /* UnderPillow.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = UnderPillow.entitlements; sourceTree = ""; }; 102 | DDF18A142919D4CC00BC2201 /* UnderPillow Finder.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "UnderPillow Finder.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; 103 | DDF18A162919D4CC00BC2201 /* FinderSync.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FinderSync.swift; sourceTree = ""; }; 104 | DDF18A182919D4CC00BC2201 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 105 | DDF18A192919D4CC00BC2201 /* UnderPillow_Finder.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = UnderPillow_Finder.entitlements; sourceTree = ""; }; 106 | /* End PBXFileReference section */ 107 | 108 | /* Begin PBXFrameworksBuildPhase section */ 109 | DD180E31291AD38500E23D59 /* Frameworks */ = { 110 | isa = PBXFrameworksBuildPhase; 111 | buildActionMask = 2147483647; 112 | files = ( 113 | ); 114 | runOnlyForDeploymentPostprocessing = 0; 115 | }; 116 | DDF189FB2919D4A700BC2201 /* Frameworks */ = { 117 | isa = PBXFrameworksBuildPhase; 118 | buildActionMask = 2147483647; 119 | files = ( 120 | ); 121 | runOnlyForDeploymentPostprocessing = 0; 122 | }; 123 | DDF18A112919D4CC00BC2201 /* Frameworks */ = { 124 | isa = PBXFrameworksBuildPhase; 125 | buildActionMask = 2147483647; 126 | files = ( 127 | ); 128 | runOnlyForDeploymentPostprocessing = 0; 129 | }; 130 | /* End PBXFrameworksBuildPhase section */ 131 | 132 | /* Begin PBXGroup section */ 133 | DD180E35291AD38500E23D59 /* UnderPillowXPC */ = { 134 | isa = PBXGroup; 135 | children = ( 136 | DD180E36291AD38500E23D59 /* UnderPillowXPCProtocol.swift */, 137 | DD180E37291AD38500E23D59 /* UnderPillowXPC.swift */, 138 | DD180E38291AD38500E23D59 /* UnderPillowXPCDelegate.swift */, 139 | DD180E3A291AD38500E23D59 /* main.swift */, 140 | DD180E3C291AD38500E23D59 /* Info.plist */, 141 | ); 142 | path = UnderPillowXPC; 143 | sourceTree = ""; 144 | }; 145 | DDF189F52919D4A700BC2201 = { 146 | isa = PBXGroup; 147 | children = ( 148 | DDF18A002919D4A700BC2201 /* UnderPillow */, 149 | DDF18A152919D4CC00BC2201 /* UnderPillow Finder */, 150 | DD180E35291AD38500E23D59 /* UnderPillowXPC */, 151 | DDF189FF2919D4A700BC2201 /* Products */, 152 | DDF18A242919EBF300BC2201 /* Frameworks */, 153 | ); 154 | sourceTree = ""; 155 | }; 156 | DDF189FF2919D4A700BC2201 /* Products */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | DDF189FE2919D4A700BC2201 /* UnderPillow.app */, 160 | DDF18A142919D4CC00BC2201 /* UnderPillow Finder.appex */, 161 | DD180E34291AD38500E23D59 /* UnderPillowXPC.xpc */, 162 | ); 163 | name = Products; 164 | sourceTree = ""; 165 | }; 166 | DDF18A002919D4A700BC2201 /* UnderPillow */ = { 167 | isa = PBXGroup; 168 | children = ( 169 | DD428DD829355C4300743250 /* Info.plist */, 170 | DDF18A012919D4A700BC2201 /* UnderPillowApp.swift */, 171 | DDF18A032919D4A700BC2201 /* ContentView.swift */, 172 | DDF18A052919D4AA00BC2201 /* Assets.xcassets */, 173 | DDF18A0A2919D4AA00BC2201 /* UnderPillow.entitlements */, 174 | DDF18A072919D4AA00BC2201 /* Preview Content */, 175 | ); 176 | path = UnderPillow; 177 | sourceTree = ""; 178 | }; 179 | DDF18A072919D4AA00BC2201 /* Preview Content */ = { 180 | isa = PBXGroup; 181 | children = ( 182 | DDF18A082919D4AA00BC2201 /* Preview Assets.xcassets */, 183 | ); 184 | path = "Preview Content"; 185 | sourceTree = ""; 186 | }; 187 | DDF18A152919D4CC00BC2201 /* UnderPillow Finder */ = { 188 | isa = PBXGroup; 189 | children = ( 190 | DDF18A162919D4CC00BC2201 /* FinderSync.swift */, 191 | DDF18A182919D4CC00BC2201 /* Info.plist */, 192 | DDF18A192919D4CC00BC2201 /* UnderPillow_Finder.entitlements */, 193 | ); 194 | path = "UnderPillow Finder"; 195 | sourceTree = ""; 196 | }; 197 | DDF18A242919EBF300BC2201 /* Frameworks */ = { 198 | isa = PBXGroup; 199 | children = ( 200 | ); 201 | name = Frameworks; 202 | sourceTree = ""; 203 | }; 204 | /* End PBXGroup section */ 205 | 206 | /* Begin PBXNativeTarget section */ 207 | DD180E33291AD38500E23D59 /* UnderPillowXPC */ = { 208 | isa = PBXNativeTarget; 209 | buildConfigurationList = DD180E40291AD38500E23D59 /* Build configuration list for PBXNativeTarget "UnderPillowXPC" */; 210 | buildPhases = ( 211 | DD180E30291AD38500E23D59 /* Sources */, 212 | DD180E31291AD38500E23D59 /* Frameworks */, 213 | DD180E32291AD38500E23D59 /* Resources */, 214 | ); 215 | buildRules = ( 216 | ); 217 | dependencies = ( 218 | ); 219 | name = UnderPillowXPC; 220 | productName = UnderPillowXPC; 221 | productReference = DD180E34291AD38500E23D59 /* UnderPillowXPC.xpc */; 222 | productType = "com.apple.product-type.xpc-service"; 223 | }; 224 | DDF189FD2919D4A700BC2201 /* UnderPillow */ = { 225 | isa = PBXNativeTarget; 226 | buildConfigurationList = DDF18A0D2919D4AA00BC2201 /* Build configuration list for PBXNativeTarget "UnderPillow" */; 227 | buildPhases = ( 228 | DDF189FA2919D4A700BC2201 /* Sources */, 229 | DDF189FB2919D4A700BC2201 /* Frameworks */, 230 | DDF189FC2919D4A700BC2201 /* Resources */, 231 | DDF18A202919D4CC00BC2201 /* Embed App Extensions */, 232 | DD180E43291AD38500E23D59 /* Embed XPC Services */, 233 | ); 234 | buildRules = ( 235 | ); 236 | dependencies = ( 237 | DDF18A1B2919D4CC00BC2201 /* PBXTargetDependency */, 238 | DD180E3E291AD38500E23D59 /* PBXTargetDependency */, 239 | ); 240 | name = UnderPillow; 241 | packageProductDependencies = ( 242 | ); 243 | productName = UnderPillow; 244 | productReference = DDF189FE2919D4A700BC2201 /* UnderPillow.app */; 245 | productType = "com.apple.product-type.application"; 246 | }; 247 | DDF18A132919D4CC00BC2201 /* UnderPillow Finder */ = { 248 | isa = PBXNativeTarget; 249 | buildConfigurationList = DDF18A1D2919D4CC00BC2201 /* Build configuration list for PBXNativeTarget "UnderPillow Finder" */; 250 | buildPhases = ( 251 | DDF18A102919D4CC00BC2201 /* Sources */, 252 | DDF18A112919D4CC00BC2201 /* Frameworks */, 253 | DDF18A122919D4CC00BC2201 /* Resources */, 254 | DD180E4E291B14CD00E23D59 /* CopyFiles */, 255 | ); 256 | buildRules = ( 257 | ); 258 | dependencies = ( 259 | DD180E4D291B14AE00E23D59 /* PBXTargetDependency */, 260 | ); 261 | name = "UnderPillow Finder"; 262 | packageProductDependencies = ( 263 | ); 264 | productName = "UnderPillow Finder"; 265 | productReference = DDF18A142919D4CC00BC2201 /* UnderPillow Finder.appex */; 266 | productType = "com.apple.product-type.app-extension"; 267 | }; 268 | /* End PBXNativeTarget section */ 269 | 270 | /* Begin PBXProject section */ 271 | DDF189F62919D4A700BC2201 /* Project object */ = { 272 | isa = PBXProject; 273 | attributes = { 274 | BuildIndependentTargetsInParallel = 1; 275 | LastSwiftUpdateCheck = 1310; 276 | LastUpgradeCheck = 1310; 277 | TargetAttributes = { 278 | DD180E33291AD38500E23D59 = { 279 | CreatedOnToolsVersion = 13.1; 280 | }; 281 | DDF189FD2919D4A700BC2201 = { 282 | CreatedOnToolsVersion = 13.1; 283 | }; 284 | DDF18A132919D4CC00BC2201 = { 285 | CreatedOnToolsVersion = 13.1; 286 | }; 287 | }; 288 | }; 289 | buildConfigurationList = DDF189F92919D4A700BC2201 /* Build configuration list for PBXProject "UnderPillow" */; 290 | compatibilityVersion = "Xcode 13.0"; 291 | developmentRegion = en; 292 | hasScannedForEncodings = 0; 293 | knownRegions = ( 294 | en, 295 | Base, 296 | ); 297 | mainGroup = DDF189F52919D4A700BC2201; 298 | packageReferences = ( 299 | ); 300 | productRefGroup = DDF189FF2919D4A700BC2201 /* Products */; 301 | projectDirPath = ""; 302 | projectRoot = ""; 303 | targets = ( 304 | DDF189FD2919D4A700BC2201 /* UnderPillow */, 305 | DDF18A132919D4CC00BC2201 /* UnderPillow Finder */, 306 | DD180E33291AD38500E23D59 /* UnderPillowXPC */, 307 | ); 308 | }; 309 | /* End PBXProject section */ 310 | 311 | /* Begin PBXResourcesBuildPhase section */ 312 | DD180E32291AD38500E23D59 /* Resources */ = { 313 | isa = PBXResourcesBuildPhase; 314 | buildActionMask = 2147483647; 315 | files = ( 316 | ); 317 | runOnlyForDeploymentPostprocessing = 0; 318 | }; 319 | DDF189FC2919D4A700BC2201 /* Resources */ = { 320 | isa = PBXResourcesBuildPhase; 321 | buildActionMask = 2147483647; 322 | files = ( 323 | DDF18A092919D4AA00BC2201 /* Preview Assets.xcassets in Resources */, 324 | DDF18A062919D4AA00BC2201 /* Assets.xcassets in Resources */, 325 | ); 326 | runOnlyForDeploymentPostprocessing = 0; 327 | }; 328 | DDF18A122919D4CC00BC2201 /* Resources */ = { 329 | isa = PBXResourcesBuildPhase; 330 | buildActionMask = 2147483647; 331 | files = ( 332 | ); 333 | runOnlyForDeploymentPostprocessing = 0; 334 | }; 335 | /* End PBXResourcesBuildPhase section */ 336 | 337 | /* Begin PBXSourcesBuildPhase section */ 338 | DD180E30291AD38500E23D59 /* Sources */ = { 339 | isa = PBXSourcesBuildPhase; 340 | buildActionMask = 2147483647; 341 | files = ( 342 | DD180E47291AF41D00E23D59 /* UnderPillowXPCProtocol.swift in Sources */, 343 | DD180E48291AF41D00E23D59 /* UnderPillowXPC.swift in Sources */, 344 | DD180E3B291AD38500E23D59 /* main.swift in Sources */, 345 | DD180E39291AD38500E23D59 /* UnderPillowXPCDelegate.swift in Sources */, 346 | ); 347 | runOnlyForDeploymentPostprocessing = 0; 348 | }; 349 | DDF189FA2919D4A700BC2201 /* Sources */ = { 350 | isa = PBXSourcesBuildPhase; 351 | buildActionMask = 2147483647; 352 | files = ( 353 | DD180E49291AF8B800E23D59 /* UnderPillowXPCProtocol.swift in Sources */, 354 | DD180E4A291AF8B800E23D59 /* UnderPillowXPC.swift in Sources */, 355 | DDF18A042919D4A700BC2201 /* ContentView.swift in Sources */, 356 | DDF18A022919D4A700BC2201 /* UnderPillowApp.swift in Sources */, 357 | ); 358 | runOnlyForDeploymentPostprocessing = 0; 359 | }; 360 | DDF18A102919D4CC00BC2201 /* Sources */ = { 361 | isa = PBXSourcesBuildPhase; 362 | buildActionMask = 2147483647; 363 | files = ( 364 | DD180E44291AF1EA00E23D59 /* UnderPillowXPCProtocol.swift in Sources */, 365 | DD180E45291AF1EA00E23D59 /* UnderPillowXPC.swift in Sources */, 366 | DD180E46291AF1EA00E23D59 /* UnderPillowXPCDelegate.swift in Sources */, 367 | DDF18A172919D4CC00BC2201 /* FinderSync.swift in Sources */, 368 | ); 369 | runOnlyForDeploymentPostprocessing = 0; 370 | }; 371 | /* End PBXSourcesBuildPhase section */ 372 | 373 | /* Begin PBXTargetDependency section */ 374 | DD180E3E291AD38500E23D59 /* PBXTargetDependency */ = { 375 | isa = PBXTargetDependency; 376 | target = DD180E33291AD38500E23D59 /* UnderPillowXPC */; 377 | targetProxy = DD180E3D291AD38500E23D59 /* PBXContainerItemProxy */; 378 | }; 379 | DD180E4D291B14AE00E23D59 /* PBXTargetDependency */ = { 380 | isa = PBXTargetDependency; 381 | target = DD180E33291AD38500E23D59 /* UnderPillowXPC */; 382 | targetProxy = DD180E4C291B14AE00E23D59 /* PBXContainerItemProxy */; 383 | }; 384 | DDF18A1B2919D4CC00BC2201 /* PBXTargetDependency */ = { 385 | isa = PBXTargetDependency; 386 | target = DDF18A132919D4CC00BC2201 /* UnderPillow Finder */; 387 | targetProxy = DDF18A1A2919D4CC00BC2201 /* PBXContainerItemProxy */; 388 | }; 389 | /* End PBXTargetDependency section */ 390 | 391 | /* Begin XCBuildConfiguration section */ 392 | DD180E41291AD38500E23D59 /* Debug */ = { 393 | isa = XCBuildConfiguration; 394 | buildSettings = { 395 | CODE_SIGN_IDENTITY = "Developer ID Application"; 396 | CODE_SIGN_STYLE = Manual; 397 | COMBINE_HIDPI_IMAGES = YES; 398 | CURRENT_PROJECT_VERSION = 1; 399 | DEVELOPMENT_TEAM = D3SBBNFWTC; 400 | ENABLE_HARDENED_RUNTIME = YES; 401 | GENERATE_INFOPLIST_FILE = YES; 402 | INFOPLIST_FILE = UnderPillowXPC/Info.plist; 403 | INFOPLIST_KEY_CFBundleDisplayName = UnderPillowXPC; 404 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 405 | MARKETING_VERSION = 0.6; 406 | PRODUCT_BUNDLE_IDENTIFIER = "Crispy-Driven-Pixels.UnderPillowXPC"; 407 | PRODUCT_NAME = "$(TARGET_NAME)"; 408 | PROVISIONING_PROFILE_SPECIFIER = ""; 409 | SKIP_INSTALL = YES; 410 | SWIFT_EMIT_LOC_STRINGS = YES; 411 | SWIFT_INSTALL_OBJC_HEADER = NO; 412 | SWIFT_OBJC_INTERFACE_HEADER_NAME = ""; 413 | SWIFT_VERSION = 5.0; 414 | }; 415 | name = Debug; 416 | }; 417 | DD180E42291AD38500E23D59 /* Release */ = { 418 | isa = XCBuildConfiguration; 419 | buildSettings = { 420 | CODE_SIGN_IDENTITY = "Developer ID Application"; 421 | CODE_SIGN_STYLE = Manual; 422 | COMBINE_HIDPI_IMAGES = YES; 423 | CURRENT_PROJECT_VERSION = 1; 424 | DEVELOPMENT_TEAM = D3SBBNFWTC; 425 | ENABLE_HARDENED_RUNTIME = YES; 426 | GENERATE_INFOPLIST_FILE = YES; 427 | INFOPLIST_FILE = UnderPillowXPC/Info.plist; 428 | INFOPLIST_KEY_CFBundleDisplayName = UnderPillowXPC; 429 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 430 | MARKETING_VERSION = 0.6; 431 | PRODUCT_BUNDLE_IDENTIFIER = "Crispy-Driven-Pixels.UnderPillowXPC"; 432 | PRODUCT_NAME = "$(TARGET_NAME)"; 433 | PROVISIONING_PROFILE_SPECIFIER = ""; 434 | SKIP_INSTALL = YES; 435 | SWIFT_EMIT_LOC_STRINGS = YES; 436 | SWIFT_INSTALL_OBJC_HEADER = NO; 437 | SWIFT_OBJC_INTERFACE_HEADER_NAME = ""; 438 | SWIFT_VERSION = 5.0; 439 | }; 440 | name = Release; 441 | }; 442 | DDF18A0B2919D4AA00BC2201 /* Debug */ = { 443 | isa = XCBuildConfiguration; 444 | buildSettings = { 445 | ALWAYS_SEARCH_USER_PATHS = NO; 446 | CLANG_ANALYZER_NONNULL = YES; 447 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 448 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 449 | CLANG_CXX_LIBRARY = "libc++"; 450 | CLANG_ENABLE_MODULES = YES; 451 | CLANG_ENABLE_OBJC_ARC = YES; 452 | CLANG_ENABLE_OBJC_WEAK = YES; 453 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 454 | CLANG_WARN_BOOL_CONVERSION = YES; 455 | CLANG_WARN_COMMA = YES; 456 | CLANG_WARN_CONSTANT_CONVERSION = YES; 457 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 458 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 459 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 460 | CLANG_WARN_EMPTY_BODY = YES; 461 | CLANG_WARN_ENUM_CONVERSION = YES; 462 | CLANG_WARN_INFINITE_RECURSION = YES; 463 | CLANG_WARN_INT_CONVERSION = YES; 464 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 465 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 466 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 467 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 468 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 469 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 470 | CLANG_WARN_STRICT_PROTOTYPES = YES; 471 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 472 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 473 | CLANG_WARN_UNREACHABLE_CODE = YES; 474 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 475 | COPY_PHASE_STRIP = NO; 476 | DEBUG_INFORMATION_FORMAT = dwarf; 477 | ENABLE_STRICT_OBJC_MSGSEND = YES; 478 | ENABLE_TESTABILITY = YES; 479 | GCC_C_LANGUAGE_STANDARD = gnu11; 480 | GCC_DYNAMIC_NO_PIC = NO; 481 | GCC_NO_COMMON_BLOCKS = YES; 482 | GCC_OPTIMIZATION_LEVEL = 0; 483 | GCC_PREPROCESSOR_DEFINITIONS = ( 484 | "DEBUG=1", 485 | "$(inherited)", 486 | ); 487 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 488 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 489 | GCC_WARN_UNDECLARED_SELECTOR = YES; 490 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 491 | GCC_WARN_UNUSED_FUNCTION = YES; 492 | GCC_WARN_UNUSED_VARIABLE = YES; 493 | MACOSX_DEPLOYMENT_TARGET = 11.7; 494 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 495 | MTL_FAST_MATH = YES; 496 | ONLY_ACTIVE_ARCH = YES; 497 | SDKROOT = macosx; 498 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 499 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 500 | }; 501 | name = Debug; 502 | }; 503 | DDF18A0C2919D4AA00BC2201 /* Release */ = { 504 | isa = XCBuildConfiguration; 505 | buildSettings = { 506 | ALWAYS_SEARCH_USER_PATHS = NO; 507 | CLANG_ANALYZER_NONNULL = YES; 508 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 509 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 510 | CLANG_CXX_LIBRARY = "libc++"; 511 | CLANG_ENABLE_MODULES = YES; 512 | CLANG_ENABLE_OBJC_ARC = YES; 513 | CLANG_ENABLE_OBJC_WEAK = YES; 514 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 515 | CLANG_WARN_BOOL_CONVERSION = YES; 516 | CLANG_WARN_COMMA = YES; 517 | CLANG_WARN_CONSTANT_CONVERSION = YES; 518 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 519 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 520 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 521 | CLANG_WARN_EMPTY_BODY = YES; 522 | CLANG_WARN_ENUM_CONVERSION = YES; 523 | CLANG_WARN_INFINITE_RECURSION = YES; 524 | CLANG_WARN_INT_CONVERSION = YES; 525 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 526 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 527 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 528 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 529 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 530 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 531 | CLANG_WARN_STRICT_PROTOTYPES = YES; 532 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 533 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 534 | CLANG_WARN_UNREACHABLE_CODE = YES; 535 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 536 | COPY_PHASE_STRIP = NO; 537 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 538 | ENABLE_NS_ASSERTIONS = NO; 539 | ENABLE_STRICT_OBJC_MSGSEND = YES; 540 | GCC_C_LANGUAGE_STANDARD = gnu11; 541 | GCC_NO_COMMON_BLOCKS = YES; 542 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 543 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 544 | GCC_WARN_UNDECLARED_SELECTOR = YES; 545 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 546 | GCC_WARN_UNUSED_FUNCTION = YES; 547 | GCC_WARN_UNUSED_VARIABLE = YES; 548 | MACOSX_DEPLOYMENT_TARGET = 11.7; 549 | MTL_ENABLE_DEBUG_INFO = NO; 550 | MTL_FAST_MATH = YES; 551 | SDKROOT = macosx; 552 | SWIFT_COMPILATION_MODE = wholemodule; 553 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 554 | }; 555 | name = Release; 556 | }; 557 | DDF18A0E2919D4AA00BC2201 /* Debug */ = { 558 | isa = XCBuildConfiguration; 559 | buildSettings = { 560 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 561 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 562 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 563 | ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; 564 | CODE_SIGN_ENTITLEMENTS = UnderPillow/UnderPillow.entitlements; 565 | CODE_SIGN_IDENTITY = "Developer ID Application"; 566 | CODE_SIGN_STYLE = Manual; 567 | COMBINE_HIDPI_IMAGES = YES; 568 | CURRENT_PROJECT_VERSION = 1; 569 | DEVELOPMENT_ASSET_PATHS = "\"UnderPillow/Preview Content\""; 570 | DEVELOPMENT_TEAM = D3SBBNFWTC; 571 | ENABLE_HARDENED_RUNTIME = YES; 572 | ENABLE_PREVIEWS = YES; 573 | GENERATE_INFOPLIST_FILE = YES; 574 | INFOPLIST_FILE = UnderPillow/Info.plist; 575 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 576 | LD_RUNPATH_SEARCH_PATHS = ( 577 | "$(inherited)", 578 | "@executable_path/../Frameworks", 579 | ); 580 | MARKETING_VERSION = 0.6; 581 | PRODUCT_BUNDLE_IDENTIFIER = "Crispy-Driven-Pixels.UnderPillow"; 582 | PRODUCT_NAME = "$(TARGET_NAME)"; 583 | PROVISIONING_PROFILE_SPECIFIER = ""; 584 | SWIFT_EMIT_LOC_STRINGS = YES; 585 | SWIFT_VERSION = 5.0; 586 | }; 587 | name = Debug; 588 | }; 589 | DDF18A0F2919D4AA00BC2201 /* Release */ = { 590 | isa = XCBuildConfiguration; 591 | buildSettings = { 592 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 593 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 594 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 595 | ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; 596 | CODE_SIGN_ENTITLEMENTS = UnderPillow/UnderPillow.entitlements; 597 | CODE_SIGN_IDENTITY = "Developer ID Application"; 598 | CODE_SIGN_STYLE = Manual; 599 | COMBINE_HIDPI_IMAGES = YES; 600 | CURRENT_PROJECT_VERSION = 1; 601 | DEVELOPMENT_ASSET_PATHS = "\"UnderPillow/Preview Content\""; 602 | DEVELOPMENT_TEAM = D3SBBNFWTC; 603 | ENABLE_HARDENED_RUNTIME = YES; 604 | ENABLE_PREVIEWS = YES; 605 | GENERATE_INFOPLIST_FILE = YES; 606 | INFOPLIST_FILE = UnderPillow/Info.plist; 607 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 608 | LD_RUNPATH_SEARCH_PATHS = ( 609 | "$(inherited)", 610 | "@executable_path/../Frameworks", 611 | ); 612 | MARKETING_VERSION = 0.6; 613 | PRODUCT_BUNDLE_IDENTIFIER = "Crispy-Driven-Pixels.UnderPillow"; 614 | PRODUCT_NAME = "$(TARGET_NAME)"; 615 | PROVISIONING_PROFILE_SPECIFIER = ""; 616 | SWIFT_EMIT_LOC_STRINGS = YES; 617 | SWIFT_VERSION = 5.0; 618 | }; 619 | name = Release; 620 | }; 621 | DDF18A1E2919D4CC00BC2201 /* Debug */ = { 622 | isa = XCBuildConfiguration; 623 | buildSettings = { 624 | CODE_SIGN_ENTITLEMENTS = "UnderPillow Finder/UnderPillow_Finder.entitlements"; 625 | CODE_SIGN_IDENTITY = "Developer ID Application"; 626 | CODE_SIGN_STYLE = Manual; 627 | COMBINE_HIDPI_IMAGES = YES; 628 | CURRENT_PROJECT_VERSION = 1; 629 | DEVELOPMENT_TEAM = D3SBBNFWTC; 630 | ENABLE_HARDENED_RUNTIME = YES; 631 | GENERATE_INFOPLIST_FILE = YES; 632 | INFOPLIST_FILE = "UnderPillow Finder/Info.plist"; 633 | INFOPLIST_KEY_CFBundleDisplayName = "UnderPillow Finder"; 634 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 635 | LD_RUNPATH_SEARCH_PATHS = ( 636 | "$(inherited)", 637 | "@executable_path/../Frameworks", 638 | "@executable_path/../../../../Frameworks", 639 | ); 640 | MARKETING_VERSION = 0.6; 641 | PRODUCT_BUNDLE_IDENTIFIER = "Crispy-Driven-Pixels.UnderPillow.UnderPillow-Finder"; 642 | PRODUCT_NAME = "$(TARGET_NAME)"; 643 | PROVISIONING_PROFILE_SPECIFIER = ""; 644 | SKIP_INSTALL = YES; 645 | SWIFT_EMIT_LOC_STRINGS = YES; 646 | SWIFT_VERSION = 5.0; 647 | }; 648 | name = Debug; 649 | }; 650 | DDF18A1F2919D4CC00BC2201 /* Release */ = { 651 | isa = XCBuildConfiguration; 652 | buildSettings = { 653 | CODE_SIGN_ENTITLEMENTS = "UnderPillow Finder/UnderPillow_Finder.entitlements"; 654 | CODE_SIGN_IDENTITY = "Developer ID Application"; 655 | CODE_SIGN_STYLE = Manual; 656 | COMBINE_HIDPI_IMAGES = YES; 657 | CURRENT_PROJECT_VERSION = 1; 658 | DEVELOPMENT_TEAM = D3SBBNFWTC; 659 | ENABLE_HARDENED_RUNTIME = YES; 660 | GENERATE_INFOPLIST_FILE = YES; 661 | INFOPLIST_FILE = "UnderPillow Finder/Info.plist"; 662 | INFOPLIST_KEY_CFBundleDisplayName = "UnderPillow Finder"; 663 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 664 | LD_RUNPATH_SEARCH_PATHS = ( 665 | "$(inherited)", 666 | "@executable_path/../Frameworks", 667 | "@executable_path/../../../../Frameworks", 668 | ); 669 | MARKETING_VERSION = 0.6; 670 | PRODUCT_BUNDLE_IDENTIFIER = "Crispy-Driven-Pixels.UnderPillow.UnderPillow-Finder"; 671 | PRODUCT_NAME = "$(TARGET_NAME)"; 672 | PROVISIONING_PROFILE_SPECIFIER = ""; 673 | SKIP_INSTALL = YES; 674 | SWIFT_EMIT_LOC_STRINGS = YES; 675 | SWIFT_VERSION = 5.0; 676 | }; 677 | name = Release; 678 | }; 679 | /* End XCBuildConfiguration section */ 680 | 681 | /* Begin XCConfigurationList section */ 682 | DD180E40291AD38500E23D59 /* Build configuration list for PBXNativeTarget "UnderPillowXPC" */ = { 683 | isa = XCConfigurationList; 684 | buildConfigurations = ( 685 | DD180E41291AD38500E23D59 /* Debug */, 686 | DD180E42291AD38500E23D59 /* Release */, 687 | ); 688 | defaultConfigurationIsVisible = 0; 689 | defaultConfigurationName = Release; 690 | }; 691 | DDF189F92919D4A700BC2201 /* Build configuration list for PBXProject "UnderPillow" */ = { 692 | isa = XCConfigurationList; 693 | buildConfigurations = ( 694 | DDF18A0B2919D4AA00BC2201 /* Debug */, 695 | DDF18A0C2919D4AA00BC2201 /* Release */, 696 | ); 697 | defaultConfigurationIsVisible = 0; 698 | defaultConfigurationName = Release; 699 | }; 700 | DDF18A0D2919D4AA00BC2201 /* Build configuration list for PBXNativeTarget "UnderPillow" */ = { 701 | isa = XCConfigurationList; 702 | buildConfigurations = ( 703 | DDF18A0E2919D4AA00BC2201 /* Debug */, 704 | DDF18A0F2919D4AA00BC2201 /* Release */, 705 | ); 706 | defaultConfigurationIsVisible = 0; 707 | defaultConfigurationName = Release; 708 | }; 709 | DDF18A1D2919D4CC00BC2201 /* Build configuration list for PBXNativeTarget "UnderPillow Finder" */ = { 710 | isa = XCConfigurationList; 711 | buildConfigurations = ( 712 | DDF18A1E2919D4CC00BC2201 /* Debug */, 713 | DDF18A1F2919D4CC00BC2201 /* Release */, 714 | ); 715 | defaultConfigurationIsVisible = 0; 716 | defaultConfigurationName = Release; 717 | }; 718 | /* End XCConfigurationList section */ 719 | }; 720 | rootObject = DDF189F62919D4A700BC2201 /* Project object */; 721 | } 722 | --------------------------------------------------------------------------------