GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |
GeezerVison is showing github.com — feat(swift-interop): adapter lifetime, cancellation, subscripts, Combine and operators (6/7) by NathanWalker · Pull Request #523 · NativeScript/ios Conversation
|
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews: auto_review: drafts: true
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
4eb9b59 to
d43b891
Compare
8c4d970 to
7a3876e
Compare
…fetime rule (ABI 14)
A JS object passed as a protocol value now gets one Swift adapter per
protocol instead of a new one per call. Swift sees one identity, so
`removeAll { $0 === listener }` matches.
The runtime owns each adapter while its JS object lives. Before each
garbage collection it holds the JS object strongly if anything else
retains the adapter, and weakly otherwise. This follows NativeScript's
rule for the JS side of Objective-C objects:
- strong Swift references (`var delegate`) keep the JS object alive;
- `weak var delegate` holds it for as long as JS keeps it, then becomes
nil.
Once neither side holds them, both are collected. Previously a weakly
held adapter was freed as soon as the call returned.
Calls through an adapter whose JS object was collected fail like a JS
implementation that throws.
Thunk ABI 14: API slots 54 (adapterOf) and 55 (adoptAdapter).
An async member now takes an optional AbortSignal after its arguments: `await fetchItems(query, controller.signal)`. Aborting rejects the Promise at once with the signal's reason, as fetch does, and cancels the Swift task. Results the task reports afterwards are dropped. A signal that is already aborted rejects without calling Swift. The signal is taken off before overload resolution, so it never competes with real arguments. Async thunks keep their Task and register a cancel hook for the call's token. TypeScript declares `signal?: AbortSignal` on async members, and types/ns-swift.d.ts declares a minimal AbortSignal for programs without the DOM library. Thunk ABI 15: API slot 56 (setCancel).
…hods
A subscript with indices is now a JS method: `shelf.subscript("apples")`
reads it. A settable one also gets `shelf.setSubscript("apples", 3)`,
which assigns it, writing through a struct's box in place. Subscripts
are overloaded like methods, by their indices. Named methods keep
property access untouched and can't collide with a type's own `get` or
`set`.
The surface adds the setter as a synthetic member, and the emitter
spells `receiver[indices]` and `receiver[indices] = value`. Against the
iOS 18 SDK this adds 2 WeatherKit, 4 Foundation, 5 SwiftUI, 1 SwiftData
and 1 Charts callables. Every module's thunks still type-check.
…oop exit A bridged class or struct conforming to AsyncSequence now keeps its JS class and other members, and is also async-iterable through a synthetic `[Symbol.asyncIterator]()`. The element comes from its `Element` typealias, or else from its iterator's own `next()`. AnyPublisher, PassthroughSubject and CurrentValueSubject are async iterators over their `values` on iOS 15+, and null on earlier systems. Thunks import Combine when one is bridged. Async iterators now implement `return()`, so leaving a `for await` loop early releases the Swift iterator. That ends a stream Swift still produces: AsyncStream's onTermination sees `.cancelled`, and a publisher's subscription is cancelled.
Operators are now JS methods named for what they do: - `+` `-` `*` `/` `%` are `plus`, `minus`, `times`, `dividedBy` and `remainder`; - `==`, `<`, `<=`, `>` and `>=` are `equals`, `lessThan`, `lessThanOrEqualTo`, `greaterThan` and `greaterThanOrEqualTo`; - prefix `-` and `!` are `negated()` and `not()`. An operator whose left operand is its own type is an instance method of that operand (`a.plus(b)`); any other is static (`Vector2.times(2, v)`). Compound assignment, bitwise and custom operators stay unexposed. Equatable classes and structs (also through Hashable or Comparable) now get `equals(other)`, and Comparable ones get `compare(other)`, which returns -1, 0 or 1 from Swift's `<`. Symbol graphs omit the `==` the compiler synthesizes, so these come from the conformances. Against the iOS 18 SDK this adds 238 Foundation, 106 SwiftUI, 42 WeatherKit, 20 SwiftData, 6 Charts and 3 Observation callables. Every module's thunks still type-check.
A type parameter constrained to Sequence, Collection or another protocol arrays conform to now stands in as an array. With `where C.Element == X` the stand-in is `[X]`; otherwise it is an array of each of the element's own stand-ins. `C.Element` in the signature is substituted to match. `some Sequence<Int>` stands in as `[Int]`. A parameter typed `any Sequence<E>` (or another such protocol) takes an array, and a result of that type is copied out as one. Against the iOS 18 SDK this adds 5 Foundation and 2 SwiftUI callables. Every module's thunks still type-check.
7a3876e to
ae7d342
Compare
d43b891 to
1c568f9
Compare
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.