Skip to content

Commit 74b8e3e

Browse files
authored
Fixed lost progression when the system kills the WebKit process (#654)
1 parent 79d802a commit 74b8e3e

File tree

3 files changed

+58
-34
lines changed

3 files changed

+58
-34
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file. Take a look
1515
#### Navigator
1616

1717
* The safe area insets strategy was adjusted to take into account changes in iOS/iPadOS 26.
18+
* Fixed the lost progression with the EPUB navigator when the application becomes active again after the system terminated the WebKit process.
1819

1920

2021
## [3.4.0]

Sources/Navigator/EPUB/EPUBNavigatorViewController.swift

Lines changed: 56 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -329,13 +329,31 @@ open class EPUBNavigatorViewController: InputObservableViewController,
329329
self.delegate?.navigator(self, didReleaseKey: event)
330330
}
331331
)
332+
333+
NotificationCenter.default.addObserver(
334+
self,
335+
selector: #selector(didBecomeActive),
336+
name: UIApplication.didBecomeActiveNotification,
337+
object: nil
338+
)
339+
340+
NotificationCenter.default.addObserver(
341+
self,
342+
selector: #selector(willResignActive),
343+
name: UIApplication.willResignActiveNotification,
344+
object: nil
345+
)
332346
}
333347

334348
@available(*, unavailable)
335349
public required init?(coder aDecoder: NSCoder) {
336350
fatalError("init(coder:) has not been implemented")
337351
}
338352

353+
deinit {
354+
NotificationCenter.default.removeObserver(self)
355+
}
356+
339357
override open func viewDidLoad() {
340358
super.viewDidLoad()
341359

@@ -348,6 +366,21 @@ open class EPUBNavigatorViewController: InputObservableViewController,
348366
}
349367
}
350368

369+
private var isActive = true
370+
371+
@objc private func willResignActive() {
372+
isActive = false
373+
}
374+
375+
@objc private func didBecomeActive() {
376+
isActive = true
377+
378+
if needsReloadSpreadsOnActive {
379+
needsReloadSpreadsOnActive = false
380+
reloadSpreads(force: true)
381+
}
382+
}
383+
351384
private func initialize() async {
352385
do {
353386
positionsByReadingOrder = try await loadPositionsByReadingOrder().get()
@@ -365,7 +398,7 @@ open class EPUBNavigatorViewController: InputObservableViewController,
365398

366399
applySettings()
367400

368-
_reloadSpreads(at: currentLocation, force: false)
401+
_reloadSpreads(force: true)
369402

370403
onInitializedCallbacks.complete()
371404
}
@@ -404,9 +437,7 @@ open class EPUBNavigatorViewController: InputObservableViewController,
404437
viewModel.viewSizeWillChange(size)
405438

406439
coordinator.animate(alongsideTransition: nil) { [weak self] _ in
407-
Task {
408-
await self?.reloadSpreads(force: false)
409-
}
440+
self?.reloadSpreads(force: false)
410441
}
411442
}
412443

@@ -499,13 +530,13 @@ open class EPUBNavigatorViewController: InputObservableViewController,
499530
return view
500531
}
501532

502-
private func invalidatePaginationView() async {
533+
private func invalidatePaginationView() {
503534
guard let paginationView = paginationView else {
504535
return
505536
}
506537

507538
paginationView.isScrollEnabled = isPaginationViewScrollingEnabled
508-
await reloadSpreads(force: true)
539+
reloadSpreads(force: true)
509540
}
510541

511542
private var spreads: [EPUBSpread] = []
@@ -515,34 +546,22 @@ open class EPUBNavigatorViewController: InputObservableViewController,
515546
paginationView?.currentIndex ?? 0
516547
}
517548

518-
private var reloadSpreadsContinuations = [CheckedContinuation<Void, Never>]()
519-
private var needsReloadSpreads = false
549+
private var needsReloadSpreadsOnActive = false
520550

521-
private func reloadSpreads(at locator: Locator? = nil, force: Bool) async {
522-
guard state != .initializing, isViewLoaded else {
523-
return
524-
}
525-
526-
guard !needsReloadSpreads else {
527-
await withCheckedContinuation { continuation in
528-
reloadSpreadsContinuations.append(continuation)
529-
}
551+
private func reloadSpreads(force: Bool) {
552+
guard
553+
state != .initializing,
554+
isViewLoaded,
555+
isActive
556+
else {
530557
return
531558
}
532559

533-
needsReloadSpreads = true
534-
535-
_reloadSpreads(at: locator, force: force)
536-
for continuation in reloadSpreadsContinuations {
537-
continuation.resume()
538-
}
539-
reloadSpreadsContinuations.removeAll()
540-
541-
needsReloadSpreads = false
560+
_reloadSpreads(force: force)
542561
}
543562

544-
private func _reloadSpreads(at locator: Locator? = nil, force: Bool) {
545-
let locator = locator ?? currentLocation
563+
private func _reloadSpreads(force: Bool) {
564+
let locator = currentLocation
546565

547566
guard
548567
let paginationView = paginationView,
@@ -935,9 +954,7 @@ open class EPUBNavigatorViewController: InputObservableViewController,
935954

936955
extension EPUBNavigatorViewController: EPUBNavigatorViewModelDelegate {
937956
func epubNavigatorViewModelInvalidatePaginationView(_ viewModel: EPUBNavigatorViewModel) {
938-
Task {
939-
await invalidatePaginationView()
940-
}
957+
invalidatePaginationView()
941958
}
942959

943960
func epubNavigatorViewModel(_ viewModel: EPUBNavigatorViewModel, runScript script: String, in scope: EPUBScriptScope) {
@@ -1179,8 +1196,14 @@ extension EPUBNavigatorViewController: EPUBSpreadViewDelegate {
11791196
}
11801197

11811198
func spreadViewDidTerminate() {
1182-
Task {
1183-
await reloadSpreads(force: true)
1199+
if !isActive {
1200+
// If we reload the spreads while the app is in the background, the
1201+
// web view will reset to progression 0 instead of the current one.
1202+
// We need to wait for the application to return to the foreground
1203+
// to maintain the current location.
1204+
needsReloadSpreadsOnActive = true
1205+
} else {
1206+
reloadSpreads(force: true)
11841207
}
11851208
}
11861209
}

TestApp/Sources/Common/Toolkit/Extensions/Locator.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import Foundation
88
import ReadiumShared
99

10-
extension Locator: Codable {
10+
extension Locator: @retroactive Codable {
1111
public init(from decoder: Decoder) throws {
1212
let json = try decoder.singleValueContainer().decode(String.self)
1313
try self.init(jsonString: json)!

0 commit comments

Comments
 (0)