Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions Example/iOS-Example/Model+Fetchable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ extension FetchableObjectProtocol where Self: Model {

return FetchDefinition<Self>(
request: { completion in
DispatchQueue.main.async {
completion(fetchAll())
}
completion(fetchAll())
},
objectCreationToken: ModelCreationToken<Self>(),
dataResetTokens: dataResetTokens
Expand Down
11 changes: 9 additions & 2 deletions Example/iOS-Example/Model.swift
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,11 @@ extension Model: FetchableObjectProtocol {
}

func observeIsDeletedChanges(_ handler: @escaping @MainActor () -> Void) -> InvalidatableToken {
self.observe(\.isDeleted, options: [.old, .new]) { @MainActor(unsafe) object, change in
self.observe(\.isDeleted, options: [.old, .new]) { object, change in
guard let old = change.oldValue, let new = change.newValue, old != new else {
return
}
handler()
unsafeHandler(for: handler)
}
}

Expand All @@ -133,6 +133,13 @@ extension Model: FetchableObjectProtocol {
}
}

@MainActor(unsafe)
private func unsafeHandler(for handler: @MainActor () -> Void) {
assert(Thread.isMainThread)
// This is a dumb wrapper, but I can't otherwise have a "clean" compile
handler()
}

// MARK: - Private Helpers

private extension Model {
Expand Down
24 changes: 11 additions & 13 deletions Example/iOS-Example/SwiftUIView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,22 @@ struct SwiftUIView: View {
.transition(.slide)
.navigationBarTitle("SwiftUI Example", displayMode: .inline)
.navigationBarItems(
leading:
Button {
Model.reset()
} label: {
Image(systemName: "trash")
},
trailing:
Button {
try? Model().save()
} label: {
Image(systemName: "plus")
}
leading: Button {
Model.reset()
} label: {
Image(systemName: "trash")
},
trailing: Button {
try? Model().save()
} label: {
Image(systemName: "plus")
}
)
}
}
}

// Mark: List Row
// MARK: List Row
extension SwiftUIView {
@ViewBuilder
func row(for model: Model) -> some View {
Expand Down
2 changes: 1 addition & 1 deletion Example/iOS-Example/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ private extension ViewController {
func addItem(_ sender: Any) {
try? Model().save()
}

@objc
func showSwiftUI(_ sender: Any) {
present(UIHostingController(rootView: SwiftUIView()), animated: true)
Expand Down
25 changes: 19 additions & 6 deletions FetchRequests/Sources/SwiftUI/FetchableRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,11 @@ public struct FetchableRequest<FetchedObject: FetchableObject>: DynamicProperty
return
}

var isSynchronous = true

defer {
fetchController.performFetch()
isSynchronous = false
}

let controller = fetchController
Expand All @@ -112,12 +115,22 @@ public struct FetchableRequest<FetchedObject: FetchableObject>: DynamicProperty
guard let controller else {
return
}
withAnimation(animation) {
let newVersion = binding.wrappedValue.version + 1
binding.wrappedValue = FetchableResults(
contents: controller.fetchedObjects,
version: newVersion
)
let change: () -> Void = {
withAnimation(animation) {
let newVersion = binding.wrappedValue.version + 1
binding.wrappedValue = FetchableResults(
contents: controller.fetchedObjects,
version: newVersion
)
}
}

if isSynchronous {
DispatchQueue.main.async {
change()
}
} else {
change()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,11 @@ extension CollapsibleSectionsFetchedResultsControllerTestCase {
let originalObjects = createTestObjects(count: 20, inSectionsOfLength: 10)
try performFetch(originalObjects)

XCTAssert(controller.sections[0].allObjects.count == 10)
XCTAssertEqual(controller.sections[0].allObjects.count, 10)
XCTAssertEqual(controller.sections[0].displayableObjects.count, maxNumberOfItems)

XCTAssert(controller.sections[1].allObjects.count == 10)
XCTAssert(controller.sections[1].displayableObjects.count == controller.sections[1].allObjects.count)
XCTAssertEqual(controller.sections[1].allObjects.count, 10)
XCTAssertEqual(controller.sections[1].displayableObjects.count, controller.sections[1].allObjects.count)

controller.update(section: controller.sections[0], maximumNumberOfItemsToDisplay: 6)
XCTAssertEqual(controller.sections[0].displayableObjects.count, 6)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ class FetchableObjectProtocolTestCase: XCTestCase {
let data: TestObject.RawData = ["id": "1", "test": 2]
var newData: TestObject.RawData = ["id": "1", "test": 3]

XCTAssertFalse(data == newData)
XCTAssertNotEqual(data, newData)

newData.test = 2

XCTAssertTrue(data == newData)
XCTAssertEqual(data, newData)
}
}
2 changes: 1 addition & 1 deletion FetchRequests/Tests/Models/JSONTestCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ extension JSONTestCase {
func testNonJsonNSObjectForBoxedJSON() {
let set = NSSet(objects: "1", "2")
let boxed = BoxedJSON(__object: set)
XCTAssertTrue(boxed == nil)
XCTAssertNil(boxed)
}

func testJsonNSObjectForBoxedJSON() {
Expand Down