Skip to content

Commit

Permalink
Merge pull request #88 from Nirma/WKDeviceComplete
Browse files Browse the repository at this point in the history
Apple Watch devices support
  • Loading branch information
Nirma committed Sep 26, 2023
2 parents 488c0dd + a4a2e1c commit 7f2d9f5
Show file tree
Hide file tree
Showing 14 changed files with 582 additions and 16 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/swift.yml
Expand Up @@ -10,5 +10,7 @@ jobs:
DEVELOPER_DIR: /Applications/Xcode_14.0.app/Contents/Developer
steps:
- uses: actions/checkout@v2
- name: Test
- name: Test (iOS)
run: set -o pipefail && env NSUnbufferedIO=YES xcodebuild -project "UIDeviceComplete.xcodeproj" -scheme "UIDeviceComplete" -destination "OS=16.0,name=iPhone 14 Pro" clean test | xcpretty
- name: Test (watchOS)
run: set -o pipefail && env NSUnbufferedIO=YES xcodebuild -project "UIDeviceComplete.xcodeproj" -scheme "UIDeviceComplete" -destination "OS=9.0,name=Apple Watch Series 8 (45mm)" clean test | xcpretty
7 changes: 7 additions & 0 deletions .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Package.swift
Expand Up @@ -25,7 +25,7 @@ import PackageDescription
let package = Package(
name: "UIDeviceComplete",
platforms: [
.iOS(.v11)
.iOS(.v11), .watchOS(.v4)
],
products: [
.library(name: "UIDeviceComplete", targets: ["UIDeviceComplete"])
Expand Down
3 changes: 3 additions & 0 deletions Sources/DeviceFamily.swift
Expand Up @@ -26,6 +26,7 @@ public enum DeviceFamily: String {
case iPhone
case iPod
case iPad
case watch
case unknown

public init(rawValue: String) {
Expand All @@ -36,6 +37,8 @@ public enum DeviceFamily: String {
self = .iPod
case "iPad":
self = .iPad
case "Watch":
self = .watch
default:
self = .unknown
}
Expand Down
66 changes: 62 additions & 4 deletions Sources/DeviceModel.swift
Expand Up @@ -23,6 +23,7 @@

public enum DeviceModel: CaseIterable {

#if os(iOS)
case iPhone4, iPhone4S
case iPhone5, iPhone5C, iPhone5S
case iPhone6, iPhone6Plus
Expand Down Expand Up @@ -62,7 +63,24 @@ public enum DeviceModel: CaseIterable {

case iPodTouchFirstGen, iPodTouchSecondGen, iPodTouchThirdGen,
iPodTouchFourthGen, iPodTouchFifthGen, iPodTouchSixthGen, iPodTouchSeventhGen


#elseif os(watchOS)
case firstGen
case series1
case series2
case series3
case series4
case series5
case se
case series6
case series7
case series8
case se2
case ultra
case series9
case ultra2
#endif

case unknown
}

Expand All @@ -72,19 +90,24 @@ public enum DeviceModel: CaseIterable {
extension DeviceModel {
init(identifier: Identifier) {
switch identifier.type {
#if os(iOS)
case .iPhone:
self = DeviceModel.detectIphoneModel(with: identifier)
case .iPad:
self = DeviceModel.detectIpadModel(with: identifier)
case .iPod:
self = DeviceModel.detectIpodModel(with: identifier)
#elseif os(watchOS)
case .watch:
self = DeviceModel.detectWatchModel(with: identifier)
#endif
default:
self = .unknown
}
}
}


#if os(iOS)
// MARK: Detecting iPhone Models

extension DeviceModel {
Expand Down Expand Up @@ -154,8 +177,9 @@ extension DeviceModel {
}
}
}
#endif


#if os(iOS)
// MARK: Detecting iPad Models

extension DeviceModel {
Expand Down Expand Up @@ -207,8 +231,9 @@ extension DeviceModel {
}
}
}
#endif


#if os(iOS)
// MARK: Detecting iPod Models

extension DeviceModel {
Expand All @@ -230,8 +255,40 @@ extension DeviceModel {
}
}
}
#endif

#if os(watchOS)
// MARK: Detecting Apple Watch Models

extension DeviceModel {
fileprivate static func detectWatchModel(with identifier: Identifier) -> DeviceModel {
guard let major = identifier.version.major,
let minor = identifier.version.minor
else { return .unknown }

switch (major, minor) {
case (1, _): return .firstGen
case (2, 3), (2, 4): return .series2
case (2, 6), (2, 7): return .series1
case (3, _): return .series3
case (4, _): return .series4
case (5, 1), (5, 2), (5, 3), (5, 4): return .series5
case (5, 9), (5, 10), (5, 11), (5, 12): return .se
case (6, 1), (6, 2), (6, 3), (6, 4): return .series6
case (6, 6), (6, 7), (6, 8), (6, 9): return .series7
case (6, 10), (6, 11), (6, 12), (6, 13): return .se2
case (6, 14), (6, 15), (6, 16), (6, 17): return .series8
case (6, 18): return .ultra
case (7, 1), (7, 2), (7, 3), (7, 4): return .series9
case (7, 5): return .ultra2

default: return .unknown
}
}
}
#endif

#if os(iOS)
// MARK: Detecting the Notch

extension DeviceModel {
Expand Down Expand Up @@ -266,3 +323,4 @@ extension DeviceModel {
}
}
}
#endif
97 changes: 97 additions & 0 deletions Sources/Identifier.swift
Expand Up @@ -69,6 +69,8 @@ extension Identifier: CustomStringConvertible {
return iPadStringRepresentation(major: major, minor: minor)
case .iPod:
return iPodStringRepresentation(major: major, minor: minor)
case .watch:
return watchStringRepresentable(major: major, minor: minor)
case .unknown:
return "unknown"
}
Expand Down Expand Up @@ -384,4 +386,99 @@ extension Identifier: CustomStringConvertible {
return "unknown"
}
}

private func watchStringRepresentable(major: Int, minor: Int) -> String {
switch (major, minor) {
case (1, 1):
return "Apple Watch (1st generation), 38mm case"
case (1, 2):
return "Apple Watch (1st generation), 42mm case"
case (2, 3):
return "Apple Watch Series 2, 38mm case"
case (2, 4):
return "Apple Watch Series 2, 42mm case"
case (2, 6):
return "Apple Watch Series 1, 38mm case"
case (2, 7):
return "Apple Watch Series 1, 42mm case"
case (3, 1):
return "Apple Watch Series 3, 38mm case (GPS + Cellular)"
case (3, 2):
return "Apple Watch Series 3, 42mm case (GPS + Cellular)"
case (3, 3):
return "Apple Watch Series 3, 38mm case (GPS)"
case (3, 4):
return "Apple Watch Series 3, 42mm case (GPS)"
case (4, 1):
return "Apple Watch Series 4, 40mm case (GPS)"
case (4, 2):
return "Apple Watch Series 4, 44mm case (GPS)"
case (4, 3):
return "Apple Watch Series 4, 40mm case (GPS + Cellular)"
case (4, 4):
return "Apple Watch Series 4, 44mm case (GPS + Cellular)"
case (5, 1):
return "Apple Watch Series 5, 40mm case (GPS)"
case (5, 2):
return "Apple Watch Series 5, 44mm case (GPS)"
case (5, 3):
return "Apple Watch Series 5, 40mm case (GPS + Cellular)"
case (5, 4):
return "Apple Watch Series 5, 44mm case (GPS + Cellular)"
case (5, 9):
return "Apple Watch SE, 40mm case (GPS)"
case (5, 10):
return "Apple Watch SE, 44mm case (GPS)"
case (5, 11):
return "Apple Watch SE, 40mm case (GPS + Cellular)"
case (5, 12):
return "Apple Watch SE, 44mm case (GPS + Cellular)"
case (6, 1):
return "Apple Watch Series 6, 40mm case (GPS)"
case (6, 2):
return "Apple Watch Series 6, 44mm case (GPS)"
case (6, 3):
return "Apple Watch Series 6, 40mm case (GPS + Cellular)"
case (6, 4):
return "Apple Watch Series 6, 44mm case (GPS + Cellular)"
case (6, 6):
return "Apple Watch Series 7, 41mm case (GPS)"
case (6, 7):
return "Apple Watch Series 7, 45mm case (GPS)"
case (6, 8):
return "Apple Watch Series 7, 41mm case (GPS + Cellular)"
case (6, 9):
return "Apple Watch Series 7, 45mm case (GPS + Cellular)"
case (6, 10):
return "Apple Watch SE (2nd Generation), 40mm case (GPS)"
case (6, 11):
return "Apple Watch SE (2nd Generation), 44mm case (GPS)"
case (6, 12):
return "Apple Watch SE (2nd Generation), 40mm case (GPS + Cellular)"
case (6, 13):
return "Apple Watch SE (2nd Generation), 44mm case (GPS + Cellular)"
case (6, 14):
return "Apple Watch Series 8, 41mm case (GPS)"
case (6, 15):
return "Apple Watch Series 8, 45mm case (GPS)"
case (6, 16):
return "Apple Watch Series 8, 41mm case (GPS + Cellular)"
case (6, 17):
return "Apple Watch Series 8, 45mm case (GPS + Cellular)"
case (6, 18):
return "Apple Watch Ultra"
case (7, 1):
return "Apple Watch Series 9, 41mm case (GPS)"
case (7, 2):
return "Apple Watch Series 9, 45mm case (GPS)"
case (7, 3):
return "Apple Watch Series 9, 41mm case (GPS + Cellular)"
case (7, 4):
return "Apple Watch Series 9, 45mm case (GPS + Cellular)"
case (7, 5):
return "Apple Watch Ultra 2"
default:
return "unknown"
}
}
}
42 changes: 41 additions & 1 deletion Sources/Screen.swift
Expand Up @@ -21,9 +21,12 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#if os(iOS)
import UIKit
#endif

