composed-swift / composed Goto Github PK
View Code? Open in Web Editor NEWA Swift framework for composing data.
License: Other
A Swift framework for composing data.
License: Other
Move code from ComposedUI and ComposedLayouts in to this repo (Composed)
2 main reasons:
The change would be fairly easy (copy/paste, small update to Package.swift).
I think this is a breaking change; import ComposedUI
would be ambiguous (?)
None
[A clear and concise description of what the bug is]
[Steps to reproduce the issue]
[A clear and concise description of what you expected to happen]
[Add any other context about the problem here]
RandomAccessCollection
We already provide some enhancements on ArraySection
to make it behave more like an array. In addition we could add further conformance on Section
itself using where
clauses.
E.g.
extension Section where Self: RandomAccessCollection {
public var numberOfElements: Int { return count }
}
ComposedMedia sections don't currently conform to the recent updates due to missing auto-conformance. Adding RandomAccessCollection
conformance to Section
fixes this and other potential sections in the future.
This is an additive feature.
There's no licence associated with the project (or the others in this organisation). Could one be added?
A crash can happen when an update occurs as a side effect of a view being configured, e.g. the following will trigger a crash:
0, 0
0, 0
deletes item 0, 0
during configurationA somewhat more reasonable example would be something in a header (e.g. a series of tabs) triggering the update as a setup of initial state.
This is because the updates
closure of performBatchUpdates
is still being called so the delete is processed in the context prior to the insert. This is generally a misuse of UICollectionView
and is hard to create a correct fix.
Consumers should be discouraged from performing updates during configuration, but it would be nice if this could be detected and the crash prevented.
The updates are applied in https://github.com/opennetltd/Composed/blob/batch-collection-view-updates-closure/Sources/ComposedUI/CollectionView/CollectionCoordinator.swift#L254, which can be simplified as:
print("Calling `performBatchUpdates`")
collectionView.performBatchUpdates({
print("Starting batch updates")
// ... apply updates
print("Batch updates have been applied")
}, completion: { [weak self] isFinished in
print("Batch updates completed. isFinished: \(isFinished)")
})
print("`performBatchUpdates` has been called")
I have then seen logs like:
Calling `performBatchUpdates`
Starting batch updates
Batch updates have been applied
Calling `performBatchUpdates`
Starting batch updates
Batch updates have been applied
`performBatchUpdates` has been called
`performBatchUpdates` has been called
Calling `performBatchUpdates`
Starting batch updates
Batch updates have been applied
**Crash**
Note how Starting batch updates
is printed twice before the `performBatchUpdates` has been called
. How can this be possible?
This made me look at this a little more, and only raised more questions. The updates closure has to be sync because it's not escaping (although I don't see this in the actual header and it is optional, but somehow Swift thinks it's not escaping) and Batch updates have been applied
is always printed before another update.
It looks like collection view is blocking the return from performBatchUpdates
and multiple calls are possible, but this is all being done on the main thread. This makes me think my method of testing is wrong but I can't see what it could be.
Note that the crash occurs when updates are applied as:
Since the completion hasn't been called yet I think it hasn't committed the insert yet and it crashes with a message stating that it can't delete element 0,0 because it doesn't exist yet.
One solution is to wait for completion to be called before applying more updates but this would then make all updates within Composed potentially async and introduce delay (due to waiting for layout) that isn't required the majority of the time.
The documentation of CollectionCoordinatorDelegate.coordinator(_:backgroundViewInCollectionView:)
states:
Return a background view to be shown in the
UICollectionView
when its content is empty. Defaults to nil
This is wrong because the background view is set even when the collection view is not empty.
It also causes what I could class as a bug: whenever CollectionCoordinator.prepareSections()
is called it will reset the background view, even when the delegate is nil
.
Use CollectionCoordinator
backgroundView
when delegate
is nil
or the default implementation of CollectionCoordinatorDelegate.coordinator(_:backgroundViewInCollectionView:)
is usedWhen calling ComposedSectionProvider.append(_:)
with a Section
the updateDelegate
is not set (and ComposedSectionProvider
does not conform to SectionUpdateDelegate
). This causes any updates propagated by the section to not be honoured.
It looks like these updates should be propagated up, performing mapping as required. Does SectionProviderUpdateDelegate
need to inherit SectionUpdateDelegate
to ensure these updates are not lost?
Suspendible
supportComposed should introduce the concept of a Section
being Suspendible
in order to prevent user-driven events triggering duplicate events in UIKit.
ManagedSection
is backed by CoreData and currently provides dedicated functions for suspending updates in order to support user-driven events (e.g. reordering).
However the general pattern used by Composed is to 'discover' features through the use of a protocol. To bring this inline with the rest of Composed, I'm proposing we introduce a protocol to add support for this:
public protocol Suspendible {
func suspend()
func resume()
}
In addition I feel we should add similar methods to the appropriate Coordinator
's:
This is just to provide a simple convenience for the API consumer. The implementation would be:
extension CollectionCoordinator {
func suspend() {
sectionProvider.sections
.compactMap { $0 as? Suspendible }
.forEach { $0.suspend() }
}
func resume() {
sectionProvider.sections
.compactMap { $0 as? Suspendible }
.forEach { $0.resume() }
}
}
Currently only ManagedSection
would implement this protocol however formalising this approach allows custom Section
's to piggy-back on this behaviour as well.
This should be purely additive.
N/A
This is currently in progress and will be in a PR later this week.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.