Skip to content

Commit 94b2698

Browse files
committed
Create widgets UI and logic
1 parent b24fdf6 commit 94b2698

File tree

23 files changed

+883
-5
lines changed

23 files changed

+883
-5
lines changed

SnippetsLibrary.xcodeproj/project.pbxproj

Lines changed: 272 additions & 1 deletion
Large diffs are not rendered by default.

SnippetsLibrary.xcodeproj/xcuserdata/krzysztoflowiec.xcuserdatad/xcschemes/xcschememanagement.plist

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
<key>isShown</key>
1010
<false/>
1111
<key>orderHint</key>
12-
<integer>3</integer>
12+
<integer>24</integer>
1313
</dict>
1414
<key>Promises (Playground) 2.xcscheme</key>
1515
<dict>
1616
<key>isShown</key>
1717
<false/>
1818
<key>orderHint</key>
19-
<integer>4</integer>
19+
<integer>25</integer>
2020
</dict>
2121
<key>Promises (Playground) 3.xcscheme</key>
2222
<dict>
@@ -44,13 +44,18 @@
4444
<key>isShown</key>
4545
<false/>
4646
<key>orderHint</key>
47-
<integer>2</integer>
47+
<integer>23</integer>
4848
</dict>
4949
<key>SnippetsLibrary.xcscheme_^#shared#^_</key>
5050
<dict>
5151
<key>orderHint</key>
5252
<integer>0</integer>
5353
</dict>
54+
<key>SnippetsLibraryWidgetExtension.xcscheme_^#shared#^_</key>
55+
<dict>
56+
<key>orderHint</key>
57+
<integer>1</integer>
58+
</dict>
5459
</dict>
5560
<key>SuppressBuildableAutocreation</key>
5661
<dict>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"colors" : [
3+
{
4+
"color" : {
5+
"color-space" : "display-p3",
6+
"components" : {
7+
"alpha" : "1.000",
8+
"blue" : "0.971",
9+
"green" : "0.962",
10+
"red" : "0.966"
11+
}
12+
},
13+
"idiom" : "universal"
14+
},
15+
{
16+
"appearances" : [
17+
{
18+
"appearance" : "luminosity",
19+
"value" : "dark"
20+
}
21+
],
22+
"color" : {
23+
"color-space" : "display-p3",
24+
"components" : {
25+
"alpha" : "1.000",
26+
"blue" : "0.102",
27+
"green" : "0.102",
28+
"red" : "0.102"
29+
}
30+
},
31+
"idiom" : "universal"
32+
}
33+
],
34+
"info" : {
35+
"author" : "xcode",
36+
"version" : 1
37+
}
38+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"images" : [
3+
{
4+
"filename" : "icSnippetFileBlank.png",
5+
"idiom" : "universal"
6+
}
7+
],
8+
"info" : {
9+
"author" : "xcode",
10+
"version" : 1
11+
}
12+
}
2.45 KB
Loading

SnippetsLibrary/Services/UserDefaults/UserDefaultsService.swift

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,15 @@ import Combine
1111
protocol UserDefaultsService {
1212
func saveRecentSnippet(_ snippet: Snippet)
1313
func fetchRecentSnippets() -> AnyPublisher<[Snippet], Never>
14+
15+
func fetchRecentSnippetsFromAppGroup() -> [Snippet]
1416
}
1517

