Skip to content

Commit e321c58

Browse files
committed
chore: release 5.1.0
1 parent 1293fb8 commit e321c58

104 files changed

Lines changed: 4644 additions & 2142 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,5 @@ node_modules/
108108
/nodejs/lib/binding
109109
/nodejs/dist
110110
/Samples/Electron/dist
111+
/Samples/Electron/out
111112
/Samples/Electron/.wrapper

CHANGELOG.md

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
## [Unreleased]
2+
3+
## [5.1.0] - 2026-04-09
4+
5+
### New
6+
* Setapp AI API now supports AI image generation and editing. (Image streaming isn't available yet.)
7+
8+
### Updated
9+
* [Electron] Added support for the Electron Forge build system in the sample app, alongside the existing electron-builder setup.
10+
11+
### Fixed
12+
* [iOS] Fixed an issue with an incorrect resource bundle type that caused warnings during App Store uploads.
13+
14+
### New
15+
* [Electron] Added Electron Forge build system support for the sample app alongside the existing electron-builder setup.
16+
117
## [5.0.1] - 2026-02-26
218

319
### Updated
@@ -71,7 +87,7 @@
7187
## [4.2.2] - 2024-10-17
7288

7389
### Fixed
74-
* [Electron] Fixed a crash on app launch on x86_64 architecture.
90+
* [Electron] Fixed a crash on app launch on x86_64 architecture.
7591

7692

7793
## [4.2.1] - 2024-07-31
@@ -94,7 +110,7 @@
94110
### Updated
95111
* reCAPTCHA sheet can be dismissed in QR Code Generator.
96112
* Under the hood improvements.
97-
* `README.md` file was updated.
113+
* `README.md` file was updated.
98114

99115
### Fixed
100116
* reCAPTCHA sheet layout in QR Code Generator.
@@ -110,7 +126,7 @@
110126

111127
### Updated
112128
* Setapp Framework is now built using Xcode 15.
113-
* [iOS] The minimum iOS version supported by Setapp Framework has been increased to `12.0`.
129+
* [iOS] The minimum iOS version supported by Setapp Framework has been increased to `12.0`.
114130

115131
### Fixed
116132
* Sample apps that use CocoPods were updated to address a build issue when using Xcode 15.
@@ -194,7 +210,7 @@
194210
* [iOS] Use app display name in activation alerts.
195211

196212
### Fixed
197-
* [iOS] Public key custom name.
213+
* [iOS] Public key custom name.
198214
* [iOS] SPM warnings.
199215
* Xcode 13 compatibility.
200216

@@ -213,7 +229,7 @@
213229
## [3.0.1] - 2022-09-12
214230

215231
### Fixed
216-
* [iOS] Resources bundle destribution fix.
232+
* [iOS] Resources bundle destribution fix.
217233

218234
## [3.0.0] - 2022-09-09
219235

@@ -278,13 +294,13 @@
278294
* Changed default branch to `main`.
279295

280296
### Fixed
281-
* Improved CocoaPods integration - no need to modify `SWIFT_INCLUDE_PATHS` anymore.
297+
* Improved CocoaPods integration - no need to modify `SWIFT_INCLUDE_PATHS` anymore.
282298

283299

284300
## [2.0.2] - 2022-04-19
285301

286302
### Changed
287-
* Improved CocoaPods integration - no need to modify `OTHER_LDFLAGS` anymore.
303+
* Improved CocoaPods integration - no need to modify `OTHER_LDFLAGS` anymore.
288304

289305
### Fixed
290306
* [macOS] Setapp Desktop app version recognition.
@@ -297,7 +313,7 @@
297313
* macOS apps support.
298314

299315
### Changed
300-
* Improved license storage on iOS platform.
316+
* Improved license storage on iOS platform.
301317

302318

303319
## [2.0.0]
@@ -321,7 +337,7 @@
321337
## [0.1.0] - 2020-12-23
322338

323339
### ⚠️ Breaking
324-
This release contains some breaking API changes. See the New and Changed sections below for details.
340+
This release contains some breaking API changes. See the New and Changed sections below for details.
325341

326342
### New
327343
* Added completion handlers to the `open` methods. Now, you can get a callback when the Setapp subscription state is resolved.

Samples/AIViewModel.swift

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
import Combine
12
import Setapp
23
import SetappAI
34
import SwiftUI
4-
import Combine
55

66
// MARK: - Message Model
77

@@ -36,9 +36,9 @@ struct ConversationState: Codable {
3636
@Observable
3737
@MainActor
3838
class AIViewModel {
39-
#if os(iOS)
39+
#if os(iOS)
4040
var isActivated: Bool = false
41-
#endif
41+
#endif
4242

4343
// Models
4444
var availableModels: [SetappAIAPI.Model] = []
@@ -59,14 +59,14 @@ class AIViewModel {
5959
private static let conversationStateKey = "AIViewModel.conversationState"
6060

6161
init() {
62-
#if os(iOS)
63-
subscriptionCancellable = SetappManager.shared.publisher(for: \.subscription)
62+
#if os(iOS)
63+
self.subscriptionCancellable = SetappManager.shared.publisher(for: \.subscription)
6464
.sink { [weak self] subscription in
6565
self?.isActivated = subscription?.isActive ?? false
6666
}
67-
#endif
67+
#endif
6868

69-
self.loadConversationState()
69+
loadConversationState()
7070
}
7171

7272
var selectedModel: SetappAIAPI.Model? {
@@ -122,7 +122,8 @@ class AIViewModel {
122122

123123
private func loadConversationState() {
124124
guard let data = UserDefaults.standard.data(forKey: Self.conversationStateKey),
125-
let decoded = try? JSONDecoder().decode(ConversationState.self, from: data) else {
125+
let decoded = try? JSONDecoder().decode(ConversationState.self, from: data)
126+
else {
126127
return
127128
}
128129
state = decoded
@@ -198,7 +199,9 @@ class AIViewModel {
198199
self.saveConversationState()
199200
} catch {
200201
self.streamingError = error
201-
self.updateLastMessage(content: self.currentStreamingContent + "\n\n❌ Error: \(error.localizedDescription)")
202+
self
203+
.updateLastMessage(content: self
204+
.currentStreamingContent + "\n\n❌ Error: \(error.localizedDescription)")
202205
self.currentStreamingContent = ""
203206
self.isStreaming = false
204207
self.saveConversationState()

Samples/App Extensions/Intents/AppIntentsExtension.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ struct SetappIntentsExtension: AppIntentsExtension {
1313
init() {
1414
configureSetappManager()
1515
}
16-
16+
1717
private func configureSetappManager() {
1818
SetappManager.logLevel = .debug
1919

2020
let configuration = SetappConfiguration(
2121
publicKeyBundle: .main,
2222
publicKeyFilename: "setappPublicKey-iOS.pem"
2323
)
24-
24+
2525
configuration.appGroupIdentifier = "group.setapp"
2626

2727
SetappManager.shared.start(

Samples/App Extensions/Intents/SampleIntent.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// AppIntents.swift
2+
// SampleIntent.swift
33
// AppIntents
44
//
55
// Created by Oleksandr Bilous on 14.08.2024.

Samples/App Extensions/Keyboard/KeyboardViewController.swift

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,47 +9,48 @@ import UIKit
99

1010
class KeyboardViewController: UIInputViewController {
1111
@IBOutlet var nextKeyboardButton: UIButton!
12-
13-
override var hasFullAccess: Bool { true }
14-
12+
13+
override var hasFullAccess: Bool {
14+
true
15+
}
16+
1517
override func viewDidLoad() {
1618
super.viewDidLoad()
1719
SetappUsageReporter.shared.reportExtensionUsage()
18-
20+
1921
// Perform custom UI setup here
20-
self.nextKeyboardButton = UIButton(type: .system)
21-
self.view.translatesAutoresizingMaskIntoConstraints = false
22-
self.nextKeyboardButton.setTitle("Next Keyboard", for: [])
23-
self.nextKeyboardButton.sizeToFit()
24-
self.nextKeyboardButton.translatesAutoresizingMaskIntoConstraints = false
25-
26-
self.nextKeyboardButton.addTarget(self, action: #selector(handleInputModeList(from:with:)), for: .allTouchEvents)
27-
28-
self.view.addSubview(self.nextKeyboardButton)
29-
self.nextKeyboardButton.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
30-
self.nextKeyboardButton.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
22+
nextKeyboardButton = UIButton(type: .system)
23+
view.translatesAutoresizingMaskIntoConstraints = false
24+
nextKeyboardButton.setTitle("Next Keyboard", for: [])
25+
nextKeyboardButton.sizeToFit()
26+
nextKeyboardButton.translatesAutoresizingMaskIntoConstraints = false
27+
28+
nextKeyboardButton.addTarget(self, action: #selector(handleInputModeList(from:with:)), for: .allTouchEvents)
29+
30+
view.addSubview(nextKeyboardButton)
31+
nextKeyboardButton.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
32+
nextKeyboardButton.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
3133
}
32-
34+
3335
override func viewWillLayoutSubviews() {
34-
self.nextKeyboardButton.isHidden = !self.needsInputModeSwitchKey
36+
nextKeyboardButton.isHidden = !needsInputModeSwitchKey
3537
super.viewWillLayoutSubviews()
3638
}
37-
38-
override func textWillChange(_ textInput: UITextInput?) {
39+
40+
override func textWillChange(_: UITextInput?) {
3941
// The app is about to change the document's contents. Perform any preparation here.
4042
}
41-
42-
override func textDidChange(_ textInput: UITextInput?) {
43+
44+
override func textDidChange(_: UITextInput?) {
4345
// The app has just changed the document's contents, the document context has been updated.
44-
46+
4547
var textColor: UIColor
46-
let proxy = self.textDocumentProxy
48+
let proxy = textDocumentProxy
4749
if proxy.keyboardAppearance == UIKeyboardAppearance.dark {
4850
textColor = UIColor.white
4951
} else {
5052
textColor = UIColor.black
5153
}
52-
self.nextKeyboardButton.setTitleColor(textColor, for: [])
54+
nextKeyboardButton.setTitleColor(textColor, for: [])
5355
}
54-
5556
}

Samples/App Extensions/Keyboard/SetappUsageReporter.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ final class SetappUsageReporter {
1717
publicKeyBundle: .main,
1818
publicKeyFilename: "setappPublicKey-iOS.pem"
1919
)
20-
20+
2121
configuration.appGroupIdentifier = "group.setapp"
2222

2323
SetappManager.shared.start(
2424
with: configuration
2525
)
2626
return SetappUsageReporter()
2727
}()
28-
28+
2929
func reportExtensionUsage() {
3030
SetappManager.shared.reportExtensionUsage()
3131
}

Samples/App Extensions/Widget/AppIntent.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
// Created by Oleksandr Bilous on 14.08.2024.
66
//
77

8-
import WidgetKit
98
import AppIntents
109
import Setapp
10+
import WidgetKit
1111

1212
struct ConfigurationAppIntent: WidgetConfigurationIntent {
1313
static var title: LocalizedStringResource = "Configuration"
1414
static var description = IntentDescription("This is an example widget.")
1515

16-
// An example configurable parameter.
16+
/// An example configurable parameter.
1717
@Parameter(title: "Favorite Emoji", default: "😃")
1818
var favoriteEmoji: String
1919
}

Samples/App Extensions/Widget/SetappWidget.swift

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,52 @@
11
//
2-
// widget.swift
2+
// SetappWidget.swift
33
// widget
44
//
55
// Created by Oleksandr Bilous on 14.08.2024.
66
//
77

8-
import WidgetKit
9-
import SwiftUI
108
import Setapp
9+
import SwiftUI
10+
import WidgetKit
1111

1212
struct Provider: AppIntentTimelineProvider {
1313
private let setappManager: SetappManager
14-
14+
1515
init() {
1616
self.setappManager = .shared
1717
configureSetappManager()
1818
}
19-
20-
func placeholder(in context: Context) -> SimpleEntry {
19+
20+
func placeholder(in _: Context) -> SimpleEntry {
2121
SimpleEntry(date: Date(), configuration: ConfigurationAppIntent())
2222
}
2323

24-
func snapshot(for configuration: ConfigurationAppIntent, in context: Context) async -> SimpleEntry {
24+
func snapshot(for configuration: ConfigurationAppIntent, in _: Context) async -> SimpleEntry {
2525
SimpleEntry(date: Date(), configuration: configuration)
2626
}
27-
28-
func timeline(for configuration: ConfigurationAppIntent, in context: Context) async -> Timeline<SimpleEntry> {
27+
28+
func timeline(for configuration: ConfigurationAppIntent, in _: Context) async -> Timeline<SimpleEntry> {
2929
setappManager.reportExtensionUsage()
3030
var entries: [SimpleEntry] = []
3131

3232
let currentDate = Date()
33-
for hourOffset in 0 ..< 5 {
33+
for hourOffset in 0..<5 {
3434
let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
3535
let entry = SimpleEntry(date: entryDate, configuration: configuration)
3636
entries.append(entry)
3737
}
3838

3939
return Timeline(entries: entries, policy: .atEnd)
4040
}
41-
41+
4242
private func configureSetappManager() {
4343
SetappManager.logLevel = .debug
4444

4545
let configuration = SetappConfiguration(
4646
publicKeyBundle: .main,
4747
publicKeyFilename: "setappPublicKey-iOS.pem"
4848
)
49-
49+
5050
configuration.appGroupIdentifier = "group.setapp"
5151

5252
setappManager.start(
@@ -60,7 +60,7 @@ struct SimpleEntry: TimelineEntry {
6060
let configuration: ConfigurationAppIntent
6161
}
6262

63-
struct WidgetEntryView : View {
63+
struct WidgetEntryView: View {
6464
var entry: Provider.Entry
6565
@State var isOn: Bool = false
6666

@@ -71,7 +71,7 @@ struct WidgetEntryView : View {
7171

7272
Text("Favorite Emoji:")
7373
Text(entry.configuration.favoriteEmoji)
74-
74+
7575
Toggle(isOn: isOn, intent: ToggleIntent()) {
7676
Text("Toggle")
7777
}
@@ -96,7 +96,7 @@ extension ConfigurationAppIntent {
9696
intent.favoriteEmoji = "😀"
9797
return intent
9898
}
99-
99+
100100
fileprivate static var starEyes: ConfigurationAppIntent {
101101
let intent = ConfigurationAppIntent()
102102
intent.favoriteEmoji = "🤩"

0 commit comments

Comments
 (0)