Fixes crashes on mac app

main
Laurent 3 years ago
parent 5f70c4da00
commit 205efa3704
  1. 12
      LeCountdown.xcodeproj/project.pbxproj
  2. 14
      LeCountdown.xcodeproj/xcshareddata/xcschemes/LeCountdown.xcscheme
  3. 29
      LeCountdown/AppDelegate.swift
  4. 8
      LeCountdown/Intent/TimerIdentifierAppEntity.swift
  5. 31
      LeCountdown/LeCountdownApp.swift
  6. 1
      LeCountdown/Model/Persistence.swift
  7. 22
      LeCountdown/TimerRouter.swift
  8. 4
      LeCountdown/Views/TimersView.swift
  9. 5
      LeCountdown/Widget/IntentDataProvider.swift

@ -1461,7 +1461,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 0.1.1;
MARKETING_VERSION = 0.1.2;
PRODUCT_BUNDLE_IDENTIFIER = com.staxriver.LeCountdown;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
@ -1495,7 +1495,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 0.1.1;
MARKETING_VERSION = 0.1.2;
PRODUCT_BUNDLE_IDENTIFIER = com.staxriver.LeCountdown;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
@ -1598,7 +1598,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 0.1.1;
MARKETING_VERSION = 0.1.2;
PRODUCT_BUNDLE_IDENTIFIER = com.staxriver.LeCountdown.LaunchWidget;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@ -1626,7 +1626,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 0.1.1;
MARKETING_VERSION = 0.1.2;
PRODUCT_BUNDLE_IDENTIFIER = com.staxriver.LeCountdown.LaunchWidget;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@ -1653,7 +1653,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 0.1.1;
MARKETING_VERSION = 0.1.2;
PRODUCT_BUNDLE_IDENTIFIER = com.staxriver.LeCountdown.LaunchIntents;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@ -1680,7 +1680,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 0.1.1;
MARKETING_VERSION = 0.1.2;
PRODUCT_BUNDLE_IDENTIFIER = com.staxriver.LeCountdown.LaunchIntents;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;

@ -50,6 +50,20 @@
ReferencedContainer = "container:LeCountdown.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<CommandLineArguments>
<CommandLineArgument
argument = "-com.apple.CoreData.Logging.stderr 0"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "-com.apple.CoreData.CloudKitDebug 0"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = " -com.apple.CoreData.ConcurrencyDebug 1"
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"