1618
final class UserDefaultsServiceImpl: UserDefaultsService {
1719

1820
private enum Constants {
1921
static let recentSnippetKey = "RecentSnippet"
22+
static let appGroupName = "group.com.cphlowiec.SnippetsLibrary"
2023
}
2124

2225
// MARK: - Stored Properties
@@ -25,13 +28,21 @@ final class UserDefaultsServiceImpl: UserDefaultsService {
2528

2629
// MARK: - Methods
2730

31+
// MARK: - Recent Snippets -
32+
2833
internal func saveRecentSnippet(_ snippet: Snippet) {
2934
let snippet = SnippetPlist(from: snippet)
3035
let snippetDictonary = snippet.convertedToDictonary()
36+
let snippetKey = Constants.recentSnippetKey + " \(snippet.id)"
3137

3238
userDefaults.set(
3339
snippetDictonary,
34-
forKey: Constants.recentSnippetKey + " \(snippet.id)"
40+
forKey: snippetKey
41+
)
42+
43+
saveSnippetDictonaryIntoAppGroup(
44+
snippetDictonary,
45+
key: snippetKey
3546
)
3647
}
3748

@@ -56,4 +67,37 @@ final class UserDefaultsServiceImpl: UserDefaultsService {
5667
.eraseToAnyPublisher()
5768
}
5869

70+
// MARK: - App Group -
71+
72+
internal func fetchRecentSnippetsFromAppGroup() -> [Snippet] {
73+
guard let userDefaults = UserDefaults(suiteName: Constants.appGroupName) else { return [] }
74+
75+
let keys = userDefaults.dictionaryRepresentation().keys.filter { $0.contains(Constants.recentSnippetKey) }
76+
var snippets = [Snippet]()
77+
78+
for key in keys {
79+
guard
80+
let snippetDictonary = userDefaults.object(forKey: key),
81+
let data = try? JSONSerialization.data(withJSONObject: snippetDictonary, options: []),
82+
let snippet = try? JSONDecoder().decode(SnippetPlist.self, from: data)
83+
else { continue }
84+
85+
snippets.append(Snippet(from: snippet))
86+
}
87+
88+
return snippets
89+
}
90+
91+
private func saveSnippetDictonaryIntoAppGroup(
92+
_ snippetDictonary: [String: Any],
93+
key: String
94+
) {
95+
guard let userDefaults = UserDefaults(suiteName: Constants.appGroupName) else { return }
96+
97+
userDefaults.set(
98+
snippetDictonary,
99+
forKey: key
100+
)
101+
}
102+
59103
}

SnippetsLibrary/SnippetsLibrary.entitlements

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
<dict>
55
<key>com.apple.security.app-sandbox</key>
66
<true/>
7+
<key>com.apple.security.application-groups</key>
8+
<array>
9+
<string>group.com.cphlowiec.SnippetsLibrary</string>
10+
</array>
711
<key>com.apple.security.files.user-selected.read-write</key>
812
<true/>
913
<key>com.apple.security.network.client</key>

SnippetsLibrary/SnippetsLibraryDebug.entitlements

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
<dict>
55
<key>com.apple.security.app-sandbox</key>
66
<true/>
7+
<key>com.apple.security.application-groups</key>
8+
<array>
9+
<string>group.com.cphlowiec.SnippetsLibrary</string>
10+
</array>
711
<key>com.apple.security.files.user-selected.read-write</key>
812
<true/>
913
<key>com.apple.security.network.client</key>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//
2+
// UserDefaultsServiceError.swift
3+
// SnippetsLibrary
4+
//
5+
// Created by Krzysztof Łowiec on 02/10/2021.
6+
//
7+
8+
import Foundation
9+
10+
enum UserDefaultsServiceError: Error {
11+
case unableToGetData
12+
}

SnippetsLibrary/Views/AppView.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ import SwiftUI
99

1010
struct AppView: View {
1111

12+
private enum Constants {
13+
static let statusWindowClassName = "NSStatusBarWindow"
14+
static let delay = DispatchTime.now() + 0.01
15+
}
16+
1217
// MARK: - Stored Properties
1318

1419
@Environment(\.scenePhase) var scenePhase
@@ -29,6 +34,9 @@ struct AppView: View {
2934
shouldShowNetworkAlert.toggle()
3035
}
3136
}
37+
.onOpenURL {
38+
openSnippet(fromURL: $0)
39+
}
3240
.makeDisplayed(
3341
with: $shouldShowNetworkAlert,
3442
imageName: "network",
@@ -86,6 +94,24 @@ struct AppView: View {
8694
}
8795
}
8896

97+
private func openSnippet(fromURL url: URL) {
98+
closeWindowsIfVisible()
99+
let snippetId = url.absoluteString.replacingOccurrences(of: "widget://", with: "")
100+
101+
DispatchQueue.main.asyncAfter(deadline: Constants.delay) {
102+
NSApplication.shared.windows.first?.orderFront(nil)
103+
activeAppView = .snippetsLibrary(snippetId)
104+
}
105+
}
106+
107+
private func closeWindowsIfVisible() {
108+
for window in NSApplication.shared.windows where window.className != Constants.statusWindowClassName {
109+
DispatchQueue.main.async {
110+
window.close()
111+
}
112+
}
113+
}
114+
89115
}
90116

91117

0 commit comments

Comments
 (0)