Comments (5)
Hi @beny, I'm totally aware of this issue. When I first wrote the code I thought about it for a very long time because, as you said, it's really annoying to branch your code everywhere depending on the target platform. The reasons why I chose this path are the following:
- It seems that it is the direction Swift takes
- Adding more and more devices makes it more complicated to handle all cases (what if your app is exclusively iOS but the framework wants you to handle cases for each Apple TV, each Apple Watch** and each MacBook**)
Currently I have to write this, because not all funcs and vars are available everywhere
I'm planning to unify the API as much as possible (there are some cases which don't make sense), but this also seems to be a direction of Swift (e.g. you can add methods to Arrays only if they contain Ints). I thinks that's similar.- Ultimately, even if the impact on code size is negligibly small, watchOS code should not be delivered with iOS code (I think this should also be semantically separated, communicated to the developer though the use of
#if os(iOS)
etc.)
Or is there any issue with Simulator detection or something else?
IIRC there are plans to add an #if arch(simulator)
or similar and I thought about whether or not we should move to this as well... On the one hand side I think it would clean-up the code (strictly, you don't have a .simulator case on iOS [which feels right because there is no real Simulator device], but on the other hand it complicates code on the consumer side of the framework a lot ...
That being said, I'm not sold on the current design and I'd very much appreciate discussing a different solution :) Thanks for starting this!
[Since we're still on 0.x.x releases the API can change dramatically (though I would like it to not change too much ...). I'm currently working on a protocol-oriented implementation that provides the exact same API.]
** Those are features I'm planning to provide eventually, currently there's only iDevices and Apple TV's.
from devicekit.
Hi @beny (and everyone who thankfully watches this project or might read this by accident),
Taking your thoughts (hopefully) I tried to come up with something (this is just bikeshedding at the moment, but I hope you get the idea):
The idea is that we use a DeviceType
protocol to collect all the common functionality. Then, there is no Device
type anymore but a Phone
, Pad
, Watch
, TV
, Computer
type. All of those are available on all platforms, having a failable initializer they could only be instantiated on their corresponding Device
(so on an iPhone you cannot create a Pad
).
Minimal implementation (requires Swift 3):
protocol DeviceType: Equatable {
init?()
var name: String { get }
}
enum Phone: DeviceType {
case iPhone1
case iPhone2
var name: String { return "Phone" }
init?() {
self = .iPhone1
}
}
enum Pad: DeviceType {
case iPad1
case iPad2
var name: String { return "Pad" }
init?() {
self = .iPad1
}
}
func == (lhs: DeviceType, rhs: DeviceType) -> Bool {
return lhs.name == rhs.name
}
// Would be defined inside the framework
let currentDevice: DeviceType = Phone() ?? Pad()! // Where can we put `currentDevice`?, don't like it global...
Now, the interesting part. This is how the call site would look like:
func test() {
let name = currentDevice.name
if currentDevice is Pad {
}
if let pad = currentDevice as? Pad {
if pad == .iPad1 {
}
}
}
What I really like about this approach is that we can use the is
language construct to check whether or not we are currently on that device (instead of the current .is*****
methods). Depending on how much functionality we put into the DeviceType
protocol the as?
casting would be mostly unnecessary.
What do you all think? Any feedback is very welcome!
from devicekit.
It looks great, easy to read the code with the is
and that's good thing. The latter example would be probably also (don't know if it's valid syntax in Swift 3):
if let pad = currentDevice as? Pad where pad == .iPad1 {}
Looking forward to this update.
from devicekit.
Hey @beny! Sorry it took me so long, I have a branch for you (and others of course) to play with: https://github.com/dennisweissmann/DeviceKit/tree/WIP/the-great-protocol-transformation
However, this is a work in progress and only rudimentary features are implemented, namely: Device detection, device group detection.
There is definitely a need for a few helper methods to make detection easier and don't require the consumer of the API to write the code I have put in the "Tests" (it's not really tested atm :D)
Currently you can identify your device like this:
func testCurrentDevice() {
let currentDevice = DeviceKit.currentDevice
switch currentDevice {
case let currentDevice as Pad:
switch currentDevice {
case .iPad2: print("Is iPad 2")
case .iPad3: print("Is iPad 3")
case .iPad4: print("Is iPad 4")
case .iPadAir: print("Is iPad Air")
case .iPadAir2: print("Is iPad Air 2")
case .iPadMini: print("Is iPad Mini")
case .iPadMini2: print("Is iPad Mini 2")
case .iPadMini3: print("Is iPad Mini 3")
case .iPadMini4: print("Is iPad Mini 4")
case .iPadPro: print("Is iPad Pro")
case .simulator(let pad): print("Is iPad simulator: \(pad)")
case .unknownPad(let unknown): print("Currenlty unknown device: \(unknown)")
}
case is Phone: print("Is iPhone")
default: break
}
// Or a short way:
print("\(currentDevice)")
}
Currently only iPads, iPhones, and Apple TV are supported, but this will (hopefully) change in the future.
If you have time I would love to hear from you what you think :)
from devicekit.
I’ll close this issue since there doesn’t seem to be very much interest in that feature, thanks for proposing it anyways! 🙏
from devicekit.
Related Issues (20)
- Compile xcframework for releases
- List supported iOS versions by device
- Support for building with visionOS SDK
- Deprecated: `UIScreen.main` HOT 1
- Add newly released devices HOT 7
- Privacy manifest files
- No longer compiles on visionOS HOT 2
- Missing 5.1 in CocoaPods HOT 1
- Feature Request: provide `.hasUSBCConnectivity` for device with USB-C port by opposition of Lightning HOT 1
- Can't update to DeviceKit v5.2.0 for SPM HOT 12
- Add support for Apple Vision Pro HOT 8
- Use Swift Macros instead of GYB?
- If a device send you its device identifier through network
- Development Team Required
- screenBrightness
- iPhone XR HOT 2
- Please use cocoapod resource_bundles for PrivacyInfo HOT 5
- Library evolution support.
- Spotlights van mees
- Describing use of required reason API HOT 6
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 devicekit.