6 ms·
> the seemingly secret Swift magic that's used to implement some features What magic are we talking about? I thought all the new stuff was RFC'd right after Sw
by lilyball 7y ago
> the seemingly secret Swift magic that's used to implement some features
What magic are we talking about? I thought all the new stuff was RFC'd right after SwiftUI was announced.
- Razengan 7y agoMaybe I'm just dumb, but there seem to be arcane tricks that SwiftUI's native types can do but I can't replicate in my own types.
- machello13 7y agoI believe SwiftUI's not doing anything that isn't available in the public version of Swift. There may be some stuff that's still going through the proposal process, not sure.
- DelightOne 7y agoHis problem might be that certain features (of SwiftUI) you cannot hook yourself (your own implementation) into (since they are based on protocols which cannot be implemented yourself since they are not public and so not meant to be implemented by yourself), which makes it, at times, necessary to use workarounds to public-facing apis. Or it might be something else.
- Razengan 7y agoYou're correct, part of the problem is indeed that, though I'm not completely sure myself. But how do things like EmptyView work? How do they conform to the View protocol without having a body property (that must also be a View)?
- DelightOne 7y agoI think it has a body type [0] (Never). And since a default implementation is provided [1] the compiler probably does not complain. This default body implementation does likely not draw anything, but that's just guessing. [0]: https://developer.apple.com/documentation/swiftui/emptyview/body https://developer.apple.com/documentation/swiftui/emptyview/... [1]: https://developer.apple.com/documentation/swiftui/view/3278523-body https://developer.apple.com/documentation/swiftui/view/32785...
- favorited 7y agoIt's because of Body's type: public struct EmptyView: View { @inlinable public init() public typealias Body = Never } Because Body is Never, you can't access EmptyView's body property.
- Razengan 7y agoCan we write a protocol + type like that? https://forums.swift.org/t/how-do-views-like-emptyview-conform-to-the-view-protocol https://forums.swift.org/t/how-do-views-like-emptyview-confo...
- favorited 7y agoI don't see why not. When I trick it into calling `body` on an EmptyView, I get this runtime failure: > Thread 1: Fatal error: body() should not be called on EmptyView. So I don't think the implementation is doing anything beyond the fatalError() call from that forum thread. At least not at this point in time.
- lilyball 7y agoI haven't really dug into SwiftUI yet, but I'm not quite sure what you're describing. I'd love to see a concrete example of something you think you can't replicate with your own type.
- Razengan 7y agoI tend to run into these when weaving a lot of SwiftUI + non-SwiftUI code together. A simple example: [0]. There are workarounds for this specific issue, but trying to do complex stuff sometimes surfaces inscrutable limitations that I can't quite figure out. And with no documentation relevant to a particular case, no Google hits, not even on Apple's forums, and the uncertainty of error messages, I'm not even sure if I'm doing something wrong or it just can't/shouldn't be done. I have to try random things until it works...until it doesn't. I'm currently experimenting with a SwiftUI layer for a game engine [1], and running into weird undocumented differences between macOS and iOS (like view backgrounds clipping at stack container edges on macOS but not on iOS) that I can't be sure if they're bugs or what. Still, I love SwiftUI. Also see EmptyView [2] [0] https://gist.github.com/ShinryakuTako/5a7b32bbf4f4c3874439c2261489522a https://gist.github.com/ShinryakuTako/5a7b32bbf4f4c3874439c2... [1] https://github.com/InvadingOctopus/octopuskit https://github.com/InvadingOctopus/octopuskit [2] https://forums.swift.org/t/how-do-views-like-emptyview-conform-to-the-view-protocol/26235/29 https://forums.swift.org/t/how-do-views-like-emptyview-confo...
- DelightOne 7y agoI think the issue is that a variable's type can't be set by the outside (via the template parameter ViewType) and by the inside (to be of type EmptyView) at the same time. You have to decide. Your workaround is to use the AnyView type I guess. Or a conditional with either EmptyView or the template type (displayed). What would be the name of the feature that allows you to use a default template type if no argument is given to figure out the type to use?
- Razengan 7y ago> Your workaround is to use the AnyView type I guess. Yes, I made the init generic instead of the type, and made the property an AnyView, but I've read that AnyView may decrease performance (probably because of reasons discussed in this post's article.)
- layoutIfNeeded 7y agoYep. The funny thing is that if you try to use this new automatic type-erasure stuff for anything but SwiftUI, you will soon encounter compiler errors like “`some` types are only implemented for method return types or computed property accessor return types”. Lol. So e.g. you can’t use `some`-typed variables or stored properties.
- NobodyNada 7y agoThe `some` keyword declares an opaque result type ([0]), which means "this function has a concrete return type, but the identity of that type is a hidden implementation detail." An opaque result type can be used like a generic type -- the compiler doesn't know the exact type, but it does know that calls to the function will always return the same type (which is important when working with protocols such as `Equatable` that have associatedtype or Self requirements). A `some`-typed variable or stored property wouldn't make any sense because it would be a variable that has a concrete but unknown type. You can't assign something to such a variable, because there's no way to know whether the value you're trying to assign matches the hidden concrete type of the variable. Perhaps the "automatic type-erasure" feature you're wanting is actually generalized existentials ([1])? Generalized existentials would allow you to declare a variable whose type can be "any Equatable", rather than "some (specific but unknown) Equatable", and the compiler would allow you to "open" the existential and use it like a generic type (without throwing the "protocol can only be used as a generic constraint because it has Self or associatedtype requirements" error). [0]: https://docs.swift.org/swift-book/LanguageGuide/OpaqueTypes.html https://docs.swift.org/swift-book/LanguageGuide/OpaqueTypes.... [1]: https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#generalized-existentials https://github.com/apple/swift/blob/master/docs/GenericsMani...
- favorited 7y agoYou definitely can have a 'some' type property[0]. Computed properties work just like functions do. Stored properties just need a value assigned, like so: let strings: some Collection = ["hello", "world"] [0]https://github.com/apple/swift-evolution/blob/master/proposals/0244-opaque-result-types.md#properties-and-subscripts https://github.com/apple/swift-evolution/blob/master/proposa...
- slavapestov 7y agoSwiftUI relies on implicit return statements, property wrappers, keypath member lookup and function builders. All but the last have gone through the evolution process and are implemented completely in Swift 5.1. The function builders feature has been pitched and is going through the process; the current implementation uses an underscored attribute. The implementation might change but it will not affect client code, only the declarations of the relevant types in SwiftUI. This means you can’t define your own function builders today without a future compiler possibly breaking source compatibility with your implementation — but other than that there’s no magic in the SwiftUI API beyond the language itself.