@ -7,6 +7,7 @@
import Foundation
import UIKit
import AVFoundation
class AppDelegate : NSObject, UIApplicationDelegate {
@ -20,10 +21,38 @@ class AppDelegate : NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
UNUserNotificationCenter.current().delegate = self
self._initSchemaIfNeeded()
self._activateAudioSession()
Sound.computeSoundDurationsIfNecessary()
Conductor.maestro.cleanup()
return true
}
fileprivate func _initSchemaIfNeeded() {
if !Preferences.cloudKitSchemaInitialized {
do {
try PersistenceController.shared.container.initializeCloudKitSchema()
Preferences.cloudKitSchemaInitialized = true
} catch {
print("initializeCloudKitSchema error: \(error)")
}
}
}
fileprivate func _activateAudioSession() {
do {
let audioSession: AVAudioSession = AVAudioSession.sharedInstance()
try audioSession.setCategory(.playback)
try audioSession.setActive(true)
} catch {
Logger.error(error)
}
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
if userActivity.interaction == nil {

@ -21,10 +21,14 @@ struct TimerIdentifierAppEntity: AppEntity {
}
func suggestedEntities() async throws -> [TimerIdentifierAppEntity] {
try await PersistenceController.shared.container.performBackgroundTask { context in
let timers = try IntentDataProvider.main.timers(context: context)
return timers.map { TimerIdentifierAppEntity(id: $0.stringId, displayString: $0.displayName) }
}
// TODO: return likely TimerIdentifierAppEntity entities here.
// This method is optional; the default implementation returns an empty array.
let timers = try IntentDataProvider.main.timers()
return timers.map { TimerIdentifierAppEntity(id: $0.stringId, displayString: $0.displayName) }
}
}

@ -24,31 +24,15 @@ struct LeCountdownApp: App {
UIPageControl.appearance().currentPageIndicatorTintColor = .systemPink
UIPageControl.appearance().pageIndicatorTintColor = UIColor(white: 0.7, alpha: 1.0)
Logger.log("path = \(Bundle.main.bundlePath)")
self._registerBackgroundRefreshes()
self._initSchemaIfNeeded()
self._activateAudioSession()
}
fileprivate func _initSchemaIfNeeded() {
if !Preferences.cloudKitSchemaInitialized {
do {
try persistenceController.container.initializeCloudKitSchema()
Preferences.cloudKitSchemaInitialized = true
} catch {
print("ERROR \(error)")
}
}
}
fileprivate func _activateAudioSession() {
do {
let audioSession: AVAudioSession = AVAudioSession.sharedInstance()
try audioSession.setCategory(.playback)
try audioSession.setActive(true)
} catch {
Logger.error(error)
}
// if !ProcessInfo.processInfo.isiOSAppOnMac {
// self._initSchemaIfNeeded()
// self._activateAudioSession()
// }
}
@Environment(\.scenePhase) var scenePhase
@ -98,7 +82,6 @@ struct LeCountdownApp: App {
Logger.log("preferredLanguages = \(String(describing: Locale.preferredLanguages))")
Sound.computeSoundDurationsIfNecessary()
self._patch()

@ -38,7 +38,6 @@ struct PersistenceController {
record.activity = activities.randomElement()
}
do {
try viewContext.save()
} catch {

@ -59,16 +59,18 @@ class TimerRouter {
fileprivate static func _launchCountdown(_ countdown: Countdown, handler: @escaping (Result<Void, Error>) -> Void) {
UNUserNotificationCenter.current().getNotificationSettings { settings in
switch settings.authorizationStatus {
case .notDetermined, .denied:
handler(.failure(TimerRouterError.notificationAuthorizationMissing))
default:
CountdownScheduler.master.scheduleIfPossible(countdown: countdown) { result in
switch result {
case .success:
handler(.success(Void()))
case .failure(let failure):
handler(.failure(failure))
DispatchQueue.main.async {
switch settings.authorizationStatus {
case .notDetermined, .denied:
handler(.failure(TimerRouterError.notificationAuthorizationMissing))
default:
CountdownScheduler.master.scheduleIfPossible(countdown: countdown) { result in
switch result {
case .success:
handler(.success(Void()))
case .failure(let failure):
handler(.failure(failure))
}
}
}
}

@ -53,7 +53,8 @@ struct TimersView: View {
}
}
}.padding(.horizontal, itemSpacing)
}
.padding(.horizontal, itemSpacing)
} else {
Text("You'll find your timers here. Start by creating them on the left screen").multilineTextAlignment(.center)
}
@ -75,6 +76,7 @@ struct TimersView: View {
}
fileprivate func _handleSiriTips(timer: AbstractTimer) {
let timerId = timer.stringId
if !Preferences.timerSiriTips.contains(timerId) {
self.boringContext.siriTimer = timer

@ -13,7 +13,10 @@ class IntentDataProvider {
static let main: IntentDataProvider = IntentDataProvider()
func timers() throws -> [AbstractTimer] {
let context = PersistenceController.shared.container.viewContext
return try timers(context: PersistenceController.shared.container.viewContext)
}
func timers(context: NSManagedObjectContext) throws -> [AbstractTimer] {
let request: NSFetchRequest<AbstractTimer> = AbstractTimer.fetchRequest()
request.sortDescriptors = [NSSortDescriptor(keyPath: (\AbstractTimer.order), ascending: true)]
return try context.fetch(request)

Loading…
Cancel
Save