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