Comments (4)
I see. If you wish to still have a way to do it your way, specifying the identifier
at call site every time or needing a storyboard instance, that can still be added, but tbh I quite dislike (and it's quite dangerous to, actually) adding extensions
on types that are part of Cocoa and that don't use any way of disambiguation.
What I mean by that is that is basically in these cases, you'll need a prefix like func ps_instantiate
instead of just func instantiate
to ensure that there is no name collision in the future.
Because, sure, now Swift has the concept of modules, and if you declare a class with a given name and a class of the same name is later added to UIKit, you can always disambiguate with the full name ModuleName.ClassName
. But for extensions there's no way to do that, so an extension on a type that is part of UIKit and that adds a method that only make use of UIKit and Foundation parameters can totally conflict with a future implementation that Apple would add to UIStoryboard
. The only case when you can safely create an extension
on some type provided by Apple is if your extension adds functions that themselves use custom types from your own module, because that way you don't risk conflicting with an hypothetical future function of the same name added by Apple.
That's one of the main reasons why I prefer Mixins and adding protocol conformance instead of adding an extension directly on UIStoryboard
. Because then that change is only opt-in and won't risk propagating to every UIViewController
(including the ones in other modules/frameworks you might depend on) and it only applies to what the consumer of the library choose to.
The user of the library can still totally write extension: UIViewController: StoryboardSceneBased {}
somewhere in its own source code so that all UIViewControllers have that instantiate()
method by default, but at least that's their choice at that point.
That's the same reason I didn't extend UITableViewCell
to mark all of them all as Reusable
so they have a default reuseIdentifier
. Because some people might not want all their cells to use that API (in case you're progressively migrating to Reusable
and your old cells still don't use it but only your new ones for example) and because I didn't want to risk affecting UITableViewCells
used by the system in some standard UIViewControllers
or affecting cells that are part of dependent frameworks. People can still write extension UITableViewCell: Reusable {}
in their own code if they want that anyway.
Note that for the part of the Reusable
framework that deals with cells, I did make extensions
on a UIKit type (extension UITableView
and extension UICollectionView
, but that's OK because those extensions only add functions that contains params or generics that depend on my own type, so there's no risk of conflicting with hypothetic future implementations added by Apple or by extensions added by other frameworks in your project.
from reusable.
Thanks for the explanation about what driven you to make that design decision. I really like what you have done and I find your approach really cool. 👍🏻 Truth is my suggestion doesn't fit to the current approach that you have chosen and it might feel weird to mix these two different approaches. So, I believe it will be better not to include it in Reusable
.
Thanks for the time and the effort and that you put on this thread 😀, I really appreciate it. 👍🏻
from reusable.
This approach seems nice, thanks for the suggestion 👍 I also don't like as!
and prefer generics as you propose 😉
You can see in my talks here some techniques on how to avoid that and that it made me come up with Reusable. But basically that's a similar technique as what you present in your solution, using both generics and type inference to do some magic.
The whole point of Reusable
is to get rid of the String-based APIs, including getting rid of String identifiers, because e.g. with your solution:
- you can still call
let colorViewController = storyboard?.instantiate(type: ColorViewController.self, identifier = "foo")
somewhere andlet colorViewController = storyboard?.instantiate(type: ColorViewController.self, identifier = "bar")
somewhere else, which will probably not make sense as the storyboard identifier to use is probably always the same for a given ViewController in a given Storyboard, right? - you could improve your solution by adding a default value of
= T.self
to yourtype: T.Type
parameter. See my talk/slides "Mixins over Inheritance" where I explain exactly this technique in Reusable among others to make all that even safer.
So basically, Reusable already allows to do something similar to what you're proposing, especially just using let colorViewController = ColorViewController.instantiate()
and it will do all the magic, using the right storyboard and the right identifier automatically (specified in the type, with a default value derived from the name of the class but you can specify a different storyboard and identifier in case they are not named the same)
So, that said, I wonder if what already exists in Reusable
(see also this article explaining all the steps and little magic stuff like generics behind Reusable
and what you can do with it) wouldn't be sufficient for you?
Basically, what you suggested is indeed cool and uses the right bit of Swift magic, but I wonder if let colorViewController = ColorViewController.instantiate()
wouldn't be even better, or if you have a specific need for still providing the identifier on every call like in your implementation? I mean, I'm totally ok to add your implementation if the implementation in Reusable is limited to you and doesn't address some cases you need, but given what you've presented, I wonder if it isn't in fact already covered by Reusable
itself?
from reusable.
Thanks @AliSoftware for that. 😀
Well, my suggestion doesn't cover something that is not already covered in Reusable
, it just provides a different way without protocol conformance. The trade off though (in the case the identifier is same as the class name, func instatiate<T: UIViewController>(type: T.Type = T.self, identifier: String? = nil) -> T
😉 ) is that it always needs a storyboard instance .. It might come handy in cases that some view controllers are not called more than once I assume or are called from within the same storyboard of the caller. In any other case ColorViewController.instantiate()
seems more appropriate. 👍🏻
That said, I really appreciate your time and your input on that 😀, I really enjoyed it. 👍🏻
from reusable.
Related Issues (20)
- getting error on using cellType(for indexPath:)
- Support for new API introduced on iOS 13
- MKMapView support
- Feature request - allow to use UITableViewCell with custom style
- Swift Package Manager: reusable deployment target warning HOT 3
- SPM xibs (Bundle.module) HOT 1
- Xcode 12.5 warnings HOT 2
- Swift tools version update too high, lower version build failed
- UITableViewHeaderFooterView - Warning with NibReusable
- Sure, go ahead!
- ## Summary
- Feature request - access to root xib view
- Support for reusable UITableViewHeaderFooterView subclasses?
- NibReusable should have bundle as an optional parameter HOT 5
- Swift 5 Support? HOT 2
- Undefined symbols when compiling for unit tests HOT 1
- Xcode 11 beta 4 compiler error HOT 1
- loadNibContent always loads nib named after base class HOT 14
- is there a way to override sceneStoryboard for StoryboardSceneBased HOT 2
- Swift Package Manager HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from reusable.