public struct Screen {
#if os(iOS)
init(width: Double, height: Double, scale: Double) {
self.width = width
self.height = height
Expand All @@ -37,9 +40,16 @@ public struct Screen {
public var adjustedScale: Double {
return 1.0 / scale
}
#elseif os(watchOS)
init(identifier: Identifier) {
self.identifier = identifier
}

let identifier: Identifier
#endif
}


#if os(iOS)
// MARK: - Detecting Screen size in Inches

extension Screen {
Expand Down Expand Up @@ -89,3 +99,33 @@ extension Screen {
}

}
#endif

#if os(watchOS)
extension Screen {
public var caseSize: Int? {
guard let major = identifier.version.major,
let minor = identifier.version.minor
else { return nil }

switch (major, minor) {
case (1, 1), (2, 3), (2, 6), (3, 1), (3, 3): return 38
case (1, 2), (2, 4), (2, 7), (3, 2), (3, 4): return 42

case (4, 1), (4, 3), (5, 1), (5, 3), (5, 9),
(5, 11), (6, 1), (6, 3), (6, 10), (6, 12): return 40
case (4, 2), (4, 4), (5, 2), (5, 4), (5, 10),
(5, 12), (6, 2), (6, 4), (6, 11), (6, 13): return 44

case (6, 6), (6, 8), (6, 14), (6, 16),
(7, 1), (7, 3): return 41
case (6, 7), (6, 9), (6, 15), (6, 17),
(7, 2), (7, 4): return 45

case (6, 18), (7, 5): return 49

default: return nil
}
}
}
#endif
8 changes: 8 additions & 0 deletions Sources/UIDeviceComplete.swift
Expand Up @@ -21,7 +21,11 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#if os(iOS)
import UIKit
#elseif os(watchOS)
import WatchKit
#endif

public final class UIDeviceComplete<Base> {
let base: Base
Expand All @@ -42,4 +46,8 @@ public extension UIDeviceCompleteCompatible {
}
}

#if os(iOS)
extension UIDevice: UIDeviceCompleteCompatible { }
#elseif os(watchOS)
extension WKInterfaceDevice: UIDeviceCompleteCompatible { }
#endif

0 comments on commit 7f2d9f5

Please sign in to comment.