diff --git a/.gitignore b/.gitignore index fb5a68d..19dd02a 100644 --- a/.gitignore +++ b/.gitignore @@ -54,4 +54,3 @@ Example/Pods/ # Add this line if you want to avoid checking in source code from Carthage dependencies. Carthage/Checkouts -Carthage/Build \ No newline at end of file diff --git a/.jazzy.yaml b/.jazzy.yaml deleted file mode 100644 index 882834f..0000000 --- a/.jazzy.yaml +++ /dev/null @@ -1,10 +0,0 @@ -author: Christoph Wendt -author_url: https://github.com/chrs1885 -github_url: https://github.com/chrs1885/Capable -module: Capable -readme: README.md -output: Documentation -theme: apple -clean: true -sdk: iphone -xcodebuild_arguments: [-scheme, Capable, -project, ./Capable.xcodeproj] \ No newline at end of file diff --git a/.swift-version b/.swift-version index 6e63660..819e07a 100644 --- a/.swift-version +++ b/.swift-version @@ -1 +1 @@ -5.0 \ No newline at end of file +5.0 diff --git a/.swiftformat b/.swiftformat new file mode 100644 index 0000000..33b27c3 --- /dev/null +++ b/.swiftformat @@ -0,0 +1 @@ +--exclude .build, Example/Pods \ No newline at end of file diff --git a/.swiftlint.yml b/.swiftlint.yml index 0ab3351..bfc58aa 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -5,17 +5,15 @@ disabled_rules: # rule identifiers to exclude from running - line_length - nesting - type_body_length - - variable_name + - identifier_name opt_in_rules: # some rules are only opt-in - colon - comma - control_statement - empty_count - trailing_newline -included: # paths to include during linting. `--path` is ignored if present. - - Source - - Tests -excluded: # paths to ignore during linting. Takes precedence over `included`. - -cyclomatic_complexity: - ignores_case_statements: true +included: + - Source/ +excluded: + - .build/* + - Example/Pods/ \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index c383d9a..408e4db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## Version 1.1.1 + +### Enhancements +* Add SPM support for iOS, macOS, tvOS, and watchOS +* Update project structure to match the CocoaPods lib template +* Improve development tooling by adding SwiftFormat, SwiftLint, and SourceDocs (replacement for Jazzy) + ## Version 1.1.0 ### Features diff --git a/Capable.podspec b/Capable.podspec index 7c825bc..d0850b6 100644 --- a/Capable.podspec +++ b/Capable.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'Capable' - s.version = '1.1.0' + s.version = '1.1.1' s.summary = 'Keep track of accessibility settings, leverage high contrast colors, and use scalable fonts to enable users with disabilities to use your app.' s.description = <<-DESC diff --git a/Capable.xcodeproj/project.pbxproj b/Capable.xcodeproj/project.pbxproj deleted file mode 100644 index ea8f259..0000000 --- a/Capable.xcodeproj/project.pbxproj +++ /dev/null @@ -1,1021 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 48; - objects = { - -/* Begin PBXBuildFile section */ - 4404835E2168F1940051FCE7 /* FeatureStatusesProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4404835D2168F1940051FCE7 /* FeatureStatusesProviderTests.swift */; }; - 44478267233279EF00FB1B3B /* Image+averageColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44478266233279EF00FB1B3B /* Image+averageColor.swift */; }; - 4447826B2332808400FB1B3B /* ImageArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4447826A2332808400FB1B3B /* ImageArea.swift */; }; - 44580D11212605D500F9940A /* HandicapStatuses.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44580D10212605D500F9940A /* HandicapStatuses.swift */; }; - 44580D13212606BB00F9940A /* FeatureStatuses.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44580D12212606BB00F9940A /* FeatureStatuses.swift */; }; - 44580D1721260EAA00F9940A /* FeatureStatusesProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44580D1621260EAA00F9940A /* FeatureStatusesProviderMock.swift */; }; - 44580D1921261D4E00F9940A /* CapablePerfTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44580D1821261D4E00F9940A /* CapablePerfTests.swift */; }; - 448433B323409ABA00FC7DBC /* ImageAreaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 448433B223409ABA00FC7DBC /* ImageAreaTests.swift */; }; - 448433BE2340AE6800FC7DBC /* Image+mock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 448433BD2340AE6800FC7DBC /* Image+mock.swift */; }; - 448433C02340B06D00FC7DBC /* ImageAverageColorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 448433BF2340B06D00FC7DBC /* ImageAverageColorTests.swift */; }; - 448697682127133A00A06BFF /* HandicapNotifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 448697672127133A00A06BFF /* HandicapNotifications.swift */; }; - 4486976A2127148700A06BFF /* FeatureNotifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 448697692127148700A06BFF /* FeatureNotifications.swift */; }; - 44A5FBE321B03BB4008DE1EB /* FontProps.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44A5FBE221B03BB4008DE1EB /* FontProps.swift */; }; - 44D0B937233F86DC00A9B136 /* CIImage+initWithImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44D0B936233F86DC00A9B136 /* CIImage+initWithImage.swift */; }; - 44E1055A2125CC7B00D85BBC /* HandicapStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44E105592125CC7B00D85BBC /* HandicapStatus.swift */; }; - 44FE2E32211479A300029869 /* FontMetricsProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44FE2E31211479A300029869 /* FontMetricsProvider.swift */; }; - 44FE2E34211479F700029869 /* FontMetricsProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44FE2E33211479F700029869 /* FontMetricsProviderProtocol.swift */; }; - 44FE2E3621147A6F00029869 /* FontMetricsSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44FE2E3521147A6F00029869 /* FontMetricsSupport.swift */; }; - 44FE2E3B211482DD00029869 /* FontMetricsProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44FE2E3A211482DD00029869 /* FontMetricsProviderTests.swift */; }; - 44FE2E3D211482F500029869 /* FontMetricsSupportTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44FE2E3C211482F500029869 /* FontMetricsSupportTests.swift */; }; - 44FE2E3F2114830B00029869 /* FontMetricsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44FE2E3E2114830B00029869 /* FontMetricsTests.swift */; }; - 44FE2E422114832300029869 /* FontMetricsMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44FE2E412114832300029869 /* FontMetricsMock.swift */; }; - 44FE2E442114833700029869 /* FontMetricsProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44FE2E432114833700029869 /* FontMetricsProviderMock.swift */; }; - 44FE2E452114849100029869 /* OsVersionProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83CAA3FB2097C216003F231D /* OsVersionProviderMock.swift */; }; - 83097DA521A9736100703F29 /* ConformanceLevelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83097DA421A9736100703F29 /* ConformanceLevelTests.swift */; }; - 83097DA721A97CAA00703F29 /* RGBAColorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83097DA621A97CAA00703F29 /* RGBAColorTests.swift */; }; - 8311E58721EE841800B416B4 /* FontPropsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8311E58621EE841800B416B4 /* FontPropsTests.swift */; }; - 83160D9521A548EF00FD122C /* ConformanceLevel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83160D9421A548EF00FD122C /* ConformanceLevel.swift */; }; - 831AA4DE212F437800AEAC44 /* NotificationCenterMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 831AA4DD212F437800AEAC44 /* NotificationCenterMock.swift */; }; - 831AA4E0212F46CC00AEAC44 /* NotificationCenterProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 831AA4DF212F46CC00AEAC44 /* NotificationCenterProtocol.swift */; }; - 831B4EF720A4A25A00F1BB94 /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83F0479D20A49F7400C4CA60 /* Quick.framework */; }; - 831B4EF820A4A25A00F1BB94 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83F0479920A49F6900C4CA60 /* Nimble.framework */; }; - 831B4EF920A4A25A00F1BB94 /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83A8EE5B206FB8660043EB34 /* Quick.framework */; }; - 831B4EFA20A4A25A00F1BB94 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83A8EE59206FB8410043EB34 /* Nimble.framework */; }; - 831E8EEE21247C620096930C /* Handicap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 831E8EED21247C620096930C /* Handicap.swift */; }; - 831E8EF021247EAD0096930C /* HandicapEnabledMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 831E8EEF21247EAD0096930C /* HandicapEnabledMode.swift */; }; - 831FE59121F52DDD0078F260 /* UIColor+rgbaColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 831FE59021F52DDD0078F260 /* UIColor+rgbaColor.swift */; }; - 831FE59321F52E330078F260 /* NSColor+rgbaColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 831FE59221F52E330078F260 /* NSColor+rgbaColor.swift */; }; - 8323D8E62167B8C80015F8A3 /* FeatureStatusesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8323D8E52167B8C80015F8A3 /* FeatureStatusesTests.swift */; }; - 8323D8E82167C2550015F8A3 /* HandicapStatusesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8323D8E72167C2550015F8A3 /* HandicapStatusesTests.swift */; }; - 8323D8EA2167D0670015F8A3 /* HandicapStatusesMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8323D8E92167D0670015F8A3 /* HandicapStatusesMock.swift */; }; - 8323D8EC2167D1980015F8A3 /* FeatureStatusesMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8323D8EB2167D1980015F8A3 /* FeatureStatusesMock.swift */; }; - 832953CE2110D9E200072EB9 /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 832953CC2110D9E100072EB9 /* Quick.framework */; }; - 832953CF2110D9E200072EB9 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 832953CD2110D9E200072EB9 /* Nimble.framework */; }; - 833CE9AA2194CCF400D741DE /* OSLogType+greaterEqual.swift in Sources */ = {isa = PBXBuildFile; fileRef = 833CE9A92194CCF400D741DE /* OSLogType+greaterEqual.swift */; }; - 833CE9AD2196296500D741DE /* LoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 833CE9AB2196261200D741DE /* LoggerTests.swift */; }; - 833D435421CFE42B00444EC9 /* NSFont+fontProps.swift in Sources */ = {isa = PBXBuildFile; fileRef = 833D435321CFE42B00444EC9 /* NSFont+fontProps.swift */; }; - 833D435621CFE44000444EC9 /* UIFont+fontProps.swift in Sources */ = {isa = PBXBuildFile; fileRef = 833D435521CFE44000444EC9 /* UIFont+fontProps.swift */; }; - 833D435821CFE7D300444EC9 /* NSFontFontPropsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 833D435721CFE7D300444EC9 /* NSFontFontPropsTests.swift */; }; - 833DB9BF206C164B00C8DA02 /* Notification+Name.swift in Sources */ = {isa = PBXBuildFile; fileRef = 833DB9BE206C164B00C8DA02 /* Notification+Name.swift */; }; - 833DB9C2206C188B00C8DA02 /* FeatureStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 833DB9C1206C188B00C8DA02 /* FeatureStatus.swift */; }; - 834C7232213072B300DCEBDC /* FeatureNotificationsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 834C7231213072B300DCEBDC /* FeatureNotificationsTests.swift */; }; - 834C72342131F55100DCEBDC /* HandicapNotificationsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 834C72332131F55100DCEBDC /* HandicapNotificationsTests.swift */; }; - 83529F3F21ED2BF6007637C7 /* ColorWcagTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83529F3E21ED2BF6007637C7 /* ColorWcagTests.swift */; }; - 83648E972187BD000095D208 /* HandicapTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83648E962187BD000095D208 /* HandicapTests.swift */; }; - 83648E9E218A36560095D208 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83648E9D218A36560095D208 /* Logger.swift */; }; - 8382A322206E350F00E264A3 /* FeatureStatusesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8382A321206E350F00E264A3 /* FeatureStatusesProvider.swift */; }; - 8382A324206EB40500E264A3 /* NotificationsProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8382A323206EB40500E264A3 /* NotificationsProtocol.swift */; }; - 8382A326206EB46E00E264A3 /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8382A325206EB46E00E264A3 /* Notifications.swift */; }; - 83973ADA206FD22C0057CD4F /* UIFont+ScaledFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83973AD9206FD22C0057CD4F /* UIFont+ScaledFont.swift */; }; - 83973ADD206FD3A40057CD4F /* FontMetricsProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83973ADC206FD3A40057CD4F /* FontMetricsProtocol.swift */; }; - 83973ADF206FD4080057CD4F /* FontMetrics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83973ADE206FD4080057CD4F /* FontMetrics.swift */; }; - 83B21D6D21DE687200E02470 /* UIFontFontPropsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83B21D6C21DE687200E02470 /* UIFontFontPropsTests.swift */; }; - 83B5FFE42065336F00E8E83F /* Capable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83B5FFE32065336F00E8E83F /* Capable.swift */; }; - 83B5FFE62065352500E8E83F /* CapableFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83B5FFE52065352500E8E83F /* CapableFeature.swift */; }; - 83B5FFEB206542FC00E8E83F /* FeatureStatusesProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83B5FFEA206542FC00E8E83F /* FeatureStatusesProviderProtocol.swift */; }; - 83C6A351219E08DB00BB039D /* String+isDefaultContentSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83C6A350219E08DB00BB039D /* String+isDefaultContentSize.swift */; }; - 83C6A353219E0FF200BB039D /* HearingDeviceEar+stringValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83C6A352219E0FF200BB039D /* HearingDeviceEar+stringValue.swift */; }; - 83CAA3F82097BEEC003F231D /* OsVersionProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83CAA3F72097BEEC003F231D /* OsVersionProvider.swift */; }; - 83CAA3FA2097BF9B003F231D /* OsVersionProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83CAA3F92097BF9B003F231D /* OsVersionProviderProtocol.swift */; }; - 83D2A46920F006000032054C /* CGFloat+contentSizeString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83D2A46820F006000032054C /* CGFloat+contentSizeString.swift */; }; - 83DA75F72065167600303D8F /* CapableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83DA75F62065167600303D8F /* CapableTests.swift */; }; - 83DA75F92065167600303D8F /* Capable.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DA75EB2065167600303D8F /* Capable.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 83DAF4B621A4A7320076F542 /* Color+wcag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83DAF4B521A4A7320076F542 /* Color+wcag.swift */; }; - 83DAF4B821A4A9670076F542 /* RGBAColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83DAF4B721A4A9670076F542 /* RGBAColor.swift */; }; - 83DB72462069891200384B3F /* UIContentSizeCategory+values.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83DB72452069891200384B3F /* UIContentSizeCategory+values.swift */; }; - 83DB724820698EB400384B3F /* Bool+statusString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83DB724720698EB400384B3F /* Bool+statusString.swift */; }; - 83DC7B5C2149ACFD00AF12A7 /* HandicapStatusesProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83DC7B5B2149ACFD00AF12A7 /* HandicapStatusesProtocol.swift */; }; - 83DC7B5E2149AD4B00AF12A7 /* FeatureStatusesProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83DC7B5D2149AD4B00AF12A7 /* FeatureStatusesProtocol.swift */; }; - 83DC7B602149BB4800AF12A7 /* NotificationsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83DC7B5F2149BB4800AF12A7 /* NotificationsTests.swift */; }; - 83DC7B622149C03E00AF12A7 /* StatusesProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83DC7B612149C03E00AF12A7 /* StatusesProtocol.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 83DA75F32065167600303D8F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 83DA75DF2065167600303D8F /* Project object */; - proxyType = 1; - remoteGlobalIDString = 83DA75E72065167600303D8F; - remoteInfo = "Low Vision"; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 4404835D2168F1940051FCE7 /* FeatureStatusesProviderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureStatusesProviderTests.swift; sourceTree = ""; }; - 44478266233279EF00FB1B3B /* Image+averageColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Image+averageColor.swift"; sourceTree = ""; }; - 4447826A2332808400FB1B3B /* ImageArea.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageArea.swift; sourceTree = ""; }; - 44580D10212605D500F9940A /* HandicapStatuses.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HandicapStatuses.swift; sourceTree = ""; }; - 44580D12212606BB00F9940A /* FeatureStatuses.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureStatuses.swift; sourceTree = ""; }; - 44580D1621260EAA00F9940A /* FeatureStatusesProviderMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureStatusesProviderMock.swift; sourceTree = ""; }; - 44580D1821261D4E00F9940A /* CapablePerfTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CapablePerfTests.swift; sourceTree = ""; }; - 448433B223409ABA00FC7DBC /* ImageAreaTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageAreaTests.swift; sourceTree = ""; }; - 448433BD2340AE6800FC7DBC /* Image+mock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Image+mock.swift"; sourceTree = ""; }; - 448433BF2340B06D00FC7DBC /* ImageAverageColorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageAverageColorTests.swift; sourceTree = ""; }; - 448697672127133A00A06BFF /* HandicapNotifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HandicapNotifications.swift; sourceTree = ""; }; - 448697692127148700A06BFF /* FeatureNotifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureNotifications.swift; sourceTree = ""; }; - 44A5FBE221B03BB4008DE1EB /* FontProps.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontProps.swift; sourceTree = ""; }; - 44D0B936233F86DC00A9B136 /* CIImage+initWithImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CIImage+initWithImage.swift"; sourceTree = ""; }; - 44E105592125CC7B00D85BBC /* HandicapStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HandicapStatus.swift; sourceTree = ""; }; - 44FE2E31211479A300029869 /* FontMetricsProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontMetricsProvider.swift; sourceTree = ""; }; - 44FE2E33211479F700029869 /* FontMetricsProviderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontMetricsProviderProtocol.swift; sourceTree = ""; }; - 44FE2E3521147A6F00029869 /* FontMetricsSupport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontMetricsSupport.swift; sourceTree = ""; }; - 44FE2E3A211482DD00029869 /* FontMetricsProviderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontMetricsProviderTests.swift; sourceTree = ""; }; - 44FE2E3C211482F500029869 /* FontMetricsSupportTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontMetricsSupportTests.swift; sourceTree = ""; }; - 44FE2E3E2114830B00029869 /* FontMetricsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontMetricsTests.swift; sourceTree = ""; }; - 44FE2E412114832300029869 /* FontMetricsMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontMetricsMock.swift; sourceTree = ""; }; - 44FE2E432114833700029869 /* FontMetricsProviderMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontMetricsProviderMock.swift; sourceTree = ""; }; - 83097DA421A9736100703F29 /* ConformanceLevelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConformanceLevelTests.swift; sourceTree = ""; }; - 83097DA621A97CAA00703F29 /* RGBAColorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RGBAColorTests.swift; sourceTree = ""; }; - 8311E58621EE841800B416B4 /* FontPropsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontPropsTests.swift; sourceTree = ""; }; - 83160D9421A548EF00FD122C /* ConformanceLevel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConformanceLevel.swift; sourceTree = ""; }; - 831AA4DD212F437800AEAC44 /* NotificationCenterMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationCenterMock.swift; sourceTree = ""; }; - 831AA4DF212F46CC00AEAC44 /* NotificationCenterProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationCenterProtocol.swift; sourceTree = ""; }; - 831E8EED21247C620096930C /* Handicap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Handicap.swift; sourceTree = ""; }; - 831E8EEF21247EAD0096930C /* HandicapEnabledMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HandicapEnabledMode.swift; sourceTree = ""; }; - 831FE59021F52DDD0078F260 /* UIColor+rgbaColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+rgbaColor.swift"; sourceTree = ""; }; - 831FE59221F52E330078F260 /* NSColor+rgbaColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSColor+rgbaColor.swift"; sourceTree = ""; }; - 8323D8E52167B8C80015F8A3 /* FeatureStatusesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureStatusesTests.swift; sourceTree = ""; }; - 8323D8E72167C2550015F8A3 /* HandicapStatusesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HandicapStatusesTests.swift; sourceTree = ""; }; - 8323D8E92167D0670015F8A3 /* HandicapStatusesMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HandicapStatusesMock.swift; sourceTree = ""; }; - 8323D8EB2167D1980015F8A3 /* FeatureStatusesMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureStatusesMock.swift; sourceTree = ""; }; - 832953CC2110D9E100072EB9 /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quick.framework; path = Carthage/Build/Mac/Quick.framework; sourceTree = ""; }; - 832953CD2110D9E200072EB9 /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Nimble.framework; path = Carthage/Build/Mac/Nimble.framework; sourceTree = ""; }; - 833CE9A92194CCF400D741DE /* OSLogType+greaterEqual.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OSLogType+greaterEqual.swift"; sourceTree = ""; }; - 833CE9AB2196261200D741DE /* LoggerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggerTests.swift; sourceTree = ""; }; - 833D435321CFE42B00444EC9 /* NSFont+fontProps.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSFont+fontProps.swift"; sourceTree = ""; }; - 833D435521CFE44000444EC9 /* UIFont+fontProps.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIFont+fontProps.swift"; sourceTree = ""; }; - 833D435721CFE7D300444EC9 /* NSFontFontPropsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSFontFontPropsTests.swift; sourceTree = ""; }; - 833DB9BE206C164B00C8DA02 /* Notification+Name.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Notification+Name.swift"; sourceTree = ""; }; - 833DB9C1206C188B00C8DA02 /* FeatureStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureStatus.swift; sourceTree = ""; }; - 834C7231213072B300DCEBDC /* FeatureNotificationsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureNotificationsTests.swift; sourceTree = ""; }; - 834C72332131F55100DCEBDC /* HandicapNotificationsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HandicapNotificationsTests.swift; sourceTree = ""; }; - 83529F3E21ED2BF6007637C7 /* ColorWcagTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorWcagTests.swift; sourceTree = ""; }; - 83648E962187BD000095D208 /* HandicapTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HandicapTests.swift; sourceTree = ""; }; - 83648E9D218A36560095D208 /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = ""; }; - 8382A321206E350F00E264A3 /* FeatureStatusesProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureStatusesProvider.swift; sourceTree = ""; }; - 8382A323206EB40500E264A3 /* NotificationsProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsProtocol.swift; sourceTree = ""; }; - 8382A325206EB46E00E264A3 /* Notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = ""; }; - 83973AD9206FD22C0057CD4F /* UIFont+ScaledFont.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIFont+ScaledFont.swift"; sourceTree = ""; }; - 83973ADC206FD3A40057CD4F /* FontMetricsProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontMetricsProtocol.swift; sourceTree = ""; }; - 83973ADE206FD4080057CD4F /* FontMetrics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontMetrics.swift; sourceTree = ""; }; - 83A8EE59206FB8410043EB34 /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Nimble.framework; path = Carthage/Build/iOS/Nimble.framework; sourceTree = ""; }; - 83A8EE5B206FB8660043EB34 /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quick.framework; path = Carthage/Build/iOS/Quick.framework; sourceTree = ""; }; - 83B21D6C21DE687200E02470 /* UIFontFontPropsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFontFontPropsTests.swift; sourceTree = ""; }; - 83B5FFE32065336F00E8E83F /* Capable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Capable.swift; sourceTree = ""; }; - 83B5FFE52065352500E8E83F /* CapableFeature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CapableFeature.swift; sourceTree = ""; }; - 83B5FFEA206542FC00E8E83F /* FeatureStatusesProviderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureStatusesProviderProtocol.swift; sourceTree = ""; }; - 83C6A350219E08DB00BB039D /* String+isDefaultContentSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+isDefaultContentSize.swift"; sourceTree = ""; }; - 83C6A352219E0FF200BB039D /* HearingDeviceEar+stringValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HearingDeviceEar+stringValue.swift"; sourceTree = ""; }; - 83CAA3F72097BEEC003F231D /* OsVersionProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OsVersionProvider.swift; sourceTree = ""; }; - 83CAA3F92097BF9B003F231D /* OsVersionProviderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OsVersionProviderProtocol.swift; sourceTree = ""; }; - 83CAA3FB2097C216003F231D /* OsVersionProviderMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = OsVersionProviderMock.swift; path = Tests/Fonts/Mocks/OsVersionProviderMock.swift; sourceTree = SOURCE_ROOT; }; - 83CAA40120990AB5003F231D /* WatchKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WatchKit.framework; path = System/Library/Frameworks/WatchKit.framework; sourceTree = SDKROOT; }; - 83D2A46820F006000032054C /* CGFloat+contentSizeString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGFloat+contentSizeString.swift"; sourceTree = ""; }; - 83DA75E82065167600303D8F /* Capable.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Capable.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 83DA75EB2065167600303D8F /* Capable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Capable.h; sourceTree = ""; }; - 83DA75EC2065167600303D8F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 83DA75F12065167600303D8F /* CapableTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CapableTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 83DA75F62065167600303D8F /* CapableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CapableTests.swift; sourceTree = ""; }; - 83DA75F82065167600303D8F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 83DAF4B521A4A7320076F542 /* Color+wcag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+wcag.swift"; sourceTree = ""; }; - 83DAF4B721A4A9670076F542 /* RGBAColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RGBAColor.swift; sourceTree = ""; }; - 83DB72452069891200384B3F /* UIContentSizeCategory+values.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIContentSizeCategory+values.swift"; sourceTree = ""; }; - 83DB724720698EB400384B3F /* Bool+statusString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bool+statusString.swift"; sourceTree = ""; }; - 83DC7B5B2149ACFD00AF12A7 /* HandicapStatusesProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HandicapStatusesProtocol.swift; sourceTree = ""; }; - 83DC7B5D2149AD4B00AF12A7 /* FeatureStatusesProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureStatusesProtocol.swift; sourceTree = ""; }; - 83DC7B5F2149BB4800AF12A7 /* NotificationsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsTests.swift; sourceTree = ""; }; - 83DC7B612149C03E00AF12A7 /* StatusesProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusesProtocol.swift; sourceTree = ""; }; - 83F0479920A49F6900C4CA60 /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Nimble.framework; path = Carthage/Build/tvOS/Nimble.framework; sourceTree = ""; }; - 83F0479D20A49F7400C4CA60 /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quick.framework; path = Carthage/Build/tvOS/Quick.framework; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 83DA75E42065167600303D8F /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 83DA75EE2065167600303D8F /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 832953CE2110D9E200072EB9 /* Quick.framework in Frameworks */, - 832953CF2110D9E200072EB9 /* Nimble.framework in Frameworks */, - 831B4EF720A4A25A00F1BB94 /* Quick.framework in Frameworks */, - 831B4EF820A4A25A00F1BB94 /* Nimble.framework in Frameworks */, - 831B4EF920A4A25A00F1BB94 /* Quick.framework in Frameworks */, - 831B4EFA20A4A25A00F1BB94 /* Nimble.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 448433BC2340AE4F00FC7DBC /* Mocks */ = { - isa = PBXGroup; - children = ( - 448433BD2340AE6800FC7DBC /* Image+mock.swift */, - ); - path = Mocks; - sourceTree = ""; - }; - 44AD88B9220482AF00266F4A /* Common */ = { - isa = PBXGroup; - children = ( - 44AD88BB220487CD00266F4A /* Logger */, - ); - path = Common; - sourceTree = ""; - }; - 44AD88BA220482D400266F4A /* Common */ = { - isa = PBXGroup; - children = ( - 833CE9AB2196261200D741DE /* LoggerTests.swift */, - ); - path = Common; - sourceTree = ""; - }; - 44AD88BB220487CD00266F4A /* Logger */ = { - isa = PBXGroup; - children = ( - 83648E9D218A36560095D208 /* Logger.swift */, - 833CE9A92194CCF400D741DE /* OSLogType+greaterEqual.swift */, - ); - path = Logger; - sourceTree = ""; - }; - 44FE2E3721147F7A00029869 /* Protocols */ = { - isa = PBXGroup; - children = ( - 83973ADC206FD3A40057CD4F /* FontMetricsProtocol.swift */, - 44FE2E33211479F700029869 /* FontMetricsProviderProtocol.swift */, - 83CAA3F92097BF9B003F231D /* OsVersionProviderProtocol.swift */, - ); - path = Protocols; - sourceTree = ""; - }; - 44FE2E382114804600029869 /* Features */ = { - isa = PBXGroup; - children = ( - 83BB09D02087CE29000420C5 /* Mocks */, - 44580D1821261D4E00F9940A /* CapablePerfTests.swift */, - 83DA75F62065167600303D8F /* CapableTests.swift */, - 834C7231213072B300DCEBDC /* FeatureNotificationsTests.swift */, - 4404835D2168F1940051FCE7 /* FeatureStatusesProviderTests.swift */, - 8323D8E52167B8C80015F8A3 /* FeatureStatusesTests.swift */, - 834C72332131F55100DCEBDC /* HandicapNotificationsTests.swift */, - 8323D8E72167C2550015F8A3 /* HandicapStatusesTests.swift */, - 83648E962187BD000095D208 /* HandicapTests.swift */, - 83DC7B5F2149BB4800AF12A7 /* NotificationsTests.swift */, - ); - path = Features; - sourceTree = ""; - }; - 44FE2E392114807F00029869 /* Fonts */ = { - isa = PBXGroup; - children = ( - 44FE2E402114831300029869 /* Mocks */, - 44FE2E3A211482DD00029869 /* FontMetricsProviderTests.swift */, - 44FE2E3C211482F500029869 /* FontMetricsSupportTests.swift */, - 44FE2E3E2114830B00029869 /* FontMetricsTests.swift */, - ); - path = Fonts; - sourceTree = ""; - }; - 44FE2E402114831300029869 /* Mocks */ = { - isa = PBXGroup; - children = ( - 44FE2E412114832300029869 /* FontMetricsMock.swift */, - 44FE2E432114833700029869 /* FontMetricsProviderMock.swift */, - 83CAA3FB2097C216003F231D /* OsVersionProviderMock.swift */, - ); - path = Mocks; - sourceTree = ""; - }; - 83097DA321A9732500703F29 /* Colors */ = { - isa = PBXGroup; - children = ( - 448433BC2340AE4F00FC7DBC /* Mocks */, - 83097DA421A9736100703F29 /* ConformanceLevelTests.swift */, - 8311E58621EE841800B416B4 /* FontPropsTests.swift */, - 83529F3E21ED2BF6007637C7 /* ColorWcagTests.swift */, - 448433B223409ABA00FC7DBC /* ImageAreaTests.swift */, - 448433BF2340B06D00FC7DBC /* ImageAverageColorTests.swift */, - 833D435721CFE7D300444EC9 /* NSFontFontPropsTests.swift */, - 83097DA621A97CAA00703F29 /* RGBAColorTests.swift */, - 83B21D6C21DE687200E02470 /* UIFontFontPropsTests.swift */, - ); - path = Colors; - sourceTree = ""; - }; - 83160D9221A5485300FD122C /* Models */ = { - isa = PBXGroup; - children = ( - 83160D9421A548EF00FD122C /* ConformanceLevel.swift */, - 44A5FBE221B03BB4008DE1EB /* FontProps.swift */, - 4447826A2332808400FB1B3B /* ImageArea.swift */, - 83DAF4B721A4A9670076F542 /* RGBAColor.swift */, - ); - path = Models; - sourceTree = ""; - }; - 83160D9321A5487800FD122C /* Extensions */ = { - isa = PBXGroup; - children = ( - 83DAF4B521A4A7320076F542 /* Color+wcag.swift */, - 44478266233279EF00FB1B3B /* Image+averageColor.swift */, - 831FE59221F52E330078F260 /* NSColor+rgbaColor.swift */, - 833D435321CFE42B00444EC9 /* NSFont+fontProps.swift */, - 44D0B936233F86DC00A9B136 /* CIImage+initWithImage.swift */, - 831FE59021F52DDD0078F260 /* UIColor+rgbaColor.swift */, - 833D435521CFE44000444EC9 /* UIFont+fontProps.swift */, - ); - path = Extensions; - sourceTree = ""; - }; - 833DB9C0206C187C00C8DA02 /* Models */ = { - isa = PBXGroup; - children = ( - 83B5FFE52065352500E8E83F /* CapableFeature.swift */, - 833DB9C1206C188B00C8DA02 /* FeatureStatus.swift */, - 831E8EED21247C620096930C /* Handicap.swift */, - 831E8EEF21247EAD0096930C /* HandicapEnabledMode.swift */, - 44E105592125CC7B00D85BBC /* HandicapStatus.swift */, - ); - path = Models; - sourceTree = ""; - }; - 8382A327206EC73400E264A3 /* Notifications */ = { - isa = PBXGroup; - children = ( - 448697692127148700A06BFF /* FeatureNotifications.swift */, - 448697672127133A00A06BFF /* HandicapNotifications.swift */, - 831AA4DF212F46CC00AEAC44 /* NotificationCenterProtocol.swift */, - 8382A325206EB46E00E264A3 /* Notifications.swift */, - 8382A323206EB40500E264A3 /* NotificationsProtocol.swift */, - ); - path = Notifications; - sourceTree = ""; - }; - 83973AD6206FD1B80057CD4F /* Features */ = { - isa = PBXGroup; - children = ( - 83B5FFE32065336F00E8E83F /* Capable.swift */, - 83DB7243206988DC00384B3F /* Extensions */, - 833DB9C0206C187C00C8DA02 /* Models */, - 8382A327206EC73400E264A3 /* Notifications */, - 83B5FFE720653AC000E8E83F /* Statuses */, - ); - path = Features; - sourceTree = ""; - }; - 83973AD7206FD1E00057CD4F /* Fonts */ = { - isa = PBXGroup; - children = ( - 83973AD8206FD1F30057CD4F /* Extensions */, - 83973ADB206FD2EA0057CD4F /* FontMetrics */, - ); - path = Fonts; - sourceTree = ""; - }; - 83973AD8206FD1F30057CD4F /* Extensions */ = { - isa = PBXGroup; - children = ( - 83973AD9206FD22C0057CD4F /* UIFont+ScaledFont.swift */, - ); - path = Extensions; - sourceTree = ""; - }; - 83973ADB206FD2EA0057CD4F /* FontMetrics */ = { - isa = PBXGroup; - children = ( - 44FE2E3721147F7A00029869 /* Protocols */, - 83973ADE206FD4080057CD4F /* FontMetrics.swift */, - 44FE2E31211479A300029869 /* FontMetricsProvider.swift */, - 44FE2E3521147A6F00029869 /* FontMetricsSupport.swift */, - 83CAA3F72097BEEC003F231D /* OsVersionProvider.swift */, - ); - path = FontMetrics; - sourceTree = ""; - }; - 83B5FFE720653AC000E8E83F /* Statuses */ = { - isa = PBXGroup; - children = ( - 44580D12212606BB00F9940A /* FeatureStatuses.swift */, - 83DC7B5D2149AD4B00AF12A7 /* FeatureStatusesProtocol.swift */, - 8382A321206E350F00E264A3 /* FeatureStatusesProvider.swift */, - 83B5FFEA206542FC00E8E83F /* FeatureStatusesProviderProtocol.swift */, - 44580D10212605D500F9940A /* HandicapStatuses.swift */, - 83DC7B5B2149ACFD00AF12A7 /* HandicapStatusesProtocol.swift */, - 83DC7B612149C03E00AF12A7 /* StatusesProtocol.swift */, - ); - path = Statuses; - sourceTree = ""; - }; - 83B5FFEC2065449B00E8E83F /* Frameworks */ = { - isa = PBXGroup; - children = ( - 832953CD2110D9E200072EB9 /* Nimble.framework */, - 83F0479D20A49F7400C4CA60 /* Quick.framework */, - 83F0479920A49F6900C4CA60 /* Nimble.framework */, - 832953CC2110D9E100072EB9 /* Quick.framework */, - 83CAA40120990AB5003F231D /* WatchKit.framework */, - 83A8EE5B206FB8660043EB34 /* Quick.framework */, - 83A8EE59206FB8410043EB34 /* Nimble.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 83BB09D02087CE29000420C5 /* Mocks */ = { - isa = PBXGroup; - children = ( - 8323D8EB2167D1980015F8A3 /* FeatureStatusesMock.swift */, - 44580D1621260EAA00F9940A /* FeatureStatusesProviderMock.swift */, - 8323D8E92167D0670015F8A3 /* HandicapStatusesMock.swift */, - 831AA4DD212F437800AEAC44 /* NotificationCenterMock.swift */, - ); - path = Mocks; - sourceTree = ""; - }; - 83DA75DE2065167600303D8F = { - isa = PBXGroup; - children = ( - 83DA75EA2065167600303D8F /* Source */, - 83DA75F52065167600303D8F /* Tests */, - 83DA75E92065167600303D8F /* Products */, - 83B5FFEC2065449B00E8E83F /* Frameworks */, - ); - sourceTree = ""; - }; - 83DA75E92065167600303D8F /* Products */ = { - isa = PBXGroup; - children = ( - 83DA75E82065167600303D8F /* Capable.framework */, - 83DA75F12065167600303D8F /* CapableTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 83DA75EA2065167600303D8F /* Source */ = { - isa = PBXGroup; - children = ( - 83DAF4B221A4A0F10076F542 /* Colors */, - 44AD88B9220482AF00266F4A /* Common */, - 83973AD6206FD1B80057CD4F /* Features */, - 83973AD7206FD1E00057CD4F /* Fonts */, - 83DA75EB2065167600303D8F /* Capable.h */, - 83DA75EC2065167600303D8F /* Info.plist */, - ); - path = Source; - sourceTree = ""; - }; - 83DA75F52065167600303D8F /* Tests */ = { - isa = PBXGroup; - children = ( - 83097DA321A9732500703F29 /* Colors */, - 44AD88BA220482D400266F4A /* Common */, - 44FE2E382114804600029869 /* Features */, - 44FE2E392114807F00029869 /* Fonts */, - 83DA75F82065167600303D8F /* Info.plist */, - ); - path = Tests; - sourceTree = ""; - }; - 83DAF4B221A4A0F10076F542 /* Colors */ = { - isa = PBXGroup; - children = ( - 83160D9321A5487800FD122C /* Extensions */, - 83160D9221A5485300FD122C /* Models */, - ); - path = Colors; - sourceTree = ""; - }; - 83DB7243206988DC00384B3F /* Extensions */ = { - isa = PBXGroup; - children = ( - 83DB724720698EB400384B3F /* Bool+statusString.swift */, - 83D2A46820F006000032054C /* CGFloat+contentSizeString.swift */, - 83C6A352219E0FF200BB039D /* HearingDeviceEar+stringValue.swift */, - 833DB9BE206C164B00C8DA02 /* Notification+Name.swift */, - 83C6A350219E08DB00BB039D /* String+isDefaultContentSize.swift */, - 83DB72452069891200384B3F /* UIContentSizeCategory+values.swift */, - ); - path = Extensions; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 83DA75E52065167600303D8F /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 83DA75F92065167600303D8F /* Capable.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 83DA75E72065167600303D8F /* Capable */ = { - isa = PBXNativeTarget; - buildConfigurationList = 83DA75FC2065167600303D8F /* Build configuration list for PBXNativeTarget "Capable" */; - buildPhases = ( - 83DA75E32065167600303D8F /* Sources */, - 83DA75E42065167600303D8F /* Frameworks */, - 83DA75E52065167600303D8F /* Headers */, - 83DA75E62065167600303D8F /* Resources */, - 83C7DA5620FD2EB200C32F52 /* Run SwiftLint */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Capable; - productName = "Low Vision"; - productReference = 83DA75E82065167600303D8F /* Capable.framework */; - productType = "com.apple.product-type.framework"; - }; - 83DA75F02065167600303D8F /* CapableTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 83DA75FF2065167600303D8F /* Build configuration list for PBXNativeTarget "CapableTests" */; - buildPhases = ( - 83DA75ED2065167600303D8F /* Sources */, - 83DA75EE2065167600303D8F /* Frameworks */, - 83F0479620A499F100C4CA60 /* Copy Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 83DA75F42065167600303D8F /* PBXTargetDependency */, - ); - name = CapableTests; - productName = "Low VisionTests"; - productReference = 83DA75F12065167600303D8F /* CapableTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 83DA75DF2065167600303D8F /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 0940; - TargetAttributes = { - 83DA75E72065167600303D8F = { - CreatedOnToolsVersion = 9.2; - LastSwiftMigration = 1000; - ProvisioningStyle = Automatic; - }; - 83DA75F02065167600303D8F = { - CreatedOnToolsVersion = 9.2; - LastSwiftMigration = 1000; - ProvisioningStyle = Automatic; - }; - }; - }; - buildConfigurationList = 83DA75E22065167600303D8F /* Build configuration list for PBXProject "Capable" */; - compatibilityVersion = "Xcode 8.0"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 83DA75DE2065167600303D8F; - productRefGroup = 83DA75E92065167600303D8F /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 83DA75E72065167600303D8F /* Capable */, - 83DA75F02065167600303D8F /* CapableTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 83DA75E62065167600303D8F /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 83C7DA5620FD2EB200C32F52 /* Run SwiftLint */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run SwiftLint"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; - }; - 83F0479620A499F100C4CA60 /* Copy Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Copy Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "for path in $FRAMEWORK_SEARCH_PATHS\ndo\nif [[ $path == *\"Carthage\"* ]];\nthen\n export SCRIPT_INPUT_FILE_COUNT=2\n export SCRIPT_INPUT_FILE_0=\"${path}/Quick.framework\"\n export SCRIPT_INPUT_FILE_1=\"${path}/Nimble.framework\"\n /usr/local/bin/carthage copy-frameworks\n break\nfi\ndone\n"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 83DA75E32065167600303D8F /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 83973ADF206FD4080057CD4F /* FontMetrics.swift in Sources */, - 831FE59321F52E330078F260 /* NSColor+rgbaColor.swift in Sources */, - 8382A324206EB40500E264A3 /* NotificationsProtocol.swift in Sources */, - 83DC7B5E2149AD4B00AF12A7 /* FeatureStatusesProtocol.swift in Sources */, - 83DC7B5C2149ACFD00AF12A7 /* HandicapStatusesProtocol.swift in Sources */, - 831E8EEE21247C620096930C /* Handicap.swift in Sources */, - 83D2A46920F006000032054C /* CGFloat+contentSizeString.swift in Sources */, - 833D435621CFE44000444EC9 /* UIFont+fontProps.swift in Sources */, - 83973ADA206FD22C0057CD4F /* UIFont+ScaledFont.swift in Sources */, - 831FE59121F52DDD0078F260 /* UIColor+rgbaColor.swift in Sources */, - 44E1055A2125CC7B00D85BBC /* HandicapStatus.swift in Sources */, - 83B5FFE42065336F00E8E83F /* Capable.swift in Sources */, - 44FE2E3621147A6F00029869 /* FontMetricsSupport.swift in Sources */, - 83CAA3FA2097BF9B003F231D /* OsVersionProviderProtocol.swift in Sources */, - 44580D13212606BB00F9940A /* FeatureStatuses.swift in Sources */, - 831E8EF021247EAD0096930C /* HandicapEnabledMode.swift in Sources */, - 83CAA3F82097BEEC003F231D /* OsVersionProvider.swift in Sources */, - 44478267233279EF00FB1B3B /* Image+averageColor.swift in Sources */, - 833D435421CFE42B00444EC9 /* NSFont+fontProps.swift in Sources */, - 83DB72462069891200384B3F /* UIContentSizeCategory+values.swift in Sources */, - 448697682127133A00A06BFF /* HandicapNotifications.swift in Sources */, - 44580D11212605D500F9940A /* HandicapStatuses.swift in Sources */, - 83C6A351219E08DB00BB039D /* String+isDefaultContentSize.swift in Sources */, - 44FE2E34211479F700029869 /* FontMetricsProviderProtocol.swift in Sources */, - 44D0B937233F86DC00A9B136 /* CIImage+initWithImage.swift in Sources */, - 44A5FBE321B03BB4008DE1EB /* FontProps.swift in Sources */, - 83C6A353219E0FF200BB039D /* HearingDeviceEar+stringValue.swift in Sources */, - 83973ADD206FD3A40057CD4F /* FontMetricsProtocol.swift in Sources */, - 83DB724820698EB400384B3F /* Bool+statusString.swift in Sources */, - 833DB9C2206C188B00C8DA02 /* FeatureStatus.swift in Sources */, - 8382A326206EB46E00E264A3 /* Notifications.swift in Sources */, - 83DC7B622149C03E00AF12A7 /* StatusesProtocol.swift in Sources */, - 83DAF4B821A4A9670076F542 /* RGBAColor.swift in Sources */, - 44FE2E32211479A300029869 /* FontMetricsProvider.swift in Sources */, - 83648E9E218A36560095D208 /* Logger.swift in Sources */, - 831AA4E0212F46CC00AEAC44 /* NotificationCenterProtocol.swift in Sources */, - 833DB9BF206C164B00C8DA02 /* Notification+Name.swift in Sources */, - 833CE9AA2194CCF400D741DE /* OSLogType+greaterEqual.swift in Sources */, - 83B5FFEB206542FC00E8E83F /* FeatureStatusesProviderProtocol.swift in Sources */, - 4447826B2332808400FB1B3B /* ImageArea.swift in Sources */, - 83B5FFE62065352500E8E83F /* CapableFeature.swift in Sources */, - 4486976A2127148700A06BFF /* FeatureNotifications.swift in Sources */, - 8382A322206E350F00E264A3 /* FeatureStatusesProvider.swift in Sources */, - 83DAF4B621A4A7320076F542 /* Color+wcag.swift in Sources */, - 83160D9521A548EF00FD122C /* ConformanceLevel.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 83DA75ED2065167600303D8F /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8323D8EA2167D0670015F8A3 /* HandicapStatusesMock.swift in Sources */, - 8311E58721EE841800B416B4 /* FontPropsTests.swift in Sources */, - 8323D8E62167B8C80015F8A3 /* FeatureStatusesTests.swift in Sources */, - 834C72342131F55100DCEBDC /* HandicapNotificationsTests.swift in Sources */, - 83097DA721A97CAA00703F29 /* RGBAColorTests.swift in Sources */, - 83DA75F72065167600303D8F /* CapableTests.swift in Sources */, - 831AA4DE212F437800AEAC44 /* NotificationCenterMock.swift in Sources */, - 44FE2E452114849100029869 /* OsVersionProviderMock.swift in Sources */, - 833D435821CFE7D300444EC9 /* NSFontFontPropsTests.swift in Sources */, - 83B21D6D21DE687200E02470 /* UIFontFontPropsTests.swift in Sources */, - 44FE2E442114833700029869 /* FontMetricsProviderMock.swift in Sources */, - 8323D8E82167C2550015F8A3 /* HandicapStatusesTests.swift in Sources */, - 448433B323409ABA00FC7DBC /* ImageAreaTests.swift in Sources */, - 44FE2E3B211482DD00029869 /* FontMetricsProviderTests.swift in Sources */, - 83DC7B602149BB4800AF12A7 /* NotificationsTests.swift in Sources */, - 44580D1721260EAA00F9940A /* FeatureStatusesProviderMock.swift in Sources */, - 44FE2E3F2114830B00029869 /* FontMetricsTests.swift in Sources */, - 83529F3F21ED2BF6007637C7 /* ColorWcagTests.swift in Sources */, - 44FE2E422114832300029869 /* FontMetricsMock.swift in Sources */, - 448433BE2340AE6800FC7DBC /* Image+mock.swift in Sources */, - 834C7232213072B300DCEBDC /* FeatureNotificationsTests.swift in Sources */, - 44580D1921261D4E00F9940A /* CapablePerfTests.swift in Sources */, - 83097DA521A9736100703F29 /* ConformanceLevelTests.swift in Sources */, - 448433C02340B06D00FC7DBC /* ImageAverageColorTests.swift in Sources */, - 833CE9AD2196296500D741DE /* LoggerTests.swift in Sources */, - 4404835E2168F1940051FCE7 /* FeatureStatusesProviderTests.swift in Sources */, - 8323D8EC2167D1980015F8A3 /* FeatureStatusesMock.swift in Sources */, - 44FE2E3D211482F500029869 /* FontMetricsSupportTests.swift in Sources */, - 83648E972187BD000095D208 /* HandicapTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 83DA75F42065167600303D8F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 83DA75E72065167600303D8F /* Capable */; - targetProxy = 83DA75F32065167600303D8F /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 83DA75FA2065167600303D8F /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - "OTHER_LDFLAGS[sdk=watchos*]" = "-WatchKit.framework"; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TVOS_DEPLOYMENT_TARGET = 10.0; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - WATCHOS_DEPLOYMENT_TARGET = 4.0; - }; - name = Debug; - }; - 83DA75FB2065167600303D8F /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MTL_ENABLE_DEBUG_INFO = NO; - "OTHER_LDFLAGS[arch=*]" = "-WatchKit.framework"; - SDKROOT = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 5.0; - TVOS_DEPLOYMENT_TARGET = 10.0; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - WATCHOS_DEPLOYMENT_TARGET = 4.0; - }; - name = Release; - }; - 83DA75FD2065167600303D8F /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = ""; - CODE_SIGN_STYLE = Automatic; - DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = V7PYJ2FTTJ; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - PRODUCT_BUNDLE_IDENTIFIER = "de.christoph-wendt.Capable"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - RESOURCES_TARGETED_DEVICE_FAMILY = ""; - SDKROOT = ""; - SKIP_INSTALL = YES; - SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,3,4"; - TVOS_DEPLOYMENT_TARGET = 10.0; - WATCHOS_DEPLOYMENT_TARGET = 4.0; - }; - name = Debug; - }; - 83DA75FE2065167600303D8F /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = ""; - CODE_SIGN_STYLE = Automatic; - DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = V7PYJ2FTTJ; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - PRODUCT_BUNDLE_IDENTIFIER = "de.christoph-wendt.Capable"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - RESOURCES_TARGETED_DEVICE_FAMILY = ""; - SDKROOT = ""; - SKIP_INSTALL = YES; - SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,3,4"; - TVOS_DEPLOYMENT_TARGET = 10.0; - WATCHOS_DEPLOYMENT_TARGET = 4.0; - }; - name = Release; - }; - 83DA76002065167600303D8F /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Mac Developer"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = V7PYJ2FTTJ; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/iOS", - "$(PROJECT_DIR)/Carthage/Build/tvOS", - "$(PROJECT_DIR)/Carthage/Build/Mac", - ); - "FRAMEWORK_SEARCH_PATHS[sdk=appletvos*]" = "$(SRCROOT)/Carthage/Build/tvOS"; - "FRAMEWORK_SEARCH_PATHS[sdk=appletvsimulator*]" = "$(SRCROOT)/Carthage/Build/tvOS"; - "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*]" = "$(SRCROOT)/Carthage/Build/iOS"; - "FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*]" = "$(SRCROOT)/Carthage/Build/iOS"; - "FRAMEWORK_SEARCH_PATHS[sdk=macosx*]" = "$(PROJECT_DIR)/Carthage/Build/Mac"; - INFOPLIST_FILE = Tests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks @loader_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - PRODUCT_BUNDLE_IDENTIFIER = "de.christoph-wendt.CapableTests"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,3,4"; - TVOS_DEPLOYMENT_TARGET = 10.0; - WATCHOS_DEPLOYMENT_TARGET = 4.0; - }; - name = Debug; - }; - 83DA76012065167600303D8F /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = V7PYJ2FTTJ; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/iOS", - "$(PROJECT_DIR)/Carthage/Build/tvOS", - "$(PROJECT_DIR)/Carthage/Build/Mac", - ); - "FRAMEWORK_SEARCH_PATHS[sdk=appletvos*]" = "$(SRCROOT)/Carthage/Build/tvOS"; - "FRAMEWORK_SEARCH_PATHS[sdk=appletvsimulator*]" = "$(SRCROOT)/Carthage/Build/tvOS"; - "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*]" = "$(SRCROOT)/Carthage/Build/iOS"; - "FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*]" = "$(SRCROOT)/Carthage/Build/iOS"; - "FRAMEWORK_SEARCH_PATHS[sdk=macosx*]" = "$(PROJECT_DIR)/Carthage/Build/Mac"; - INFOPLIST_FILE = Tests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - PRODUCT_BUNDLE_IDENTIFIER = "de.christoph-wendt.CapableTests"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,3,4"; - TVOS_DEPLOYMENT_TARGET = 10.0; - WATCHOS_DEPLOYMENT_TARGET = 4.0; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 83DA75E22065167600303D8F /* Build configuration list for PBXProject "Capable" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 83DA75FA2065167600303D8F /* Debug */, - 83DA75FB2065167600303D8F /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 83DA75FC2065167600303D8F /* Build configuration list for PBXNativeTarget "Capable" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 83DA75FD2065167600303D8F /* Debug */, - 83DA75FE2065167600303D8F /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 83DA75FF2065167600303D8F /* Build configuration list for PBXNativeTarget "CapableTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 83DA76002065167600303D8F /* Debug */, - 83DA76012065167600303D8F /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 83DA75DF2065167600303D8F /* Project object */; -} diff --git a/Capable.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Capable.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 13619c2..0000000 --- a/Capable.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/Capable.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Capable.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d9810..0000000 --- a/Capable.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/Capable.xcodeproj/xcshareddata/xcbaselines/83DA75F02065167600303D8F.xcbaseline/EB7FCBA4-87ED-4F09-BBB2-B815D78DFC46.plist b/Capable.xcodeproj/xcshareddata/xcbaselines/83DA75F02065167600303D8F.xcbaseline/EB7FCBA4-87ED-4F09-BBB2-B815D78DFC46.plist deleted file mode 100644 index c69e6a4..0000000 --- a/Capable.xcodeproj/xcshareddata/xcbaselines/83DA75F02065167600303D8F.xcbaseline/EB7FCBA4-87ED-4F09-BBB2-B815D78DFC46.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - classNames - - CapablePerfTests - - testStatusMapPerformance() - - com.apple.XCTPerformanceMetric_WallClockTime - - baselineAverage - 0.0044355 - baselineIntegrationDisplayName - Local Baseline - - - - - - diff --git a/Capable.xcodeproj/xcshareddata/xcbaselines/83DA75F02065167600303D8F.xcbaseline/Info.plist b/Capable.xcodeproj/xcshareddata/xcbaselines/83DA75F02065167600303D8F.xcbaseline/Info.plist deleted file mode 100644 index 4ae6ea0..0000000 --- a/Capable.xcodeproj/xcshareddata/xcbaselines/83DA75F02065167600303D8F.xcbaseline/Info.plist +++ /dev/null @@ -1,40 +0,0 @@ - - - - - runDestinationsByUUID - - EB7FCBA4-87ED-4F09-BBB2-B815D78DFC46 - - localComputer - - busSpeedInMHz - 100 - cpuCount - 1 - cpuKind - Intel Core i7 - cpuSpeedInMHz - 3100 - logicalCPUCoresPerPackage - 8 - modelCode - MacBookPro14,3 - physicalCPUCoresPerPackage - 4 - platformIdentifier - com.apple.platform.macosx - - targetArchitecture - x86_64 - targetDevice - - modelCode - iPhone10,3 - platformIdentifier - com.apple.platform.iphonesimulator - - - - - diff --git a/Cartfile b/Cartfile deleted file mode 100644 index e69de29..0000000 diff --git a/Cartfile.private b/Cartfile.private deleted file mode 100644 index e95f845..0000000 --- a/Cartfile.private +++ /dev/null @@ -1,2 +0,0 @@ -github "Quick/Quick" -github "Quick/Nimble" \ No newline at end of file diff --git a/Cartfile.resolved b/Cartfile.resolved deleted file mode 100644 index 9eb6d52..0000000 --- a/Cartfile.resolved +++ /dev/null @@ -1,2 +0,0 @@ -github "Quick/Nimble" "v8.0.4" -github "Quick/Quick" "v2.2.0" diff --git a/Documentation/Enums.html b/Documentation/Enums.html deleted file mode 100644 index a5a8e20..0000000 --- a/Documentation/Enums.html +++ /dev/null @@ -1,253 +0,0 @@ - - - - Enumerations Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

Enumerations

-

The following enumerations are available globally.

- -
-
-
-
    -
  • -
    - - - - ConformanceLevel - -
    -
    -
    -
    -
    -
    -

    An enum specifying all WCAG conformance levels.

    - - See more -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public enum ConformanceLevel : Int
    - -
    -
    -
    -
    -
  • -
-
-
-
    -
  • -
    - - - - ImageArea - -
    -
    -
    -
    -
    -
    -

    Undocumented

    - - See more -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public enum ImageArea
    - -
    -
    -
    -
    -
  • -
-
-
-
    -
  • -
    - - - - CapableFeature - -
    -
    -
    -
    -
    -
    -

    An enum specifying all features available on the current platform.

    - - See more -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public enum CapableFeature : String, CaseIterable
    - -
    -
    -
    -
    -
  • -
-
-
-
    -
  • -
    - - - - HandicapEnabledMode - -
    -
    -
    -
    -
    -
    -

    This enum defines several modes which describe whether all features need to be enabled to set the Handicap‘s status to enabled or only one of them.

    - - See more -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public enum HandicapEnabledMode : String
    - -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/Enums/CapableFeature.html b/Documentation/Enums/CapableFeature.html deleted file mode 100644 index 573f8d7..0000000 --- a/Documentation/Enums/CapableFeature.html +++ /dev/null @@ -1,667 +0,0 @@ - - - - CapableFeature Enumeration Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

CapableFeature

-
-
-
public enum CapableFeature : String, CaseIterable
- -
-
-

An enum specifying all features available on the current platform.

- -
-
-
-
    -
  • -
    - - - - assistiveTouch - -
    -
    -
    -
    -
    -
    -

    Menu that helps people with motor skill impairments to do certain actions or gestures by using a single tap.

    - -
    -
    -
    -
  • -
  • -
    - - - - darkerSystemColors - -
    -
    -
    -
    -
    -
    -

    Enhances text contrast.

    - -
    -
    -
    -
  • -
  • -
    - - - - guidedAccess - -
    -
    -
    -
    -
    -
    -

    Restricts access to certain features of a single app to keep the user focused.

    - -
    -
    -
    -
  • -
  • -
    - - - - hearingDevice - -
    -
    -
    -
    -
    -
    -

    Pairing status of a hearing aid.

    - -
    -
    -
    -
  • -
  • -
    - - - - onOffSwitchLabels - -
    -
    -
    -
    -
    -
    -

    Displays on/off labels for UISwitch controls.

    - -
    -
    -
    -
  • -
  • -
    - - - - shakeToUndo - -
    -
    -
    -
    -
    -
    -

    Deletes the last command by shaking the phone.

    - -
    -
    -
    -
  • -
  • -
    - - - - speakScreen - -
    -
    -
    -
    -
    -
    -

    Reads out the content of the current screen.

    - -
    -
    -
    -
  • -
  • -
    - - - - speakSelection - -
    -
    -
    -
    -
    -
    -

    Reads out the selected content.

    - -
    -
    -
    -
  • -
  • -
    - - - - fullKeyboardAccess - -
    -
    -
    -
    -
    -
    -

    Enables users to navigate through items of the screen without having to use a mouse.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case fullKeyboardAccess
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - increaseContrast - -
    -
    -
    -
    -
    -
    -

    Increases contrast to make out text and interface elements.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case increaseContrast
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - closedCaptioning - -
    -
    -
    -
    -
    -
    -

    Displays subtitles when playing videos.

    - -
    -
    -
    -
  • -
  • -
    - - - - grayscale - -
    -
    -
    -
    -
    -
    -

    Makes the display more readable for color blind people by using gray tones instead of colors.

    - -
    -
    -
    -
  • -
  • -
    - - - - monoAudio - -
    -
    -
    -
    -
    -
    -

    Merges stereo audio channels to help users that are hard of hearing or deaf in one ear.

    - -
    -
    -
    -
  • -
  • -
    - - - - videoAutoplay - -
    -
    -
    -
    -
    -
    -

    Allows users who are sensitive to motion to disable automatic video playback.

    - -
    -
    -
    -
  • -
  • -
    - - - - largerText - -
    -
    -
    -
    -
    -
    -

    Increases legibility by making fonts bigger.

    - -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Helps color blind users to differentiate settings differently, e.g. by using shapes rather than colors.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case differentiateWithoutColor
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - invertColors - -
    -
    -
    -
    -
    -
    -

    Helps people with low vision, color blindness, or sensitivity to brightness to read the display content.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case invertColors
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - reduceTransparency - -
    -
    -
    -
    -
    -
    -

    Removes transparency from layers to make them readable for users with visual impairment.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case reduceTransparency
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - switchControl - -
    -
    -
    -
    -
    -
    -

    Allows users with limited mobility to control their device with the help of ability switches and other adaptive devices.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case switchControl
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - boldText - -
    -
    -
    -
    -
    -
    -

    Increases legibility by making fonts heavier.

    - -
    -
    -
    -
  • -
  • -
    - - - - reduceMotion - -
    -
    -
    -
    -
    -
    -

    Reduces animations to help users with motion sickness and epilepsy issues.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case reduceMotion
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - voiceOver - -
    -
    -
    -
    -
    -
    -

    The screen reader available on Apple platforms.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case voiceOver
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - keys(forFeatures:) - -
    -
    -
    -
    -
    -
    -

    Iterates through a given list of feature types and returns an array containing the feature names as strings.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public static func keys(forFeatures features: [CapableFeature]) -> [String]
    - -
    -
    -
    -

    Parameters

    - - - - - - - -
    - - features - - -
    -

    An array containing the feature types of interest.

    -
    -
    -
    -
    -

    Return Value

    -

    An array containing the feature names as strings

    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/Enums/ConformanceLevel.html b/Documentation/Enums/ConformanceLevel.html deleted file mode 100644 index 17d9bbe..0000000 --- a/Documentation/Enums/ConformanceLevel.html +++ /dev/null @@ -1,344 +0,0 @@ - - - - ConformanceLevel Enumeration Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

ConformanceLevel

-
-
-
public enum ConformanceLevel : Int
- -
-
-

An enum specifying all WCAG conformance levels.

- -
-
-
-
    -
  • -
    - - - - A - -
    -
    -
    -
    -
    -
    -

    The minimum level of conformance.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case A = 1
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - AA - -
    -
    -
    -
    -
    -
    -

    The medium level of conformance including success criterias of level A.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case AA = 2
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - AAA - -
    -
    -
    -
    -
    -
    -

    The highest level of conformance including success criterias of level A and AA.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case AAA = 3
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - failed - -
    -
    -
    -
    -
    -
    -

    Indicates that no level of conformance has been reached.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case failed = 0
    - -
    -
    -
    -
    -
  • -
-
-
-
    -
  • - -
    -
    -
    -
    -
    -

    Initializes a ConformanceLevel based on a given contrast ratio and font information used for the text.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public init(contrastRatio: CGFloat, fontSize: CGFloat, isBoldFont: Bool)
    - -
    -
    -
    -

    Parameters

    - - - - - - - - - - - - - - - -
    - - contrastRatio - - -
    -

    The contrast ratio of a text and its background.

    -
    -
    - - fontSize - - -
    -

    The font size of the text.

    -
    -
    - - isBoldFont - - -
    -

    Information regarding the font weight.

    -
    -
    -
    -
    -
    -
  • -
  • -
    - - - - text - -
    -
    -
    -
    -
    -
    -

    The text representation of the conformance level.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public var text: String { get }
    - -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/Enums/HandicapEnabledMode.html b/Documentation/Enums/HandicapEnabledMode.html deleted file mode 100644 index 8e5a18c..0000000 --- a/Documentation/Enums/HandicapEnabledMode.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - HandicapEnabledMode Enumeration Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

HandicapEnabledMode

-
-
-
public enum HandicapEnabledMode : String
- -
-
-

This enum defines several modes which describe whether all features need to be enabled to set the Handicap‘s status to enabled or only one of them.

- -
-
-
-
    -
  • -
    - - - - oneFeatureEnabled - -
    -
    -
    -
    -
    -
    -

    The Handicap‘s status is enabled if one of its features is currently set to enabled.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case oneFeatureEnabled
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - allFeaturesEnabled - -
    -
    -
    -
    -
    -
    -

    The Handicap‘s status is enabled if all its features are currently set to enabled.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case allFeaturesEnabled
    - -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/Enums/ImageArea.html b/Documentation/Enums/ImageArea.html deleted file mode 100644 index 04b2fa6..0000000 --- a/Documentation/Enums/ImageArea.html +++ /dev/null @@ -1,594 +0,0 @@ - - - - ImageArea Enumeration Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

ImageArea

-
-
-
public enum ImageArea
- -
-
-

Undocumented

- -
-
-
-
    -
  • -
    - - - - full - -
    -
    -
    -
    -
    -
    -

    The full image size.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case full
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - bottom - -
    -
    -
    -
    -
    -
    -

    The last vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case bottom
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - bottomCenter - -
    -
    -
    -
    -
    -
    -

    The second horizontal third of the last vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case bottomCenter
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - bottomLeft - -
    -
    -
    -
    -
    -
    -

    The first horizontal third of the last vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case bottomLeft
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - bottomRight - -
    -
    -
    -
    -
    -
    -

    The last horizontal third of the last vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case bottomRight
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - center - -
    -
    -
    -
    -
    -
    -

    The second horizontal third of the second vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case center
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - centerLeft - -
    -
    -
    -
    -
    -
    -

    The first horizontal third of the second vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case centerLeft
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - centerRight - -
    -
    -
    -
    -
    -
    -

    The last horizontal third of the second vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case centerRight
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - custom(rect:) - -
    -
    -
    -
    -
    -
    -

    A custom area of the image defined by a CGRect.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case custom(rect: CGRect)
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - horizontalCenter - -
    -
    -
    -
    -
    -
    -

    The second vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case horizontalCenter
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - left - -
    -
    -
    -
    -
    -
    -

    The first horizontal third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case left
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - right - -
    -
    -
    -
    -
    -
    -

    The last horizontal third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case right
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - top - -
    -
    -
    -
    -
    -
    -

    The first vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case top
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - topCenter - -
    -
    -
    -
    -
    -
    -

    The second horizontal third of the first vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case topCenter
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - topLeft - -
    -
    -
    -
    -
    -
    -

    The first horizontal third of the first vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case topLeft
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - topRight - -
    -
    -
    -
    -
    -
    -

    The last horizontal third of the first vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case topRight
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - verticalCenter - -
    -
    -
    -
    -
    -
    -

    The second horizontal third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case verticalCenter
    - -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/Extensions.html b/Documentation/Extensions.html deleted file mode 100644 index d18155c..0000000 --- a/Documentation/Extensions.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - Extensions Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

Extensions

-

The following extensions are available globally.

- -
-
-
-
    -
  • -
    - - - - Color - -
    -
    -
    -
    -
    -
    -

    Extension that adds functionality for calculating WCAG compliant high contrast colors.

    - - See more -
    -
    -

    Declaration

    -
    -

    Swift

    -
    extension Color
    - -
    -
    -
    -
    -
  • -
-
-
- -
-
-
    -
  • -
    - - - - UIFont - -
    -
    -
    -
    -
    -
    -

    Extension that adds functionality for creating scalable UIFont objects.

    - - See more -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/Extensions/Color.html b/Documentation/Extensions/Color.html deleted file mode 100644 index c1135f8..0000000 --- a/Documentation/Extensions/Color.html +++ /dev/null @@ -1,608 +0,0 @@ - - - - Color Extension Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

Color

-
-
-
extension Color
- -
-
-

Extension that adds functionality for calculating WCAG compliant high contrast colors.

- -
-
-
-
    -
  • - -
    -
    -
    -
    -
    -

    Calculates the color ratio for a text color on a background color.

    -
    -

    Note

    -

    Semi-transparent text colors will be blended with the background color. However, for background colors, the alpha component is ignored.

    - -
    -
    -

    Warning

    -

    This function will also return nil if any input color is not convertable to the sRGB color space.

    - -
    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public class func getContrastRatio(forTextColor textColor: Color, onBackgroundColor backgroundColor: Color) -> CGFloat?
    - -
    -
    -
    -

    Parameters

    - - - - - - - - - - - -
    - - textColor - - -
    -

    The text color.

    -
    -
    - - backgroundColor - - -
    -

    The background color.

    -
    -
    -
    -
    -

    Return Value

    -

    The contrast ratio for a given pair of colors.

    -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Returns the text color with the highest contrast (black or white) for a given background color.

    -
    -

    Note

    -

    Semi-transparent text colors will be blended with the background color. However, for background colors, the alpha component is ignored.

    - -
    -
    -

    Warning

    -

    This function will also return nil if any input color is not convertable to the sRGB color space.

    - -
    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public class func getTextColor(onBackgroundColor backgroundColor: Color) -> Color?
    - -
    -
    -
    -

    Parameters

    - - - - - - - -
    - - backgroundColor - - -
    -

    The background color.

    -
    -
    -
    -
    -

    Return Value

    -

    A color that has the highest contrast with the given background color.

    -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Calculates the contrast ratio of a given list of text colors and a background color. The first color that conforms to the conformance level defined gets returned. The default conformance level is .AA.

    -
    -

    Note

    -

    Semi-transparent text colors will be blended with the background color. However, for background colors, the alpha component is ignored.

    - -
    -
    -

    Warning

    -

    This function will also return nil if any input color is not convertable to the sRGB color space.

    - -
    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public class func getTextColor(fromColors colors: [Color], withFont font: Font, onBackgroundColor backgroundColor: Color, conformanceLevel: ConformanceLevel = .AA) -> Color?
    - -
    -
    -
    -

    Parameters

    - - - - - - - - - - - - - - - - - - - -
    - - colors - - -
    -

    A list of possible text colors.

    -
    -
    - - font - - -
    -

    The font used for the text.

    -
    -
    - - backgroundColor - - -
    -

    The background color that the text should be displayed on.

    -
    -
    - - conformanceLevel - - -
    -

    The conformance level that needs to be passed when calculating the contrast ratio. The default conformance level is .AA.

    -
    -
    -
    -
    -

    Return Value

    -

    The first color that conforms to the conformance level defined or nil if non of the colors provided passed.

    -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Returns the text color with the highest contrast (black or white) for a specific area of given background image.

    -
  • backgroundImage: The background image.
  • -
  • imageArea: The area of the image that is used as the text background. Defaults to .full.

  • -
    -

    Note

    -

    For the background image, the alpha component is ignored.

    - -
    -
    -

    Warning

    -

    This function will also return nil if the image is corrupted.

    - -
    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public class func getTextColor(onBackgroundImage image: Image, imageArea: ImageArea = .full) -> Color?
    - -
    -
    -
    -

    Return Value

    -

    A color that has the highest contrast with the given background image.

    -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Calculates the contrast ratio of a given list of text colors and a specific area of given background image. The first color that conforms to the conformance level defined gets returned. The default conformance level is .AA.

    -
  • colors: A list of possible text colors.
  • -
  • font: The font used for the text.
  • -
  • backgroundImage: The background image that the text should be displayed on.
  • -
  • imageArea: The area of the image that is used as the text background. Defaults to .full.
  • -
  • conformanceLevel: The conformance level that needs to be passed when calculating the contrast ratio. The default conformance level is .AA.

  • -
    -

    Note

    -

    Semi-transparent text colors will be blended with the background color. However, for the background image, the alpha component is ignored.

    - -
    -
    -

    Warning

    -

    This function will also return nil if any input color is not convertable to the sRGB color space.

    - -
    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public class func getTextColor(fromColors colors: [Color], withFont font: Font, onBackgroundImage image: Image, imageArea: ImageArea = .full, conformanceLevel: ConformanceLevel = .AA) -> Color?
    - -
    -
    -
    -

    Return Value

    -

    The first color that conforms to the conformance level defined or nil if non of the colors provided passed.

    -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Returns the background color with the highest contrast (black or white) for a given text color.

    -
    -

    Note

    -

    Semi-transparent text colors will be blended with the background color. However, for background colors, the alpha component is ignored.

    - -
    -
    -

    Warning

    -

    This function will also return nil if any input color is not convertable to the sRGB color space.

    - -
    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public class func getBackgroundColor(forTextColor textColor: Color) -> Color?
    - -
    -
    -
    -

    Parameters

    - - - - - - - -
    - - textColor - - -
    -

    The textColor color.

    -
    -
    -
    -
    -

    Return Value

    -

    A color that has the highest contrast with the given text color.

    -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Calculates the contrast ratio of a given list of background colors and a text color. The first color that conforms to the conformance level defined gets returned. The default conformance level is .AA.

    -
    -

    Note

    -

    Semi-transparent text colors will be blended with the background color. However, for background colors, the alpha component is ignored.

    - -
    -
    -

    Warning

    -

    This function will also return nil if any input color is not convertable to the sRGB color space.

    - -
    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public class func getBackgroundColor(fromColors colors: [Color], forTextColor textColor: Color, withFont font: Font, conformanceLevel: ConformanceLevel = .AA) -> Color?
    - -
    -
    -
    -

    Parameters

    - - - - - - - - - - - - - - - - - - - -
    - - colors - - -
    -

    A list of possible background colors.

    -
    -
    - - textColor - - -
    -

    The text color that should be used.

    -
    -
    - - font - - -
    -

    The font used for the text.

    -
    -
    - - conformanceLevel - - -
    -

    The conformance level that needs to be passed when calculating the contrast ratio. The default conformance level is .AA.

    -
    -
    -
    -
    -

    Return Value

    -

    The first color that conforms to the conformance level defined or nil if non of the colors provided passed.

    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/Extensions/Notification.html b/Documentation/Extensions/Notification.html deleted file mode 100644 index 08dc91e..0000000 --- a/Documentation/Extensions/Notification.html +++ /dev/null @@ -1,156 +0,0 @@ - - - - Notification Extension Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

Notification

- -
-
-
-
    -
  • -
    - - - - Name - -
    -
    -
    -
    -
    -
    -

    Extension that defines notification names provided by the Capable framework.

    - - See more -
    -
    -

    Declaration

    -
    -

    Swift

    -
    extension Notification.Name
    - -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/Extensions/Notification/Name.html b/Documentation/Extensions/Notification/Name.html deleted file mode 100644 index 17e2d75..0000000 --- a/Documentation/Extensions/Notification/Name.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - Name Extension Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

Name

-
-
-
extension Notification.Name
- -
-
-

Extension that defines notification names provided by the Capable framework.

- -
-
-
-
    -
  • - -
    -
    -
    -
    -
    -

    Name of the notification that gets fired whenever an observed accessibility feature status changes.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public static let CapableFeatureStatusDidChange: Notification.Name
    - -
    -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Name of the notification that gets fired whenever an observed Handicap status changes.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public static let CapableHandicapStatusDidChange: Notification.Name
    - -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/Extensions/UIFont.html b/Documentation/Extensions/UIFont.html deleted file mode 100644 index 2df44b6..0000000 --- a/Documentation/Extensions/UIFont.html +++ /dev/null @@ -1,224 +0,0 @@ - - - - UIFont Extension Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

UIFont

-

Extension that adds functionality for creating scalable UIFont objects.

- -
-
-
- -
-
-
- -
-
- - - diff --git a/Documentation/Reference/README.md b/Documentation/Reference/README.md new file mode 100644 index 0000000..5e9488f --- /dev/null +++ b/Documentation/Reference/README.md @@ -0,0 +1,24 @@ +# Reference Documentation +This Reference Documentation has been generated with +[SourceDocs](https://github.com/eneko/SourceDocs). + +## Structs + +- [Capable](structs/Capable.md) +- [FeatureStatus](structs/FeatureStatus.md) +- [Handicap](structs/Handicap.md) +- [HandicapStatus](structs/HandicapStatus.md) + +## Enums + +- [CapableFeature](enums/CapableFeature.md) +- [ConformanceLevel](enums/ConformanceLevel.md) +- [HandicapEnabledMode](enums/HandicapEnabledMode.md) +- [ImageArea](enums/ImageArea.md) + +## Extensions + +- [Capable](extensions/Capable.md) +- [Color](extensions/Color.md) +- [ConformanceLevel](extensions/ConformanceLevel.md) +- [UIFont](extensions/UIFont.md) diff --git a/Documentation/Reference/enums/CapableFeature.md b/Documentation/Reference/enums/CapableFeature.md new file mode 100644 index 0000000..15f3555 --- /dev/null +++ b/Documentation/Reference/enums/CapableFeature.md @@ -0,0 +1,150 @@ +**ENUM** + +# `CapableFeature` + +```swift +public enum CapableFeature: String, CaseIterable +``` + +> An enum specifying all features available on the current platform. + +## Cases +### `assistiveTouch` + +> Menu that helps people with motor skill impairments to do certain actions or gestures by using a single tap. + +### `darkerSystemColors` + +> Enhances text contrast. + +### `guidedAccess` + +> Restricts access to certain features of a single app to keep the user focused. + +### `hearingDevice` + +> Pairing status of a hearing aid. + +### `onOffSwitchLabels` + +> Displays on/off labels for UISwitch controls. + +### `shakeToUndo` + +> Deletes the last command by shaking the phone. + +### `speakScreen` + +> Reads out the content of the current screen. + +### `speakSelection` + +> Reads out the selected content. + +### `fullKeyboardAccess` + +```swift +case fullKeyboardAccess +``` + +> Enables users to navigate through items of the screen without having to use a mouse. + +### `increaseContrast` + +```swift +case increaseContrast +``` + +> Increases contrast to make out text and interface elements. + +### `closedCaptioning` + +> Displays subtitles when playing videos. + +### `grayscale` + +> Makes the display more readable for color blind people by using gray tones instead of colors. + +### `monoAudio` + +> Merges stereo audio channels to help users that are hard of hearing or deaf in one ear. + +### `videoAutoplay` + +> Allows users who are sensitive to motion to disable automatic video playback. + +### `largerText` + +> Increases legibility by making fonts bigger. + +### `differentiateWithoutColor` + +```swift +case differentiateWithoutColor +``` + +> Helps color blind users to differentiate settings differently, e.g. by using shapes rather than colors. + +### `invertColors` + +```swift +case invertColors +``` + +> Helps people with low vision, color blindness, or sensitivity to brightness to read the display content. + +### `reduceTransparency` + +```swift +case reduceTransparency +``` + +> Removes transparency from layers to make them readable for users with visual impairment. + +### `switchControl` + +```swift +case switchControl +``` + +> Allows users with limited mobility to control their device with the help of ability switches and other adaptive devices. + +### `boldText` + +> Increases legibility by making fonts heavier. + +### `reduceMotion` + +```swift +case reduceMotion +``` + +> Reduces animations to help users with motion sickness and epilepsy issues. + +### `voiceOver` + +```swift +case voiceOver +``` + +> The screen reader available on Apple platforms. + +## Methods +### `keys(forFeatures:)` + +```swift +public static func keys(forFeatures features: [CapableFeature]) -> [String] +``` + +> Iterates through a given list of feature types and returns an array containing the feature names as strings. +> +> - Parameters: +> - features: An array containing the feature types of interest. +> +> - Returns: An array containing the feature names as strings + +#### Parameters + +| Name | Description | +| ---- | ----------- | +| features | An array containing the feature types of interest. | \ No newline at end of file diff --git a/Documentation/Reference/enums/ConformanceLevel.md b/Documentation/Reference/enums/ConformanceLevel.md new file mode 100644 index 0000000..ef59725 --- /dev/null +++ b/Documentation/Reference/enums/ConformanceLevel.md @@ -0,0 +1,42 @@ +**ENUM** + +# `ConformanceLevel` + +```swift +public enum ConformanceLevel: Int +``` + +> An enum specifying all WCAG conformance levels. + +## Cases +### `A` + +```swift +case A = 1 +``` + +> The minimum level of conformance. + +### `AA` + +```swift +case AA = 2 +``` + +> The medium level of conformance including success criterias of level A. + +### `AAA` + +```swift +case AAA = 3 +``` + +> The highest level of conformance including success criterias of level A and AA. + +### `failed` + +```swift +case failed = 0 +``` + +> Indicates that no level of conformance has been reached. diff --git a/Documentation/Reference/enums/HandicapEnabledMode.md b/Documentation/Reference/enums/HandicapEnabledMode.md new file mode 100644 index 0000000..fef2602 --- /dev/null +++ b/Documentation/Reference/enums/HandicapEnabledMode.md @@ -0,0 +1,26 @@ +**ENUM** + +# `HandicapEnabledMode` + +```swift +public enum HandicapEnabledMode: String +``` + +> This enum defines several modes which describe whether all features need to be enabled to set the `Handicap`'s status to enabled or only one of them. + +## Cases +### `oneFeatureEnabled` + +```swift +case oneFeatureEnabled +``` + +> The `Handicap`'s status is enabled if one of its features is currently set to **enabled**. + +### `allFeaturesEnabled` + +```swift +case allFeaturesEnabled +``` + +> The `Handicap`'s status is enabled if all its features are currently set to **enabled**. diff --git a/Documentation/Reference/enums/ImageArea.md b/Documentation/Reference/enums/ImageArea.md new file mode 100644 index 0000000..301fc0b --- /dev/null +++ b/Documentation/Reference/enums/ImageArea.md @@ -0,0 +1,144 @@ +**ENUM** + +# `ImageArea` + +```swift +public enum ImageArea +``` + +## Cases +### `full` + +```swift +case full +``` + +> The full image size. + +### `bottom` + +```swift +case bottom +``` + +> The last vertical third. + +### `bottomCenter` + +```swift +case bottomCenter +``` + +> The second horizontal third of the last vertical third. + +### `bottomLeft` + +```swift +case bottomLeft +``` + +> The first horizontal third of the last vertical third. + +### `bottomRight` + +```swift +case bottomRight +``` + +> The last horizontal third of the last vertical third. + +### `center` + +```swift +case center +``` + +> The second horizontal third of the second vertical third. + +### `centerLeft` + +```swift +case centerLeft +``` + +> The first horizontal third of the second vertical third. + +### `centerRight` + +```swift +case centerRight +``` + +> The last horizontal third of the second vertical third. + +### `custom(rect:)` + +```swift +case custom(rect: CGRect) +``` + +> A custom area of the image defined by a CGRect. + +### `horizontalCenter` + +```swift +case horizontalCenter +``` + +> The second vertical third. + +### `left` + +```swift +case left +``` + +> The first horizontal third. + +### `right` + +```swift +case right +``` + +> The last horizontal third. + +### `top` + +```swift +case top +``` + +> The first vertical third. + +### `topCenter` + +```swift +case topCenter +``` + +> The second horizontal third of the first vertical third. + +### `topLeft` + +```swift +case topLeft +``` + +> The first horizontal third of the first vertical third. + +### `topRight` + +```swift +case topRight +``` + +> The last horizontal third of the first vertical third. + +### `verticalCenter` + +```swift +case verticalCenter +``` + +> The second horizontal third. diff --git a/Documentation/Reference/extensions/Capable.md b/Documentation/Reference/extensions/Capable.md new file mode 100644 index 0000000..37d390b --- /dev/null +++ b/Documentation/Reference/extensions/Capable.md @@ -0,0 +1,52 @@ +**EXTENSION** + +# `Capable` + +## Properties +### `statusMap` + +```swift +public var statusMap: [String: String] +``` + +> The `statusMap` property returns a dictionary of all `CapableFeature`s or `Handicap`s , that the Capable instance has been initialized with along with their current statuses. This object is compatible with most analytic SDKs such as **Fabric Answers**, **Firebase Analytics**, **AppCenter Analytics**, or **HockeyApp**. +> While most entries can only have a status set to **enabled** or **disabled**, the `.largerText` feature offers the font scale set by the user. + +## Methods +### `isFeatureEnabled(feature:)` + +```swift +public func isFeatureEnabled(feature: CapableFeature) -> Bool +``` + +> Provides information regarding the current status of a provided feature. +> +> - Parameters: +> - feature: The feature of interest. +> +> - Returns: `true` if the given feature has been enabled, otherwise `false`. + +#### Parameters + +| Name | Description | +| ---- | ----------- | +| feature | The feature of interest. | + +### `isHandicapEnabled(handicapName:)` + +```swift +public func isHandicapEnabled(handicapName: String) -> Bool +``` + +> Provides information regarding the current status of a provided `Handicap`. +> +> - Parameters: +> - handicapName: The name of the requested of `Handicap`. +> +> - Returns: `true` if the given feature has been enabled, otherwise `false`. Note that the status depends on the `Handicap`'s `enabledIf` value (see `HandicapEnabledMode`). + +#### Parameters + +| Name | Description | +| ---- | ----------- | +| handicapName | The name of the requested of `Handicap`. | \ No newline at end of file diff --git a/Documentation/Reference/extensions/Color.md b/Documentation/Reference/extensions/Color.md new file mode 100644 index 0000000..574cb60 --- /dev/null +++ b/Documentation/Reference/extensions/Color.md @@ -0,0 +1,172 @@ +**EXTENSION** + +# `Color` + +## Methods +### `getContrastRatio(forTextColor:onBackgroundColor:)` + +```swift +public class func getContrastRatio(forTextColor textColor: Color, onBackgroundColor backgroundColor: Color) -> CGFloat? +``` + +> Calculates the color ratio for a text color on a background color. +> +> - Parameters: +> - textColor: The text color. +> - backgroundColor: The background color. +> +> - Returns: The contrast ratio for a given pair of colors. +> +> - Note: Semi-transparent text colors will be blended with the background color. However, for background colors, the alpha component is ignored. +> +> - Warning: This function will also return `nil` if any input color is not convertable to the sRGB color space. + +#### Parameters + +| Name | Description | +| ---- | ----------- | +| textColor | The text color. | +| backgroundColor | The background color. | + +### `getTextColor(onBackgroundColor:)` + +```swift +public class func getTextColor(onBackgroundColor backgroundColor: Color) -> Color? +``` + +> Returns the text color with the highest contrast (black or white) for a given background color. +> +> - Parameters: +> - backgroundColor: The background color. +> +> - Returns: A color that has the highest contrast with the given background color. +> +> - Note: Semi-transparent text colors will be blended with the background color. However, for background colors, the alpha component is ignored. +> +> - Warning: This function will also return `nil` if any input color is not convertable to the sRGB color space. + +#### Parameters + +| Name | Description | +| ---- | ----------- | +| backgroundColor | The background color. | + +### `getTextColor(fromColors:withFont:onBackgroundColor:conformanceLevel:)` + +```swift +public class func getTextColor(fromColors colors: [Color], withFont font: Font, onBackgroundColor backgroundColor: Color, conformanceLevel: ConformanceLevel = .AA) -> Color? +``` + +> Calculates the contrast ratio of a given list of text colors and a background color. The first color that conforms to the conformance level defined gets returned. The default conformance level is .AA. +> +> - Parameters: +> - colors: A list of possible text colors. +> - font: The font used for the text. +> - backgroundColor: The background color that the text should be displayed on. +> - conformanceLevel: The conformance level that needs to be passed when calculating the contrast ratio. The default conformance level is .AA. +> +> - Returns: The first color that conforms to the conformance level defined or `nil` if non of the colors provided passed. +> +> - Note: Semi-transparent text colors will be blended with the background color. However, for background colors, the alpha component is ignored. +> +> - Warning: This function will also return `nil` if any input color is not convertable to the sRGB color space. + +#### Parameters + +| Name | Description | +| ---- | ----------- | +| colors | A list of possible text colors. | +| font | The font used for the text. | +| backgroundColor | The background color that the text should be displayed on. | +| conformanceLevel | The conformance level that needs to be passed when calculating the contrast ratio. The default conformance level is .AA. | + +### `getTextColor(onBackgroundImage:imageArea:)` + +```swift +public class func getTextColor(onBackgroundImage image: Image, imageArea: ImageArea = .full) -> Color? +``` + +> Returns the text color with the highest contrast (black or white) for a specific area of given background image. +> +> - Parameters: +> - backgroundImage: The background image. +> - imageArea: The area of the image that is used as the text background. Defaults to .full. +> +> - Returns: A color that has the highest contrast with the given background image. +> +> - Note: For the background image, the alpha component is ignored. +> +> - Warning: This function will also return `nil` if the image is corrupted. + +### `getTextColor(fromColors:withFont:onBackgroundImage:imageArea:conformanceLevel:)` + +```swift +public class func getTextColor(fromColors colors: [Color], withFont font: Font, onBackgroundImage image: Image, imageArea: ImageArea = .full, conformanceLevel: ConformanceLevel = .AA) -> Color? +``` + +> Calculates the contrast ratio of a given list of text colors and a specific area of given background image. The first color that conforms to the conformance level defined gets returned. The default conformance level is .AA. +> +> - Parameters: +> - colors: A list of possible text colors. +> - font: The font used for the text. +> - backgroundImage: The background image that the text should be displayed on. +> - imageArea: The area of the image that is used as the text background. Defaults to .full. +> - conformanceLevel: The conformance level that needs to be passed when calculating the contrast ratio. The default conformance level is .AA. +> +> - Returns: The first color that conforms to the conformance level defined or `nil` if non of the colors provided passed. +> +> - Note: Semi-transparent text colors will be blended with the background color. However, for the background image, the alpha component is ignored. +> +> - Warning: This function will also return `nil` if any input color is not convertable to the sRGB color space. + +### `getBackgroundColor(forTextColor:)` + +```swift +public class func getBackgroundColor(forTextColor textColor: Color) -> Color? +``` + +> Returns the background color with the highest contrast (black or white) for a given text color. +> +> - Parameters: +> - textColor: The textColor color. +> +> - Returns: A color that has the highest contrast with the given text color. +> +> - Note: Semi-transparent text colors will be blended with the background color. However, for background colors, the alpha component is ignored. +> +> - Warning: This function will also return `nil` if any input color is not convertable to the sRGB color space. + +#### Parameters + +| Name | Description | +| ---- | ----------- | +| textColor | The textColor color. | + +### `getBackgroundColor(fromColors:forTextColor:withFont:conformanceLevel:)` + +```swift +public class func getBackgroundColor(fromColors colors: [Color], forTextColor textColor: Color, withFont font: Font, conformanceLevel: ConformanceLevel = .AA) -> Color? +``` + +> Calculates the contrast ratio of a given list of background colors and a text color. The first color that conforms to the conformance level defined gets returned. The default conformance level is .AA. +> +> - Parameters: +> - colors: A list of possible background colors. +> - textColor: The text color that should be used. +> - font: The font used for the text. +> - conformanceLevel: The conformance level that needs to be passed when calculating the contrast ratio. The default conformance level is .AA. +> +> - Returns: The first color that conforms to the conformance level defined or `nil` if non of the colors provided passed. +> +> - Note: Semi-transparent text colors will be blended with the background color. However, for background colors, the alpha component is ignored. +> +> - Warning: This function will also return `nil` if any input color is not convertable to the sRGB color space. + +#### Parameters + +| Name | Description | +| ---- | ----------- | +| colors | A list of possible background colors. | +| textColor | The text color that should be used. | +| font | The font used for the text. | +| conformanceLevel | The conformance level that needs to be passed when calculating the contrast ratio. The default conformance level is .AA. | \ No newline at end of file diff --git a/Documentation/Reference/extensions/ConformanceLevel.md b/Documentation/Reference/extensions/ConformanceLevel.md new file mode 100644 index 0000000..814466d --- /dev/null +++ b/Documentation/Reference/extensions/ConformanceLevel.md @@ -0,0 +1,34 @@ +**EXTENSION** + +# `ConformanceLevel` + +## Properties +### `text` + +```swift +public var text: String +``` + +> The text representation of the conformance level. + +## Methods +### `init(contrastRatio:fontSize:isBoldFont:)` + +```swift +public init(contrastRatio: CGFloat, fontSize: CGFloat, isBoldFont: Bool) +``` + +> Initializes a ConformanceLevel based on a given contrast ratio and font information used for the text. +> +> - Parameters: +> - contrastRatio: The contrast ratio of a text and its background. +> - fontSize: The font size of the text. +> - isBoldFont: Information regarding the font weight. + +#### Parameters + +| Name | Description | +| ---- | ----------- | +| contrastRatio | The contrast ratio of a text and its background. | +| fontSize | The font size of the text. | +| isBoldFont | Information regarding the font weight. | \ No newline at end of file diff --git a/Documentation/Reference/extensions/UIFont.md b/Documentation/Reference/extensions/UIFont.md new file mode 100644 index 0000000..d055666 --- /dev/null +++ b/Documentation/Reference/extensions/UIFont.md @@ -0,0 +1,50 @@ +**EXTENSION** + +# `UIFont` + +## Methods +### `scaledFont(for:)` + +> Makes the given font scalable. +> +> - Parameters: +> - font: The font to make scalable. +> +> - Returns: A scalable font object. + +### `scaledFont(withName:ofSize:)` + +> Creates a scalable font with the given font name and reference font size. +> +> - Parameters: +> - fontName: The name of the font that should be used. +> - fontSize: The reference font size to use. +> +> - Returns: A scalable font object. + +### `scaledSystemFont(ofSize:)` + +> Creates a scalable system font with a given reference font size. +> +> - Parameters: +> - fontSize: The reference font size to use. +> +> - Returns: A scalable font object. + +### `scaledBoldSystemFont(ofSize:)` + +> Creates a scalable bold system font with a given reference font size. +> +> - Parameters: +> - fontSize: The reference font size to use. +> +> - Returns: A scalable font object. + +### `scaledItalicSystemFont(ofSize:)` + +> Creates a scalable italic system font with a given reference font size. +> +> - Parameters: +> - fontSize: The reference font size to use. +> +> - Returns: A scalable font object. diff --git a/Documentation/Reference/structs/Capable.md b/Documentation/Reference/structs/Capable.md new file mode 100644 index 0000000..1d61515 --- /dev/null +++ b/Documentation/Reference/structs/Capable.md @@ -0,0 +1,44 @@ +**STRUCT** + +# `Capable` + +```swift +public struct Capable +``` + +> This class defines the main interface of the Capable framework. + +## Methods +### `init(withFeatures:)` + +```swift +public init(withFeatures features: [CapableFeature] = CapableFeature.allCases) +``` + +> Initializes the framework instance with a specified set of features. If no feature was provided, this defaults to all features available on the current platform. +> +> - Parameters: +> - features: An optional array containing the features of interest. This will default to all features available on the current platform. + +#### Parameters + +| Name | Description | +| ---- | ----------- | +| features | An optional array containing the features of interest. This will default to all features available on the current platform. | + +### `init(withHandicaps:)` + +```swift +public init(withHandicaps handicaps: [Handicap]) +``` + +> Initializes the framework instance with a set of `Handicap`s. +> +> - Parameters: +> - handicaps: An optional array containing the `Handicaps`s specified by the caller. + +#### Parameters + +| Name | Description | +| ---- | ----------- | +| handicaps | An optional array containing the `Handicaps`s specified by the caller. | \ No newline at end of file diff --git a/Documentation/Reference/structs/FeatureStatus.md b/Documentation/Reference/structs/FeatureStatus.md new file mode 100644 index 0000000..c4de7e8 --- /dev/null +++ b/Documentation/Reference/structs/FeatureStatus.md @@ -0,0 +1,26 @@ +**STRUCT** + +# `FeatureStatus` + +```swift +public struct FeatureStatus +``` + +> Model class that describes the content of a Capable notification (see `Notification.Name.CapableFeatureStatusDidChange`) + +## Properties +### `feature` + +```swift +public private(set) var feature: CapableFeature +``` + +> The feature type. + +### `statusString` + +```swift +public private(set) var statusString: String +``` + +> The feature's status: While most features can only have a status set to **enabled** or **disabled**, the '.largerText` feature offers the font scale set by the user. diff --git a/Documentation/Reference/structs/Handicap.md b/Documentation/Reference/structs/Handicap.md new file mode 100644 index 0000000..10396c7 --- /dev/null +++ b/Documentation/Reference/structs/Handicap.md @@ -0,0 +1,48 @@ +**STRUCT** + +# `Handicap` + +```swift +public struct Handicap: Equatable +``` + +> Model class that groups a number of `CapableFeature`s to represent a user's handicap. + +## Properties +### `features` + +```swift +public private(set) var features: [CapableFeature] +``` + +> A list of `CapableFeature`s that are expected to be enabled if a user has this handicap. + +### `name` + +```swift +public private(set) var name: String +``` + +> The name of the `Handicap` that can be used to uniquely identify the `Handicap`. This name is also used inside the status map. + +### `enabledIf` + +```swift +public private(set) var enabledIf: HandicapEnabledMode +``` + +> This mode defines whether all features need to be enabled to set the `Handicap`'s status to enabled or only one of them. + +## Methods +### `init(features:name:enabledIf:)` + +```swift +public init(features: [CapableFeature], name: String, enabledIf: HandicapEnabledMode) +``` + +> Initializes a new `Handicap` object. +> +> - Parameters: +> - features: A list of features that are expected to be enabled if a user has this handicap. +> - name: The name of the `Handicap` that can be used to uniquely identify the `Handicap`. This name is also used inside the status map. +> - enabledIf: This mode defines whether all features need to be enabled to set the `Handicap`'s status to enabled or only one of them. diff --git a/Documentation/Reference/structs/HandicapStatus.md b/Documentation/Reference/structs/HandicapStatus.md new file mode 100644 index 0000000..2672e23 --- /dev/null +++ b/Documentation/Reference/structs/HandicapStatus.md @@ -0,0 +1,26 @@ +**STRUCT** + +# `HandicapStatus` + +```swift +public struct HandicapStatus +``` + +> Model class that describes the content of a Capable notification (see `Notification.Name.CapableHandicapStatusDidChange`) + +## Properties +### `handicap` + +```swift +public private(set) var handicap: Handicap +``` + +> The `Handicap` that has changed. + +### `statusString` + +```swift +public private(set) var statusString: String +``` + +> The `Handicap`'s status (**enabled** or **disabled**). Note that the status depends on the `Handicap`'s `enabledIf` value (see `HandicapEnabledMode`). diff --git a/Documentation/Structs.html b/Documentation/Structs.html deleted file mode 100644 index b7becc1..0000000 --- a/Documentation/Structs.html +++ /dev/null @@ -1,253 +0,0 @@ - - - - Structures Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

Structures

-

The following structures are available globally.

- -
-
-
-
    -
  • -
    - - - - Capable - -
    -
    -
    -
    -
    -
    -

    This class defines the main interface of the Capable framework.

    - - See more -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public struct Capable
    - -
    -
    -
    -
    -
  • -
-
-
- -
-
-
    -
  • -
    - - - - Handicap - -
    -
    -
    -
    -
    -
    -

    Model class that groups a number of CapableFeatures to represent a user’s handicap.

    - - See more -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public struct Handicap : Equatable
    - -
    -
    -
    -
    -
  • -
-
-
- -
-
-
- -
-
- - - diff --git a/Documentation/Structs/Capable.html b/Documentation/Structs/Capable.html deleted file mode 100644 index a73c469..0000000 --- a/Documentation/Structs/Capable.html +++ /dev/null @@ -1,462 +0,0 @@ - - - - Capable Structure Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

Capable

-
-
-
public struct Capable
- -
-
-

This class defines the main interface of the Capable framework.

- -
-
-
-
    -
  • -
    - - - - init(withFeatures:) - -
    -
    -
    -
    -
    -
    -

    Initializes the framework instance with a specified set of features. If no feature was provided, this defaults to all features available on the current platform.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public init(withFeatures features: [CapableFeature] = CapableFeature.allCases)
    - -
    -
    -
    -

    Parameters

    - - - - - - - -
    - - features - - -
    -

    An optional array containing the features of interest. This will default to all features available on the current platform.

    -
    -
    -
    -
    -
    -
  • -
  • -
    - - - - init(withHandicaps:) - -
    -
    -
    -
    -
    -
    -

    Initializes the framework instance with a set of Handicaps.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public init(withHandicaps handicaps: [Handicap])
    - -
    -
    -
    -

    Parameters

    - - - - - - - -
    - - handicaps - - -
    -

    An optional array containing the Handicapss specified by the caller.

    -
    -
    -
    -
    -
    -
  • -
-
-
- -
    -
  • -
    - - - - statusMap - -
    -
    -
    -
    -
    -
    -

    The statusMap property returns a dictionary of all CapableFeatures or Handicaps , that the Capable instance has been initialized with along with their current statuses. This object is compatible with most analytic SDKs such as Fabric Answers, Firebase Analytics, AppCenter Analytics, or HockeyApp. -While most entries can only have a status set to enabled or disabled, the .largerText feature offers the font scale set by the user.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public var statusMap: [String : String] { get }
    - -
    -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Provides information regarding the current status of a provided feature.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public func isFeatureEnabled(feature: CapableFeature) -> Bool
    - -
    -
    -
    -

    Parameters

    - - - - - - - -
    - - feature - - -
    -

    The feature of interest.

    -
    -
    -
    -
    -

    Return Value

    -

    true if the given feature has been enabled, otherwise false.

    -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Provides information regarding the current status of a provided Handicap.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public func isHandicapEnabled(handicapName: String) -> Bool
    - -
    -
    -
    -

    Parameters

    - - - - - - - -
    - - handicapName - - -
    -

    The name of the requested of Handicap.

    -
    -
    -
    -
    -

    Return Value

    -

    true if the given feature has been enabled, otherwise false. Note that the status depends on the Handicap‘s enabledIf value (see HandicapEnabledMode).

    -
    -
    -
    -
  • -
-
-
- -
    -
  • -
    - - - - minLogType - -
    -
    -
    -
    -
    -
    -

    The minimum log level that should be considered when logging messages. Note that the custom ‘onLog’ closure will only be called for messages of this log type or higher. This value defaults to OSLogType.debug.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public static var minLogType: OSLogType { get set }
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - onLog - -
    -
    -
    -
    -
    -
    -

    A custom closure that should be used by the logger for all Capable instances instead of the default os_log implementation.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public static var onLog: (_ message: String, _ logType: OSLogType) -> Void { get set }
    - -
    -
    -
    -

    Parameters

    - - - - - - - - - - - -
    - - message - - -
    -

    The message string that is about to be logged.

    -
    -
    - - logType - - -
    -

    The ‘OSLogType’ of the message.

    -
    -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/Structs/FeatureStatus.html b/Documentation/Structs/FeatureStatus.html deleted file mode 100644 index 6d28dfc..0000000 --- a/Documentation/Structs/FeatureStatus.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - FeatureStatus Structure Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

FeatureStatus

-
-
-
public struct FeatureStatus
- -
-
-

Model class that describes the content of a Capable notification (see Notification.Name.CapableFeatureStatusDidChange)

- -
-
-
-
    -
  • -
    - - - - feature - -
    -
    -
    -
    -
    -
    -

    The feature type.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public private(set) var feature: CapableFeature
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - statusString - -
    -
    -
    -
    -
    -
    -

    The feature’s status: While most features can only have a status set to enabled or disabled, the ‘.largerText` feature offers the font scale set by the user.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public private(set) var statusString: String
    - -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/Structs/Handicap.html b/Documentation/Structs/Handicap.html deleted file mode 100644 index 1bbe514..0000000 --- a/Documentation/Structs/Handicap.html +++ /dev/null @@ -1,249 +0,0 @@ - - - - Handicap Structure Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

Handicap

-
-
-
public struct Handicap : Equatable
- -
-
-

Model class that groups a number of CapableFeatures to represent a user’s handicap.

- -
-
-
-
    -
  • -
    - - - - features - -
    -
    -
    -
    -
    -
    -

    A list of CapableFeatures that are expected to be enabled if a user has this handicap.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public private(set) var features: [CapableFeature]
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - name - -
    -
    -
    -
    -
    -
    -

    The name of the Handicap that can be used to uniquely identify the Handicap. This name is also used inside the status map.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public private(set) var name: String
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - enabledIf - -
    -
    -
    -
    -
    -
    -

    This mode defines whether all features need to be enabled to set the Handicap‘s status to enabled or only one of them.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public private(set) var enabledIf: HandicapEnabledMode
    - -
    -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Initializes a new Handicap object.

    - -
      -
    • features: A list of features that are expected to be enabled if a user has this handicap.
    • -
    • name: The name of the Handicap that can be used to uniquely identify the Handicap. This name is also used inside the status map.
    • -
    • enabledIf: This mode defines whether all features need to be enabled to set the Handicap‘s status to enabled or only one of them.
    • -
    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public init(features: [CapableFeature], name: String, enabledIf: HandicapEnabledMode)
    - -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/Structs/HandicapStatus.html b/Documentation/Structs/HandicapStatus.html deleted file mode 100644 index b1ae901..0000000 --- a/Documentation/Structs/HandicapStatus.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - HandicapStatus Structure Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

HandicapStatus

-
-
-
public struct HandicapStatus
- -
-
-

Model class that describes the content of a Capable notification (see Notification.Name.CapableHandicapStatusDidChange)

- -
-
-
-
    -
  • -
    - - - - handicap - -
    -
    -
    -
    -
    -
    -

    The Handicap that has changed.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public private(set) var handicap: Handicap
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - statusString - -
    -
    -
    -
    -
    -
    -

    The Handicap‘s status (enabled or disabled). Note that the status depends on the Handicap’s enabledIf value (see HandicapEnabledMode).

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public private(set) var statusString: String
    - -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/Typealiases.html b/Documentation/Typealiases.html deleted file mode 100644 index 768e0cb..0000000 --- a/Documentation/Typealiases.html +++ /dev/null @@ -1,271 +0,0 @@ - - - - Type Aliases Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

Type Aliases

-

The following type aliases are available globally.

- -
-
-
-
    -
  • -
    - - - - Color - -
    -
    -
    -
    -
    -
    -

    Typealias used for colors. It maps to UIColor.

    - -
    -
    -
    -
  • -
  • -
    - - - - Font - -
    -
    -
    -
    -
    -
    -

    Typealias used for fonts. It maps to UIFont.

    - -
    -
    -
    -
  • -
  • -
    - - - - Color - -
    -
    -
    -
    -
    -
    -

    Typealias used for colors. It maps to NSColor.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public typealias Color = NSColor
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - Font - -
    -
    -
    -
    -
    -
    -

    Typealias used for fonts. It maps to NSFont.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public typealias Font = NSFont
    - -
    -
    -
    -
    -
  • -
-
-
-
    -
  • -
    - - - - Image - -
    -
    -
    -
    -
    -
    -

    Typealias used for images. It maps to UIImage.

    - -
    -
    -
    -
  • -
  • -
    - - - - Image - -
    -
    -
    -
    -
    -
    -

    Typealias used for image. It maps to NSImage.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public typealias Image = NSImage
    - -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/badge.svg b/Documentation/badge.svg deleted file mode 100644 index f47d948..0000000 --- a/Documentation/badge.svg +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - documentation - - - documentation - - - 98% - - - 98% - - - diff --git a/Documentation/css/highlight.css b/Documentation/css/highlight.css deleted file mode 100644 index d0db0e1..0000000 --- a/Documentation/css/highlight.css +++ /dev/null @@ -1,200 +0,0 @@ -/* Credit to https://gist.github.com/wataru420/2048287 */ -.highlight { - /* Comment */ - /* Error */ - /* Keyword */ - /* Operator */ - /* Comment.Multiline */ - /* Comment.Preproc */ - /* Comment.Single */ - /* Comment.Special */ - /* Generic.Deleted */ - /* Generic.Deleted.Specific */ - /* Generic.Emph */ - /* Generic.Error */ - /* Generic.Heading */ - /* Generic.Inserted */ - /* Generic.Inserted.Specific */ - /* Generic.Output */ - /* Generic.Prompt */ - /* Generic.Strong */ - /* Generic.Subheading */ - /* Generic.Traceback */ - /* Keyword.Constant */ - /* Keyword.Declaration */ - /* Keyword.Pseudo */ - /* Keyword.Reserved */ - /* Keyword.Type */ - /* Literal.Number */ - /* Literal.String */ - /* Name.Attribute */ - /* Name.Builtin */ - /* Name.Class */ - /* Name.Constant */ - /* Name.Entity */ - /* Name.Exception */ - /* Name.Function */ - /* Name.Namespace */ - /* Name.Tag */ - /* Name.Variable */ - /* Operator.Word */ - /* Text.Whitespace */ - /* Literal.Number.Float */ - /* Literal.Number.Hex */ - /* Literal.Number.Integer */ - /* Literal.Number.Oct */ - /* Literal.String.Backtick */ - /* Literal.String.Char */ - /* Literal.String.Doc */ - /* Literal.String.Double */ - /* Literal.String.Escape */ - /* Literal.String.Heredoc */ - /* Literal.String.Interpol */ - /* Literal.String.Other */ - /* Literal.String.Regex */ - /* Literal.String.Single */ - /* Literal.String.Symbol */ - /* Name.Builtin.Pseudo */ - /* Name.Variable.Class */ - /* Name.Variable.Global */ - /* Name.Variable.Instance */ - /* Literal.Number.Integer.Long */ } - .highlight .c { - color: #999988; - font-style: italic; } - .highlight .err { - color: #a61717; - background-color: #e3d2d2; } - .highlight .k { - color: #000000; - font-weight: bold; } - .highlight .o { - color: #000000; - font-weight: bold; } - .highlight .cm { - color: #999988; - font-style: italic; } - .highlight .cp { - color: #999999; - font-weight: bold; } - .highlight .c1 { - color: #999988; - font-style: italic; } - .highlight .cs { - color: #999999; - font-weight: bold; - font-style: italic; } - .highlight .gd { - color: #000000; - background-color: #ffdddd; } - .highlight .gd .x { - color: #000000; - background-color: #ffaaaa; } - .highlight .ge { - color: #000000; - font-style: italic; } - .highlight .gr { - color: #aa0000; } - .highlight .gh { - color: #999999; } - .highlight .gi { - color: #000000; - background-color: #ddffdd; } - .highlight .gi .x { - color: #000000; - background-color: #aaffaa; } - .highlight .go { - color: #888888; } - .highlight .gp { - color: #555555; } - .highlight .gs { - font-weight: bold; } - .highlight .gu { - color: #aaaaaa; } - .highlight .gt { - color: #aa0000; } - .highlight .kc { - color: #000000; - font-weight: bold; } - .highlight .kd { - color: #000000; - font-weight: bold; } - .highlight .kp { - color: #000000; - font-weight: bold; } - .highlight .kr { - color: #000000; - font-weight: bold; } - .highlight .kt { - color: #445588; } - .highlight .m { - color: #009999; } - .highlight .s { - color: #d14; } - .highlight .na { - color: #008080; } - .highlight .nb { - color: #0086B3; } - .highlight .nc { - color: #445588; - font-weight: bold; } - .highlight .no { - color: #008080; } - .highlight .ni { - color: #800080; } - .highlight .ne { - color: #990000; - font-weight: bold; } - .highlight .nf { - color: #990000; } - .highlight .nn { - color: #555555; } - .highlight .nt { - color: #000080; } - .highlight .nv { - color: #008080; } - .highlight .ow { - color: #000000; - font-weight: bold; } - .highlight .w { - color: #bbbbbb; } - .highlight .mf { - color: #009999; } - .highlight .mh { - color: #009999; } - .highlight .mi { - color: #009999; } - .highlight .mo { - color: #009999; } - .highlight .sb { - color: #d14; } - .highlight .sc { - color: #d14; } - .highlight .sd { - color: #d14; } - .highlight .s2 { - color: #d14; } - .highlight .se { - color: #d14; } - .highlight .sh { - color: #d14; } - .highlight .si { - color: #d14; } - .highlight .sx { - color: #d14; } - .highlight .sr { - color: #009926; } - .highlight .s1 { - color: #d14; } - .highlight .ss { - color: #990073; } - .highlight .bp { - color: #999999; } - .highlight .vc { - color: #008080; } - .highlight .vg { - color: #008080; } - .highlight .vi { - color: #008080; } - .highlight .il { - color: #009999; } diff --git a/Documentation/css/jazzy.css b/Documentation/css/jazzy.css deleted file mode 100644 index 103ee29..0000000 --- a/Documentation/css/jazzy.css +++ /dev/null @@ -1,348 +0,0 @@ -html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td { - background: transparent; - border: 0; - margin: 0; - outline: 0; - padding: 0; - vertical-align: baseline; } - -body { - background-color: #f2f2f2; - font-family: Helvetica, freesans, Arial, sans-serif; - font-size: 14px; - -webkit-font-smoothing: subpixel-antialiased; - word-wrap: break-word; } - -h1, h2, h3 { - margin-top: 0.8em; - margin-bottom: 0.3em; - font-weight: 100; - color: black; } - -h1 { - font-size: 2.5em; } - -h2 { - font-size: 2em; - border-bottom: 1px solid #e2e2e2; } - -h4 { - font-size: 13px; - line-height: 1.5; - margin-top: 21px; } - -h5 { - font-size: 1.1em; } - -h6 { - font-size: 1.1em; - color: #777; } - -.section-name { - color: gray; - display: block; - font-family: Helvetica; - font-size: 22px; - font-weight: 100; - margin-bottom: 15px; } - -pre, code { - font: 0.95em Menlo, monospace; - color: #777; - word-wrap: normal; } - -p code, li code { - background-color: #eee; - padding: 2px 4px; - border-radius: 4px; } - -a { - color: #0088cc; - text-decoration: none; } - -ul { - padding-left: 15px; } - -li { - line-height: 1.8em; } - -img { - max-width: 100%; } - -blockquote { - margin-left: 0; - padding: 0 10px; - border-left: 4px solid #ccc; } - -.content-wrapper { - margin: 0 auto; - width: 980px; } - -header { - font-size: 0.85em; - line-height: 26px; - background-color: #414141; - position: fixed; - width: 100%; - z-index: 1; } - header img { - padding-right: 6px; - vertical-align: -4px; - height: 16px; } - header a { - color: #fff; } - header p { - float: left; - color: #999; } - header .header-right { - float: right; - margin-left: 16px; } - -#breadcrumbs { - background-color: #f2f2f2; - height: 27px; - padding-top: 17px; - position: fixed; - width: 100%; - z-index: 1; - margin-top: 26px; } - #breadcrumbs #carat { - height: 10px; - margin: 0 5px; } - -.sidebar { - background-color: #f9f9f9; - border: 1px solid #e2e2e2; - overflow-y: auto; - overflow-x: hidden; - position: fixed; - top: 70px; - bottom: 0; - width: 230px; - word-wrap: normal; } - -.nav-groups { - list-style-type: none; - background: #fff; - padding-left: 0; } - -.nav-group-name { - border-bottom: 1px solid #e2e2e2; - font-size: 1.1em; - font-weight: 100; - padding: 15px 0 15px 20px; } - .nav-group-name > a { - color: #333; } - -.nav-group-tasks { - margin-top: 5px; } - -.nav-group-task { - font-size: 0.9em; - list-style-type: none; - white-space: nowrap; } - .nav-group-task a { - color: #888; } - -.main-content { - background-color: #fff; - border: 1px solid #e2e2e2; - margin-left: 246px; - position: absolute; - overflow: hidden; - padding-bottom: 20px; - top: 70px; - width: 734px; } - .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote { - margin-bottom: 1em; } - .main-content p { - line-height: 1.8em; } - .main-content section .section:first-child { - margin-top: 0; - padding-top: 0; } - .main-content section .task-group-section .task-group:first-of-type { - padding-top: 10px; } - .main-content section .task-group-section .task-group:first-of-type .section-name { - padding-top: 15px; } - .main-content section .heading:before { - content: ""; - display: block; - padding-top: 70px; - margin: -70px 0 0; } - -.section { - padding: 0 25px; } - -.highlight { - background-color: #eee; - padding: 10px 12px; - border: 1px solid #e2e2e2; - border-radius: 4px; - overflow-x: auto; } - -.declaration .highlight { - overflow-x: initial; - padding: 0 40px 40px 0; - margin-bottom: -25px; - background-color: transparent; - border: none; } - -.section-name { - margin: 0; - margin-left: 18px; } - -.task-group-section { - padding-left: 6px; - border-top: 1px solid #e2e2e2; } - -.task-group { - padding-top: 0px; } - -.task-name-container a[name]:before { - content: ""; - display: block; - padding-top: 70px; - margin: -70px 0 0; } - -.item { - padding-top: 8px; - width: 100%; - list-style-type: none; } - .item a[name]:before { - content: ""; - display: block; - padding-top: 70px; - margin: -70px 0 0; } - .item code { - background-color: transparent; - padding: 0; } - .item .token, .item .direct-link { - padding-left: 3px; - margin-left: 15px; - font-size: 11.9px; - transition: all 300ms; } - .item .token-open { - margin-left: 0px; } - .item .discouraged { - text-decoration: line-through; } - .item .declaration-note { - font-size: .85em; - color: gray; - font-style: italic; } - -.pointer-container { - border-bottom: 1px solid #e2e2e2; - left: -23px; - padding-bottom: 13px; - position: relative; - width: 110%; } - -.pointer { - background: #f9f9f9; - border-left: 1px solid #e2e2e2; - border-top: 1px solid #e2e2e2; - height: 12px; - left: 21px; - top: -7px; - -webkit-transform: rotate(45deg); - -moz-transform: rotate(45deg); - -o-transform: rotate(45deg); - transform: rotate(45deg); - position: absolute; - width: 12px; } - -.height-container { - display: none; - left: -25px; - padding: 0 25px; - position: relative; - width: 100%; - overflow: hidden; } - .height-container .section { - background: #f9f9f9; - border-bottom: 1px solid #e2e2e2; - left: -25px; - position: relative; - width: 100%; - padding-top: 10px; - padding-bottom: 5px; } - -.aside, .language { - padding: 6px 12px; - margin: 12px 0; - border-left: 5px solid #dddddd; - overflow-y: hidden; } - .aside .aside-title, .language .aside-title { - font-size: 9px; - letter-spacing: 2px; - text-transform: uppercase; - padding-bottom: 0; - margin: 0; - color: #aaa; - -webkit-user-select: none; } - .aside p:last-child, .language p:last-child { - margin-bottom: 0; } - -.language { - border-left: 5px solid #cde9f4; } - .language .aside-title { - color: #4b8afb; } - -.aside-warning, .aside-deprecated, .aside-unavailable { - border-left: 5px solid #ff6666; } - .aside-warning .aside-title, .aside-deprecated .aside-title, .aside-unavailable .aside-title { - color: #ff0000; } - -.graybox { - border-collapse: collapse; - width: 100%; } - .graybox p { - margin: 0; - word-break: break-word; - min-width: 50px; } - .graybox td { - border: 1px solid #e2e2e2; - padding: 5px 25px 5px 10px; - vertical-align: middle; } - .graybox tr td:first-of-type { - text-align: right; - padding: 7px; - vertical-align: top; - word-break: normal; - width: 40px; } - -.slightly-smaller { - font-size: 0.9em; } - -#footer { - position: relative; - top: 10px; - bottom: 0px; - margin-left: 25px; } - #footer p { - margin: 0; - color: #aaa; - font-size: 0.8em; } - -html.dash header, html.dash #breadcrumbs, html.dash .sidebar { - display: none; } - -html.dash .main-content { - width: 980px; - margin-left: 0; - border: none; - width: 100%; - top: 0; - padding-bottom: 0; } - -html.dash .height-container { - display: block; } - -html.dash .item .token { - margin-left: 0; } - -html.dash .content-wrapper { - width: auto; } - -html.dash #footer { - position: static; } diff --git a/Documentation/docsets/Capable.docset/Contents/Info.plist b/Documentation/docsets/Capable.docset/Contents/Info.plist deleted file mode 100644 index 1cbf832..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Info.plist +++ /dev/null @@ -1,20 +0,0 @@ - - - - - CFBundleIdentifier - com.jazzy.capable - CFBundleName - Capable - DocSetPlatformFamily - capable - isDashDocset - - dashIndexFilePath - index.html - isJavaScriptEnabled - - DashDocSetFamily - dashtoc - - diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Enums.html b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Enums.html deleted file mode 100644 index a5a8e20..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Enums.html +++ /dev/null @@ -1,253 +0,0 @@ - - - - Enumerations Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

Enumerations

-

The following enumerations are available globally.

- -
-
-
-
    -
  • -
    - - - - ConformanceLevel - -
    -
    -
    -
    -
    -
    -

    An enum specifying all WCAG conformance levels.

    - - See more -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public enum ConformanceLevel : Int
    - -
    -
    -
    -
    -
  • -
-
-
-
    -
  • -
    - - - - ImageArea - -
    -
    -
    -
    -
    -
    -

    Undocumented

    - - See more -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public enum ImageArea
    - -
    -
    -
    -
    -
  • -
-
-
-
    -
  • -
    - - - - CapableFeature - -
    -
    -
    -
    -
    -
    -

    An enum specifying all features available on the current platform.

    - - See more -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public enum CapableFeature : String, CaseIterable
    - -
    -
    -
    -
    -
  • -
-
-
-
    -
  • -
    - - - - HandicapEnabledMode - -
    -
    -
    -
    -
    -
    -

    This enum defines several modes which describe whether all features need to be enabled to set the Handicap‘s status to enabled or only one of them.

    - - See more -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public enum HandicapEnabledMode : String
    - -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Enums/CapableFeature.html b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Enums/CapableFeature.html deleted file mode 100644 index 573f8d7..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Enums/CapableFeature.html +++ /dev/null @@ -1,667 +0,0 @@ - - - - CapableFeature Enumeration Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

CapableFeature

-
-
-
public enum CapableFeature : String, CaseIterable
- -
-
-

An enum specifying all features available on the current platform.

- -
-
-
-
    -
  • -
    - - - - assistiveTouch - -
    -
    -
    -
    -
    -
    -

    Menu that helps people with motor skill impairments to do certain actions or gestures by using a single tap.

    - -
    -
    -
    -
  • -
  • -
    - - - - darkerSystemColors - -
    -
    -
    -
    -
    -
    -

    Enhances text contrast.

    - -
    -
    -
    -
  • -
  • -
    - - - - guidedAccess - -
    -
    -
    -
    -
    -
    -

    Restricts access to certain features of a single app to keep the user focused.

    - -
    -
    -
    -
  • -
  • -
    - - - - hearingDevice - -
    -
    -
    -
    -
    -
    -

    Pairing status of a hearing aid.

    - -
    -
    -
    -
  • -
  • -
    - - - - onOffSwitchLabels - -
    -
    -
    -
    -
    -
    -

    Displays on/off labels for UISwitch controls.

    - -
    -
    -
    -
  • -
  • -
    - - - - shakeToUndo - -
    -
    -
    -
    -
    -
    -

    Deletes the last command by shaking the phone.

    - -
    -
    -
    -
  • -
  • -
    - - - - speakScreen - -
    -
    -
    -
    -
    -
    -

    Reads out the content of the current screen.

    - -
    -
    -
    -
  • -
  • -
    - - - - speakSelection - -
    -
    -
    -
    -
    -
    -

    Reads out the selected content.

    - -
    -
    -
    -
  • -
  • -
    - - - - fullKeyboardAccess - -
    -
    -
    -
    -
    -
    -

    Enables users to navigate through items of the screen without having to use a mouse.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case fullKeyboardAccess
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - increaseContrast - -
    -
    -
    -
    -
    -
    -

    Increases contrast to make out text and interface elements.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case increaseContrast
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - closedCaptioning - -
    -
    -
    -
    -
    -
    -

    Displays subtitles when playing videos.

    - -
    -
    -
    -
  • -
  • -
    - - - - grayscale - -
    -
    -
    -
    -
    -
    -

    Makes the display more readable for color blind people by using gray tones instead of colors.

    - -
    -
    -
    -
  • -
  • -
    - - - - monoAudio - -
    -
    -
    -
    -
    -
    -

    Merges stereo audio channels to help users that are hard of hearing or deaf in one ear.

    - -
    -
    -
    -
  • -
  • -
    - - - - videoAutoplay - -
    -
    -
    -
    -
    -
    -

    Allows users who are sensitive to motion to disable automatic video playback.

    - -
    -
    -
    -
  • -
  • -
    - - - - largerText - -
    -
    -
    -
    -
    -
    -

    Increases legibility by making fonts bigger.

    - -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Helps color blind users to differentiate settings differently, e.g. by using shapes rather than colors.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case differentiateWithoutColor
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - invertColors - -
    -
    -
    -
    -
    -
    -

    Helps people with low vision, color blindness, or sensitivity to brightness to read the display content.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case invertColors
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - reduceTransparency - -
    -
    -
    -
    -
    -
    -

    Removes transparency from layers to make them readable for users with visual impairment.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case reduceTransparency
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - switchControl - -
    -
    -
    -
    -
    -
    -

    Allows users with limited mobility to control their device with the help of ability switches and other adaptive devices.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case switchControl
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - boldText - -
    -
    -
    -
    -
    -
    -

    Increases legibility by making fonts heavier.

    - -
    -
    -
    -
  • -
  • -
    - - - - reduceMotion - -
    -
    -
    -
    -
    -
    -

    Reduces animations to help users with motion sickness and epilepsy issues.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case reduceMotion
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - voiceOver - -
    -
    -
    -
    -
    -
    -

    The screen reader available on Apple platforms.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case voiceOver
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - keys(forFeatures:) - -
    -
    -
    -
    -
    -
    -

    Iterates through a given list of feature types and returns an array containing the feature names as strings.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public static func keys(forFeatures features: [CapableFeature]) -> [String]
    - -
    -
    -
    -

    Parameters

    - - - - - - - -
    - - features - - -
    -

    An array containing the feature types of interest.

    -
    -
    -
    -
    -

    Return Value

    -

    An array containing the feature names as strings

    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Enums/ConformanceLevel.html b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Enums/ConformanceLevel.html deleted file mode 100644 index 17d9bbe..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Enums/ConformanceLevel.html +++ /dev/null @@ -1,344 +0,0 @@ - - - - ConformanceLevel Enumeration Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

ConformanceLevel

-
-
-
public enum ConformanceLevel : Int
- -
-
-

An enum specifying all WCAG conformance levels.

- -
-
-
-
    -
  • -
    - - - - A - -
    -
    -
    -
    -
    -
    -

    The minimum level of conformance.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case A = 1
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - AA - -
    -
    -
    -
    -
    -
    -

    The medium level of conformance including success criterias of level A.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case AA = 2
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - AAA - -
    -
    -
    -
    -
    -
    -

    The highest level of conformance including success criterias of level A and AA.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case AAA = 3
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - failed - -
    -
    -
    -
    -
    -
    -

    Indicates that no level of conformance has been reached.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case failed = 0
    - -
    -
    -
    -
    -
  • -
-
-
-
    -
  • - -
    -
    -
    -
    -
    -

    Initializes a ConformanceLevel based on a given contrast ratio and font information used for the text.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public init(contrastRatio: CGFloat, fontSize: CGFloat, isBoldFont: Bool)
    - -
    -
    -
    -

    Parameters

    - - - - - - - - - - - - - - - -
    - - contrastRatio - - -
    -

    The contrast ratio of a text and its background.

    -
    -
    - - fontSize - - -
    -

    The font size of the text.

    -
    -
    - - isBoldFont - - -
    -

    Information regarding the font weight.

    -
    -
    -
    -
    -
    -
  • -
  • -
    - - - - text - -
    -
    -
    -
    -
    -
    -

    The text representation of the conformance level.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public var text: String { get }
    - -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Enums/HandicapEnabledMode.html b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Enums/HandicapEnabledMode.html deleted file mode 100644 index 8e5a18c..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Enums/HandicapEnabledMode.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - HandicapEnabledMode Enumeration Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

HandicapEnabledMode

-
-
-
public enum HandicapEnabledMode : String
- -
-
-

This enum defines several modes which describe whether all features need to be enabled to set the Handicap‘s status to enabled or only one of them.

- -
-
-
-
    -
  • -
    - - - - oneFeatureEnabled - -
    -
    -
    -
    -
    -
    -

    The Handicap‘s status is enabled if one of its features is currently set to enabled.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case oneFeatureEnabled
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - allFeaturesEnabled - -
    -
    -
    -
    -
    -
    -

    The Handicap‘s status is enabled if all its features are currently set to enabled.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case allFeaturesEnabled
    - -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Enums/ImageArea.html b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Enums/ImageArea.html deleted file mode 100644 index 04b2fa6..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Enums/ImageArea.html +++ /dev/null @@ -1,594 +0,0 @@ - - - - ImageArea Enumeration Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

ImageArea

-
-
-
public enum ImageArea
- -
-
-

Undocumented

- -
-
-
-
    -
  • -
    - - - - full - -
    -
    -
    -
    -
    -
    -

    The full image size.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case full
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - bottom - -
    -
    -
    -
    -
    -
    -

    The last vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case bottom
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - bottomCenter - -
    -
    -
    -
    -
    -
    -

    The second horizontal third of the last vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case bottomCenter
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - bottomLeft - -
    -
    -
    -
    -
    -
    -

    The first horizontal third of the last vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case bottomLeft
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - bottomRight - -
    -
    -
    -
    -
    -
    -

    The last horizontal third of the last vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case bottomRight
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - center - -
    -
    -
    -
    -
    -
    -

    The second horizontal third of the second vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case center
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - centerLeft - -
    -
    -
    -
    -
    -
    -

    The first horizontal third of the second vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case centerLeft
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - centerRight - -
    -
    -
    -
    -
    -
    -

    The last horizontal third of the second vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case centerRight
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - custom(rect:) - -
    -
    -
    -
    -
    -
    -

    A custom area of the image defined by a CGRect.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case custom(rect: CGRect)
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - horizontalCenter - -
    -
    -
    -
    -
    -
    -

    The second vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case horizontalCenter
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - left - -
    -
    -
    -
    -
    -
    -

    The first horizontal third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case left
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - right - -
    -
    -
    -
    -
    -
    -

    The last horizontal third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case right
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - top - -
    -
    -
    -
    -
    -
    -

    The first vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case top
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - topCenter - -
    -
    -
    -
    -
    -
    -

    The second horizontal third of the first vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case topCenter
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - topLeft - -
    -
    -
    -
    -
    -
    -

    The first horizontal third of the first vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case topLeft
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - topRight - -
    -
    -
    -
    -
    -
    -

    The last horizontal third of the first vertical third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case topRight
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - verticalCenter - -
    -
    -
    -
    -
    -
    -

    The second horizontal third.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    case verticalCenter
    - -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Extensions.html b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Extensions.html deleted file mode 100644 index d18155c..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Extensions.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - Extensions Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

Extensions

-

The following extensions are available globally.

- -
-
-
-
    -
  • -
    - - - - Color - -
    -
    -
    -
    -
    -
    -

    Extension that adds functionality for calculating WCAG compliant high contrast colors.

    - - See more -
    -
    -

    Declaration

    -
    -

    Swift

    -
    extension Color
    - -
    -
    -
    -
    -
  • -
-
-
- -
-
-
    -
  • -
    - - - - UIFont - -
    -
    -
    -
    -
    -
    -

    Extension that adds functionality for creating scalable UIFont objects.

    - - See more -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Extensions/Color.html b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Extensions/Color.html deleted file mode 100644 index c1135f8..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Extensions/Color.html +++ /dev/null @@ -1,608 +0,0 @@ - - - - Color Extension Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

Color

-
-
-
extension Color
- -
-
-

Extension that adds functionality for calculating WCAG compliant high contrast colors.

- -
-
-
-
    -
  • - -
    -
    -
    -
    -
    -

    Calculates the color ratio for a text color on a background color.

    -
    -

    Note

    -

    Semi-transparent text colors will be blended with the background color. However, for background colors, the alpha component is ignored.

    - -
    -
    -

    Warning

    -

    This function will also return nil if any input color is not convertable to the sRGB color space.

    - -
    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public class func getContrastRatio(forTextColor textColor: Color, onBackgroundColor backgroundColor: Color) -> CGFloat?
    - -
    -
    -
    -

    Parameters

    - - - - - - - - - - - -
    - - textColor - - -
    -

    The text color.

    -
    -
    - - backgroundColor - - -
    -

    The background color.

    -
    -
    -
    -
    -

    Return Value

    -

    The contrast ratio for a given pair of colors.

    -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Returns the text color with the highest contrast (black or white) for a given background color.

    -
    -

    Note

    -

    Semi-transparent text colors will be blended with the background color. However, for background colors, the alpha component is ignored.

    - -
    -
    -

    Warning

    -

    This function will also return nil if any input color is not convertable to the sRGB color space.

    - -
    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public class func getTextColor(onBackgroundColor backgroundColor: Color) -> Color?
    - -
    -
    -
    -

    Parameters

    - - - - - - - -
    - - backgroundColor - - -
    -

    The background color.

    -
    -
    -
    -
    -

    Return Value

    -

    A color that has the highest contrast with the given background color.

    -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Calculates the contrast ratio of a given list of text colors and a background color. The first color that conforms to the conformance level defined gets returned. The default conformance level is .AA.

    -
    -

    Note

    -

    Semi-transparent text colors will be blended with the background color. However, for background colors, the alpha component is ignored.

    - -
    -
    -

    Warning

    -

    This function will also return nil if any input color is not convertable to the sRGB color space.

    - -
    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public class func getTextColor(fromColors colors: [Color], withFont font: Font, onBackgroundColor backgroundColor: Color, conformanceLevel: ConformanceLevel = .AA) -> Color?
    - -
    -
    -
    -

    Parameters

    - - - - - - - - - - - - - - - - - - - -
    - - colors - - -
    -

    A list of possible text colors.

    -
    -
    - - font - - -
    -

    The font used for the text.

    -
    -
    - - backgroundColor - - -
    -

    The background color that the text should be displayed on.

    -
    -
    - - conformanceLevel - - -
    -

    The conformance level that needs to be passed when calculating the contrast ratio. The default conformance level is .AA.

    -
    -
    -
    -
    -

    Return Value

    -

    The first color that conforms to the conformance level defined or nil if non of the colors provided passed.

    -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Returns the text color with the highest contrast (black or white) for a specific area of given background image.

    -
  • backgroundImage: The background image.
  • -
  • imageArea: The area of the image that is used as the text background. Defaults to .full.

  • -
    -

    Note

    -

    For the background image, the alpha component is ignored.

    - -
    -
    -

    Warning

    -

    This function will also return nil if the image is corrupted.

    - -
    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public class func getTextColor(onBackgroundImage image: Image, imageArea: ImageArea = .full) -> Color?
    - -
    -
    -
    -

    Return Value

    -

    A color that has the highest contrast with the given background image.

    -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Calculates the contrast ratio of a given list of text colors and a specific area of given background image. The first color that conforms to the conformance level defined gets returned. The default conformance level is .AA.

    -
  • colors: A list of possible text colors.
  • -
  • font: The font used for the text.
  • -
  • backgroundImage: The background image that the text should be displayed on.
  • -
  • imageArea: The area of the image that is used as the text background. Defaults to .full.
  • -
  • conformanceLevel: The conformance level that needs to be passed when calculating the contrast ratio. The default conformance level is .AA.

  • -
    -

    Note

    -

    Semi-transparent text colors will be blended with the background color. However, for the background image, the alpha component is ignored.

    - -
    -
    -

    Warning

    -

    This function will also return nil if any input color is not convertable to the sRGB color space.

    - -
    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public class func getTextColor(fromColors colors: [Color], withFont font: Font, onBackgroundImage image: Image, imageArea: ImageArea = .full, conformanceLevel: ConformanceLevel = .AA) -> Color?
    - -
    -
    -
    -

    Return Value

    -

    The first color that conforms to the conformance level defined or nil if non of the colors provided passed.

    -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Returns the background color with the highest contrast (black or white) for a given text color.

    -
    -

    Note

    -

    Semi-transparent text colors will be blended with the background color. However, for background colors, the alpha component is ignored.

    - -
    -
    -

    Warning

    -

    This function will also return nil if any input color is not convertable to the sRGB color space.

    - -
    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public class func getBackgroundColor(forTextColor textColor: Color) -> Color?
    - -
    -
    -
    -

    Parameters

    - - - - - - - -
    - - textColor - - -
    -

    The textColor color.

    -
    -
    -
    -
    -

    Return Value

    -

    A color that has the highest contrast with the given text color.

    -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Calculates the contrast ratio of a given list of background colors and a text color. The first color that conforms to the conformance level defined gets returned. The default conformance level is .AA.

    -
    -

    Note

    -

    Semi-transparent text colors will be blended with the background color. However, for background colors, the alpha component is ignored.

    - -
    -
    -

    Warning

    -

    This function will also return nil if any input color is not convertable to the sRGB color space.

    - -
    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public class func getBackgroundColor(fromColors colors: [Color], forTextColor textColor: Color, withFont font: Font, conformanceLevel: ConformanceLevel = .AA) -> Color?
    - -
    -
    -
    -

    Parameters

    - - - - - - - - - - - - - - - - - - - -
    - - colors - - -
    -

    A list of possible background colors.

    -
    -
    - - textColor - - -
    -

    The text color that should be used.

    -
    -
    - - font - - -
    -

    The font used for the text.

    -
    -
    - - conformanceLevel - - -
    -

    The conformance level that needs to be passed when calculating the contrast ratio. The default conformance level is .AA.

    -
    -
    -
    -
    -

    Return Value

    -

    The first color that conforms to the conformance level defined or nil if non of the colors provided passed.

    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Extensions/Notification.html b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Extensions/Notification.html deleted file mode 100644 index 08dc91e..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Extensions/Notification.html +++ /dev/null @@ -1,156 +0,0 @@ - - - - Notification Extension Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

Notification

- -
-
-
-
    -
  • -
    - - - - Name - -
    -
    -
    -
    -
    -
    -

    Extension that defines notification names provided by the Capable framework.

    - - See more -
    -
    -

    Declaration

    -
    -

    Swift

    -
    extension Notification.Name
    - -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Extensions/Notification/Name.html b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Extensions/Notification/Name.html deleted file mode 100644 index 17e2d75..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Extensions/Notification/Name.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - Name Extension Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

Name

-
-
-
extension Notification.Name
- -
-
-

Extension that defines notification names provided by the Capable framework.

- -
-
-
-
    -
  • - -
    -
    -
    -
    -
    -

    Name of the notification that gets fired whenever an observed accessibility feature status changes.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public static let CapableFeatureStatusDidChange: Notification.Name
    - -
    -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Name of the notification that gets fired whenever an observed Handicap status changes.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public static let CapableHandicapStatusDidChange: Notification.Name
    - -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Extensions/UIFont.html b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Extensions/UIFont.html deleted file mode 100644 index 2df44b6..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Extensions/UIFont.html +++ /dev/null @@ -1,224 +0,0 @@ - - - - UIFont Extension Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

UIFont

-

Extension that adds functionality for creating scalable UIFont objects.

- -
-
-
- -
-
-
- -
-
- - - diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Structs.html b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Structs.html deleted file mode 100644 index b7becc1..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Structs.html +++ /dev/null @@ -1,253 +0,0 @@ - - - - Structures Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

Structures

-

The following structures are available globally.

- -
-
-
-
    -
  • -
    - - - - Capable - -
    -
    -
    -
    -
    -
    -

    This class defines the main interface of the Capable framework.

    - - See more -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public struct Capable
    - -
    -
    -
    -
    -
  • -
-
-
- -
-
-
    -
  • -
    - - - - Handicap - -
    -
    -
    -
    -
    -
    -

    Model class that groups a number of CapableFeatures to represent a user’s handicap.

    - - See more -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public struct Handicap : Equatable
    - -
    -
    -
    -
    -
  • -
-
-
- -
-
-
- -
-
- - - diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Structs/Capable.html b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Structs/Capable.html deleted file mode 100644 index a73c469..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Structs/Capable.html +++ /dev/null @@ -1,462 +0,0 @@ - - - - Capable Structure Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

Capable

-
-
-
public struct Capable
- -
-
-

This class defines the main interface of the Capable framework.

- -
-
-
-
    -
  • -
    - - - - init(withFeatures:) - -
    -
    -
    -
    -
    -
    -

    Initializes the framework instance with a specified set of features. If no feature was provided, this defaults to all features available on the current platform.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public init(withFeatures features: [CapableFeature] = CapableFeature.allCases)
    - -
    -
    -
    -

    Parameters

    - - - - - - - -
    - - features - - -
    -

    An optional array containing the features of interest. This will default to all features available on the current platform.

    -
    -
    -
    -
    -
    -
  • -
  • -
    - - - - init(withHandicaps:) - -
    -
    -
    -
    -
    -
    -

    Initializes the framework instance with a set of Handicaps.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public init(withHandicaps handicaps: [Handicap])
    - -
    -
    -
    -

    Parameters

    - - - - - - - -
    - - handicaps - - -
    -

    An optional array containing the Handicapss specified by the caller.

    -
    -
    -
    -
    -
    -
  • -
-
-
- -
    -
  • -
    - - - - statusMap - -
    -
    -
    -
    -
    -
    -

    The statusMap property returns a dictionary of all CapableFeatures or Handicaps , that the Capable instance has been initialized with along with their current statuses. This object is compatible with most analytic SDKs such as Fabric Answers, Firebase Analytics, AppCenter Analytics, or HockeyApp. -While most entries can only have a status set to enabled or disabled, the .largerText feature offers the font scale set by the user.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public var statusMap: [String : String] { get }
    - -
    -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Provides information regarding the current status of a provided feature.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public func isFeatureEnabled(feature: CapableFeature) -> Bool
    - -
    -
    -
    -

    Parameters

    - - - - - - - -
    - - feature - - -
    -

    The feature of interest.

    -
    -
    -
    -
    -

    Return Value

    -

    true if the given feature has been enabled, otherwise false.

    -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Provides information regarding the current status of a provided Handicap.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public func isHandicapEnabled(handicapName: String) -> Bool
    - -
    -
    -
    -

    Parameters

    - - - - - - - -
    - - handicapName - - -
    -

    The name of the requested of Handicap.

    -
    -
    -
    -
    -

    Return Value

    -

    true if the given feature has been enabled, otherwise false. Note that the status depends on the Handicap‘s enabledIf value (see HandicapEnabledMode).

    -
    -
    -
    -
  • -
-
-
- -
    -
  • -
    - - - - minLogType - -
    -
    -
    -
    -
    -
    -

    The minimum log level that should be considered when logging messages. Note that the custom ‘onLog’ closure will only be called for messages of this log type or higher. This value defaults to OSLogType.debug.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public static var minLogType: OSLogType { get set }
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - onLog - -
    -
    -
    -
    -
    -
    -

    A custom closure that should be used by the logger for all Capable instances instead of the default os_log implementation.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public static var onLog: (_ message: String, _ logType: OSLogType) -> Void { get set }
    - -
    -
    -
    -

    Parameters

    - - - - - - - - - - - -
    - - message - - -
    -

    The message string that is about to be logged.

    -
    -
    - - logType - - -
    -

    The ‘OSLogType’ of the message.

    -
    -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Structs/FeatureStatus.html b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Structs/FeatureStatus.html deleted file mode 100644 index 6d28dfc..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Structs/FeatureStatus.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - FeatureStatus Structure Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

FeatureStatus

-
-
-
public struct FeatureStatus
- -
-
-

Model class that describes the content of a Capable notification (see Notification.Name.CapableFeatureStatusDidChange)

- -
-
-
-
    -
  • -
    - - - - feature - -
    -
    -
    -
    -
    -
    -

    The feature type.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public private(set) var feature: CapableFeature
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - statusString - -
    -
    -
    -
    -
    -
    -

    The feature’s status: While most features can only have a status set to enabled or disabled, the ‘.largerText` feature offers the font scale set by the user.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public private(set) var statusString: String
    - -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Structs/Handicap.html b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Structs/Handicap.html deleted file mode 100644 index 1bbe514..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Structs/Handicap.html +++ /dev/null @@ -1,249 +0,0 @@ - - - - Handicap Structure Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

Handicap

-
-
-
public struct Handicap : Equatable
- -
-
-

Model class that groups a number of CapableFeatures to represent a user’s handicap.

- -
-
-
-
    -
  • -
    - - - - features - -
    -
    -
    -
    -
    -
    -

    A list of CapableFeatures that are expected to be enabled if a user has this handicap.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public private(set) var features: [CapableFeature]
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - name - -
    -
    -
    -
    -
    -
    -

    The name of the Handicap that can be used to uniquely identify the Handicap. This name is also used inside the status map.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public private(set) var name: String
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - enabledIf - -
    -
    -
    -
    -
    -
    -

    This mode defines whether all features need to be enabled to set the Handicap‘s status to enabled or only one of them.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public private(set) var enabledIf: HandicapEnabledMode
    - -
    -
    -
    -
    -
  • -
  • - -
    -
    -
    -
    -
    -

    Initializes a new Handicap object.

    - -
      -
    • features: A list of features that are expected to be enabled if a user has this handicap.
    • -
    • name: The name of the Handicap that can be used to uniquely identify the Handicap. This name is also used inside the status map.
    • -
    • enabledIf: This mode defines whether all features need to be enabled to set the Handicap‘s status to enabled or only one of them.
    • -
    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public init(features: [CapableFeature], name: String, enabledIf: HandicapEnabledMode)
    - -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Structs/HandicapStatus.html b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Structs/HandicapStatus.html deleted file mode 100644 index b1ae901..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Structs/HandicapStatus.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - HandicapStatus Structure Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

HandicapStatus

-
-
-
public struct HandicapStatus
- -
-
-

Model class that describes the content of a Capable notification (see Notification.Name.CapableHandicapStatusDidChange)

- -
-
-
-
    -
  • -
    - - - - handicap - -
    -
    -
    -
    -
    -
    -

    The Handicap that has changed.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public private(set) var handicap: Handicap
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - statusString - -
    -
    -
    -
    -
    -
    -

    The Handicap‘s status (enabled or disabled). Note that the status depends on the Handicap’s enabledIf value (see HandicapEnabledMode).

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public private(set) var statusString: String
    - -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Typealiases.html b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Typealiases.html deleted file mode 100644 index 768e0cb..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/Typealiases.html +++ /dev/null @@ -1,271 +0,0 @@ - - - - Type Aliases Reference - - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
-

Type Aliases

-

The following type aliases are available globally.

- -
-
-
-
    -
  • -
    - - - - Color - -
    -
    -
    -
    -
    -
    -

    Typealias used for colors. It maps to UIColor.

    - -
    -
    -
    -
  • -
  • -
    - - - - Font - -
    -
    -
    -
    -
    -
    -

    Typealias used for fonts. It maps to UIFont.

    - -
    -
    -
    -
  • -
  • -
    - - - - Color - -
    -
    -
    -
    -
    -
    -

    Typealias used for colors. It maps to NSColor.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public typealias Color = NSColor
    - -
    -
    -
    -
    -
  • -
  • -
    - - - - Font - -
    -
    -
    -
    -
    -
    -

    Typealias used for fonts. It maps to NSFont.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public typealias Font = NSFont
    - -
    -
    -
    -
    -
  • -
-
-
-
    -
  • -
    - - - - Image - -
    -
    -
    -
    -
    -
    -

    Typealias used for images. It maps to UIImage.

    - -
    -
    -
    -
  • -
  • -
    - - - - Image - -
    -
    -
    -
    -
    -
    -

    Typealias used for image. It maps to NSImage.

    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public typealias Image = NSImage
    - -
    -
    -
    -
    -
  • -
-
-
-
- -
-
- - - diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/css/highlight.css b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/css/highlight.css deleted file mode 100644 index d0db0e1..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/css/highlight.css +++ /dev/null @@ -1,200 +0,0 @@ -/* Credit to https://gist.github.com/wataru420/2048287 */ -.highlight { - /* Comment */ - /* Error */ - /* Keyword */ - /* Operator */ - /* Comment.Multiline */ - /* Comment.Preproc */ - /* Comment.Single */ - /* Comment.Special */ - /* Generic.Deleted */ - /* Generic.Deleted.Specific */ - /* Generic.Emph */ - /* Generic.Error */ - /* Generic.Heading */ - /* Generic.Inserted */ - /* Generic.Inserted.Specific */ - /* Generic.Output */ - /* Generic.Prompt */ - /* Generic.Strong */ - /* Generic.Subheading */ - /* Generic.Traceback */ - /* Keyword.Constant */ - /* Keyword.Declaration */ - /* Keyword.Pseudo */ - /* Keyword.Reserved */ - /* Keyword.Type */ - /* Literal.Number */ - /* Literal.String */ - /* Name.Attribute */ - /* Name.Builtin */ - /* Name.Class */ - /* Name.Constant */ - /* Name.Entity */ - /* Name.Exception */ - /* Name.Function */ - /* Name.Namespace */ - /* Name.Tag */ - /* Name.Variable */ - /* Operator.Word */ - /* Text.Whitespace */ - /* Literal.Number.Float */ - /* Literal.Number.Hex */ - /* Literal.Number.Integer */ - /* Literal.Number.Oct */ - /* Literal.String.Backtick */ - /* Literal.String.Char */ - /* Literal.String.Doc */ - /* Literal.String.Double */ - /* Literal.String.Escape */ - /* Literal.String.Heredoc */ - /* Literal.String.Interpol */ - /* Literal.String.Other */ - /* Literal.String.Regex */ - /* Literal.String.Single */ - /* Literal.String.Symbol */ - /* Name.Builtin.Pseudo */ - /* Name.Variable.Class */ - /* Name.Variable.Global */ - /* Name.Variable.Instance */ - /* Literal.Number.Integer.Long */ } - .highlight .c { - color: #999988; - font-style: italic; } - .highlight .err { - color: #a61717; - background-color: #e3d2d2; } - .highlight .k { - color: #000000; - font-weight: bold; } - .highlight .o { - color: #000000; - font-weight: bold; } - .highlight .cm { - color: #999988; - font-style: italic; } - .highlight .cp { - color: #999999; - font-weight: bold; } - .highlight .c1 { - color: #999988; - font-style: italic; } - .highlight .cs { - color: #999999; - font-weight: bold; - font-style: italic; } - .highlight .gd { - color: #000000; - background-color: #ffdddd; } - .highlight .gd .x { - color: #000000; - background-color: #ffaaaa; } - .highlight .ge { - color: #000000; - font-style: italic; } - .highlight .gr { - color: #aa0000; } - .highlight .gh { - color: #999999; } - .highlight .gi { - color: #000000; - background-color: #ddffdd; } - .highlight .gi .x { - color: #000000; - background-color: #aaffaa; } - .highlight .go { - color: #888888; } - .highlight .gp { - color: #555555; } - .highlight .gs { - font-weight: bold; } - .highlight .gu { - color: #aaaaaa; } - .highlight .gt { - color: #aa0000; } - .highlight .kc { - color: #000000; - font-weight: bold; } - .highlight .kd { - color: #000000; - font-weight: bold; } - .highlight .kp { - color: #000000; - font-weight: bold; } - .highlight .kr { - color: #000000; - font-weight: bold; } - .highlight .kt { - color: #445588; } - .highlight .m { - color: #009999; } - .highlight .s { - color: #d14; } - .highlight .na { - color: #008080; } - .highlight .nb { - color: #0086B3; } - .highlight .nc { - color: #445588; - font-weight: bold; } - .highlight .no { - color: #008080; } - .highlight .ni { - color: #800080; } - .highlight .ne { - color: #990000; - font-weight: bold; } - .highlight .nf { - color: #990000; } - .highlight .nn { - color: #555555; } - .highlight .nt { - color: #000080; } - .highlight .nv { - color: #008080; } - .highlight .ow { - color: #000000; - font-weight: bold; } - .highlight .w { - color: #bbbbbb; } - .highlight .mf { - color: #009999; } - .highlight .mh { - color: #009999; } - .highlight .mi { - color: #009999; } - .highlight .mo { - color: #009999; } - .highlight .sb { - color: #d14; } - .highlight .sc { - color: #d14; } - .highlight .sd { - color: #d14; } - .highlight .s2 { - color: #d14; } - .highlight .se { - color: #d14; } - .highlight .sh { - color: #d14; } - .highlight .si { - color: #d14; } - .highlight .sx { - color: #d14; } - .highlight .sr { - color: #009926; } - .highlight .s1 { - color: #d14; } - .highlight .ss { - color: #990073; } - .highlight .bp { - color: #999999; } - .highlight .vc { - color: #008080; } - .highlight .vg { - color: #008080; } - .highlight .vi { - color: #008080; } - .highlight .il { - color: #009999; } diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/css/jazzy.css b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/css/jazzy.css deleted file mode 100644 index 103ee29..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/css/jazzy.css +++ /dev/null @@ -1,348 +0,0 @@ -html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td { - background: transparent; - border: 0; - margin: 0; - outline: 0; - padding: 0; - vertical-align: baseline; } - -body { - background-color: #f2f2f2; - font-family: Helvetica, freesans, Arial, sans-serif; - font-size: 14px; - -webkit-font-smoothing: subpixel-antialiased; - word-wrap: break-word; } - -h1, h2, h3 { - margin-top: 0.8em; - margin-bottom: 0.3em; - font-weight: 100; - color: black; } - -h1 { - font-size: 2.5em; } - -h2 { - font-size: 2em; - border-bottom: 1px solid #e2e2e2; } - -h4 { - font-size: 13px; - line-height: 1.5; - margin-top: 21px; } - -h5 { - font-size: 1.1em; } - -h6 { - font-size: 1.1em; - color: #777; } - -.section-name { - color: gray; - display: block; - font-family: Helvetica; - font-size: 22px; - font-weight: 100; - margin-bottom: 15px; } - -pre, code { - font: 0.95em Menlo, monospace; - color: #777; - word-wrap: normal; } - -p code, li code { - background-color: #eee; - padding: 2px 4px; - border-radius: 4px; } - -a { - color: #0088cc; - text-decoration: none; } - -ul { - padding-left: 15px; } - -li { - line-height: 1.8em; } - -img { - max-width: 100%; } - -blockquote { - margin-left: 0; - padding: 0 10px; - border-left: 4px solid #ccc; } - -.content-wrapper { - margin: 0 auto; - width: 980px; } - -header { - font-size: 0.85em; - line-height: 26px; - background-color: #414141; - position: fixed; - width: 100%; - z-index: 1; } - header img { - padding-right: 6px; - vertical-align: -4px; - height: 16px; } - header a { - color: #fff; } - header p { - float: left; - color: #999; } - header .header-right { - float: right; - margin-left: 16px; } - -#breadcrumbs { - background-color: #f2f2f2; - height: 27px; - padding-top: 17px; - position: fixed; - width: 100%; - z-index: 1; - margin-top: 26px; } - #breadcrumbs #carat { - height: 10px; - margin: 0 5px; } - -.sidebar { - background-color: #f9f9f9; - border: 1px solid #e2e2e2; - overflow-y: auto; - overflow-x: hidden; - position: fixed; - top: 70px; - bottom: 0; - width: 230px; - word-wrap: normal; } - -.nav-groups { - list-style-type: none; - background: #fff; - padding-left: 0; } - -.nav-group-name { - border-bottom: 1px solid #e2e2e2; - font-size: 1.1em; - font-weight: 100; - padding: 15px 0 15px 20px; } - .nav-group-name > a { - color: #333; } - -.nav-group-tasks { - margin-top: 5px; } - -.nav-group-task { - font-size: 0.9em; - list-style-type: none; - white-space: nowrap; } - .nav-group-task a { - color: #888; } - -.main-content { - background-color: #fff; - border: 1px solid #e2e2e2; - margin-left: 246px; - position: absolute; - overflow: hidden; - padding-bottom: 20px; - top: 70px; - width: 734px; } - .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote { - margin-bottom: 1em; } - .main-content p { - line-height: 1.8em; } - .main-content section .section:first-child { - margin-top: 0; - padding-top: 0; } - .main-content section .task-group-section .task-group:first-of-type { - padding-top: 10px; } - .main-content section .task-group-section .task-group:first-of-type .section-name { - padding-top: 15px; } - .main-content section .heading:before { - content: ""; - display: block; - padding-top: 70px; - margin: -70px 0 0; } - -.section { - padding: 0 25px; } - -.highlight { - background-color: #eee; - padding: 10px 12px; - border: 1px solid #e2e2e2; - border-radius: 4px; - overflow-x: auto; } - -.declaration .highlight { - overflow-x: initial; - padding: 0 40px 40px 0; - margin-bottom: -25px; - background-color: transparent; - border: none; } - -.section-name { - margin: 0; - margin-left: 18px; } - -.task-group-section { - padding-left: 6px; - border-top: 1px solid #e2e2e2; } - -.task-group { - padding-top: 0px; } - -.task-name-container a[name]:before { - content: ""; - display: block; - padding-top: 70px; - margin: -70px 0 0; } - -.item { - padding-top: 8px; - width: 100%; - list-style-type: none; } - .item a[name]:before { - content: ""; - display: block; - padding-top: 70px; - margin: -70px 0 0; } - .item code { - background-color: transparent; - padding: 0; } - .item .token, .item .direct-link { - padding-left: 3px; - margin-left: 15px; - font-size: 11.9px; - transition: all 300ms; } - .item .token-open { - margin-left: 0px; } - .item .discouraged { - text-decoration: line-through; } - .item .declaration-note { - font-size: .85em; - color: gray; - font-style: italic; } - -.pointer-container { - border-bottom: 1px solid #e2e2e2; - left: -23px; - padding-bottom: 13px; - position: relative; - width: 110%; } - -.pointer { - background: #f9f9f9; - border-left: 1px solid #e2e2e2; - border-top: 1px solid #e2e2e2; - height: 12px; - left: 21px; - top: -7px; - -webkit-transform: rotate(45deg); - -moz-transform: rotate(45deg); - -o-transform: rotate(45deg); - transform: rotate(45deg); - position: absolute; - width: 12px; } - -.height-container { - display: none; - left: -25px; - padding: 0 25px; - position: relative; - width: 100%; - overflow: hidden; } - .height-container .section { - background: #f9f9f9; - border-bottom: 1px solid #e2e2e2; - left: -25px; - position: relative; - width: 100%; - padding-top: 10px; - padding-bottom: 5px; } - -.aside, .language { - padding: 6px 12px; - margin: 12px 0; - border-left: 5px solid #dddddd; - overflow-y: hidden; } - .aside .aside-title, .language .aside-title { - font-size: 9px; - letter-spacing: 2px; - text-transform: uppercase; - padding-bottom: 0; - margin: 0; - color: #aaa; - -webkit-user-select: none; } - .aside p:last-child, .language p:last-child { - margin-bottom: 0; } - -.language { - border-left: 5px solid #cde9f4; } - .language .aside-title { - color: #4b8afb; } - -.aside-warning, .aside-deprecated, .aside-unavailable { - border-left: 5px solid #ff6666; } - .aside-warning .aside-title, .aside-deprecated .aside-title, .aside-unavailable .aside-title { - color: #ff0000; } - -.graybox { - border-collapse: collapse; - width: 100%; } - .graybox p { - margin: 0; - word-break: break-word; - min-width: 50px; } - .graybox td { - border: 1px solid #e2e2e2; - padding: 5px 25px 5px 10px; - vertical-align: middle; } - .graybox tr td:first-of-type { - text-align: right; - padding: 7px; - vertical-align: top; - word-break: normal; - width: 40px; } - -.slightly-smaller { - font-size: 0.9em; } - -#footer { - position: relative; - top: 10px; - bottom: 0px; - margin-left: 25px; } - #footer p { - margin: 0; - color: #aaa; - font-size: 0.8em; } - -html.dash header, html.dash #breadcrumbs, html.dash .sidebar { - display: none; } - -html.dash .main-content { - width: 980px; - margin-left: 0; - border: none; - width: 100%; - top: 0; - padding-bottom: 0; } - -html.dash .height-container { - display: block; } - -html.dash .item .token { - margin-left: 0; } - -html.dash .content-wrapper { - width: auto; } - -html.dash #footer { - position: static; } diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/img/carat.png b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/img/carat.png deleted file mode 100755 index 29d2f7f..0000000 Binary files a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/img/carat.png and /dev/null differ diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/img/dash.png b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/img/dash.png deleted file mode 100755 index 6f694c7..0000000 Binary files a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/img/dash.png and /dev/null differ diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/img/gh.png b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/img/gh.png deleted file mode 100755 index 628da97..0000000 Binary files a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/img/gh.png and /dev/null differ diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/index.html b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/index.html deleted file mode 100644 index 1862b85..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/index.html +++ /dev/null @@ -1,723 +0,0 @@ - - - - Capable Reference - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
- -

-

- -
- -

Awesome -Build Status -Swift -Platforms -Carthage compatible -Cocoapods compatible -SPM -Documentation -codecov -Twitter

-

Accessibility for iOS, macOS, tvOS, and watchOS

- -

Check out the Example.xcworkspace to get a quick overview:

- -

Example project overview

-

1) Research: Do I need to care about accessibility?

- - - -

Have you ever thought about adopting accessibility features within you apps to gain your user base instead of spending a lot of time implementing features no-one really ever asked for?

- -

Most of us did, however there has never been an easy way to tell if anyone benefits from that. Adjusting layouts to be usable for people with low vision can be quite complex in some situations and tracking the user’s accessibility settings adds a lot of boilerplate code to your app.

- -

What if there was a simple way to figure out if there’s a real need to support accessibility right now. Or even better, which disability exists most across your user base.

-

2) React: Improve problematic screens

- - - -

Once you’ve figured out that users with specific handicaps get stuck at a certain stage, you can make use of various Capable APIs to enable/disable accessibility support based on the user’s accessibility settings or improve texts and colors used within your apps. Go back to step 1 to proof that the work helped users to succeed using your app.

-

3) Fault diagnosis

- -

Each Capable feature is backed by the built-in logging system, which will keep you in the loop about what might have been going wrong. Even if you are using your own logging solution, the Capable logger is fully compatible with it!

- - -

Documentation

- -

Capable offers a whole lot of features along with a bunch of configurations. To find more about how to use them inside the documentation section.

-

Installation

- -

There are currently four different ways to integrate Capable into your apps.

-

CocoaPods

-
use_frameworks!
-
-target 'MyApp' do
-
-  # all features + color and font extensions
-  pod 'Capable'
-
-  # all features, but exclude color and font extensions
-  pod 'Capable/Features'
-
-  # color extensions only
-  pod 'Capable/Colors'
-
-  # font extensions only
-  pod 'Capable/Fonts'
-end
-
-

Carthage

-
github "chrs1885/Capable"
-
-

Swift Package Manager

-
dependencies: [
-    .package(url: "https://github.com/chrs1885/Capable.git", from: "1.1.0")
-]
-
-

Manually

- -

Simply drop Capable.xcodeproj into your project. Also make sure to add -Capable.framework to your app’s embedded frameworks found in the General tab of your main project.

-

Usage

-

Register for (specific) accessibility settings

- -

Firstly, you need to import the Capable framework in your class by adding the following import statement:

-
import Capable
-
- -

There are two different ways to initialize the framework instance. You can either set it up to consider all accessibility features

-
let capable = Capable()
-
- -

or by passing in only specific feature names

-
let capable = Capable(withFeatures: [.largerText, .boldText, .shakeToUndo])
-
- -

You can find a list of all accessibility features available on each platform in the accessibility feature overview section.

- -

-

Get accessibility status

- -

If you are interested in a specific accessibility feature, you can retrieve its current status as follows:

-
let capable = Capable()
-let isVoiceOverEnabled: Bool = capable.isFeatureEnable(feature: .voiceOver)
-
- -

To get a dictionary of all features, that the Capable instance has been initialized with you can use:

-
let capable = Capable()
-let statusMap = capable.statusMap
-
- -

This will return each feature name (key) along with its current value as described in the accessibility feature overview section.

- -

-

Handicaps - grouped accessibility features

- -

You can also group accessibility features to represent a specific handicap:

-
// Define a set of features that represent a handicap
-let features: [CapableFeature] = [.voiceOver, .speakScreen, .speakSelection]
-
-// Use the Handicap object to group them
-let blindness = Handicap(features: features, name: "Blindness", enabledIf: .allFeaturesEnabled)
-
-// Initialize the framework instance by providing the Handicap
-let capable = Capable(withHandicaps: [blindness])
-
- -

The value of the name parameter will be used inside the statusMap provided by the Capable framework instance. Based on the value of enabledIf, you can specify if all features need to be set to enabled in order to set the Handicap to enabled as well.

- -

Just like accessibility features, the Handicap type works great with notifications.

- -

-

Send accessibility status

- -

The statusMap object is compatible with most analytic SDK APIs. Here’s a quick example of how to send your data along with user properties or custom events.

-
func sendMetrics() {
-    let statusMap = self.capable.statusMap
-    let eventName = "Capable features received"
-
-    // App Center
-    MSAnalytics.trackEvent(eventName, withProperties: statusMap)
-
-    // Firebase
-    Analytics.logEvent(eventName, parameters: statusMap)
-
-    // Fabric
-    Answers.logCustomEvent(withName: eventName, customAttributes: statusMap)
-}
-
- -

-

Listen for settings changes

- -

After initialization, notifications for all features that have been registered can be retrieved. To react to changes, you need to add your class as an observer as follows:

-
NotificationCenter.default.addObserver(
-    self,
-    selector: #selector(self.featureStatusChanged),
-    name: .CapableFeatureStatusDidChange,
-    object: nil)
-
- -

Inside your featureStatusChanged you can parse the specific feature and value:

-
@objc private func featureStatusChanged(notification: NSNotification) {
-    if let featureStatus = notification.object as? FeatureStatus {
-        let feature = featureStatus.feature
-        let currentValue = featureStatus.statusString
-    }
-}
-
- -

If your framework instance has been set up with Handicaps instead, you can use the CapableHandicapStatusDidChange notification:

-
NotificationCenter.default.addObserver(
-    self,
-    selector: #selector(self.handicapStatusChanged),
-    name: .CapableHandicapStatusDidChange,
-    object: nil)
-
- -

Once the notification has been sent, you can parse the Handicapand its current status as follows:

-
@objc private func handicapStatusChanged(notification: NSNotification) {
-    if let handicapStatus = notification.object as? HandicapStatus {
-        let handicap = handicapStatus.handicap
-        let currentValue = handicapStatus.statusString
-    }
-}
-
- -

Please note that when using notifications with Handicaps on macOS or watchOS, you might not get notified about all changes since not all accessibility features do support notifications, yet.

- -

-

High contrast colors (Capable UIColor/NSColor extension)

- -

The Web Content Accessibility Guidelines (WCAG) define minimum contrast ratios for a text and its background. The Capable framework extends UIColor and NSColor with functionality to use WCAG conformant colors within your apps to help people with visual disabilities to perceive content.

- -

Internally, the provided colors will be mapped to an equivalent of the sRGB color space. All functions will return nil and log warnings with further info in case any input color couldn’t be converted. Also note that semi-transparent text colors will be blended with its background color. However, the alpha value of semi-transparent background colors will be ignored since the underlying color can’t be determined.

-

Text colors

- -

Get a high contrast text color for a given background color as follows:

-
let textColor = UIColor.getTextColor(onBackgroundColor: UIColor.red)!
-
- -

This will return the text color with the highest possible contrast (black/white). Alternatively, you can define a list of possible text colors as well as a required conformance level. Since the WCAG requirements for contrast differ in text size and weight, you also need to provide the font used for the text. The following will return the first text color that satisfies the required conformance level (AA by default).

-
let textColor = UIColor.getTextColor(
-    fromColors: [UIColor.red, UIColor.yellow],
-    withFont: myLabel.font,
-    onBackgroundColor: view.backgroundColor,
-    conformanceLevel: .AA
-)!
-
-

Background colors

- -

This will also work the other way round. If you are looking for a high contrast background color:

-
let backgroundColor = UIColor.getBackgroundColor(forTextColor: UIColor.red)!
-
-// or
-
-let backgroundColor = UIColor.getBackgroundColor(
-    fromColors: [UIColor.red, UIColor.yellow],
-    forTextColor: myLabel.textColor,
-    withFont: myLabel.font,
-    conformanceLevel: .AA
-)!
-
- -

-

Image captions (iOS/tvOS/macOS)

- -

Get a high contrast text color for any given background image as follows:

-
let textColor = UIColor.getTextColor(onBackgroundImage: myImage imageArea: .full)!
-
- -

This will return the text color with the highest possible contrast (black/white) for a specific image area.

- -

Alternatively, you can define a list of possible text colors as well as a required conformance level. Since the WCAG requirements for contrast differ in text size and weight, you also need to provide the font used for the text. The following will return the first text color that satisfies the required conformance level (AA by default).

-
let textColor = UIColor.getTextColor(
-    fromColors: [UIColor.red, UIColor.yellow],
-    withFont: myLabel.font,
-    onBackgroundImage: view.backgroundColor,
-    imageArea: topLeft,
-    conformanceLevel: .AA
-)!
-
- -

You can find an overview of all image areas available in the documentation.

-

Calculating contrast ratios & WCAG conformance levels

- -

The contrast ratio of two opaque colors can be calculated as well:

-
let contrastRatio: CGFloat = UIColor.getContrastRatio(forTextColor: UIColor.red, onBackgroundColor: UIColor.yellow)!
-
- -

Once the contrast ratio has been determined, you can check the resulting conformance level specified by WCAG as follows:

-
let passedConformanceLevel = ConformanceLevel(contrastRatio: contrastRatio, fontSize: myLabel.font.pointSize, isBoldFont: true)
-
- -

Here’s an overview of available conformance levels:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LevelContrast ratioFont size
.ANot specified for text color-
.AA3.018.0 (or 14.0 and bold)
4.514.0
.AAA4.518.0 (or 14.0 and bold)
.AAA7.014.0
.failed.AA/.AAA not satisfied-
- -

-

Dynamic Type with custom fonts (Capable UIFont extension)

- -

Supporting Dynamic Type along with different OS versions such as iOS 10 and iOS 11 (watchOS 3 and watchOS 4) can be a huge pain, since both versions provide different APIs.

- -

Capable easily auto scales system fonts as well as your custom fonts by providing one line of code:

-
let myLabel = UILabel(frame: frame)
-
-// Scalable custom font
-let myCustomFont = UIFont(name: "Custom Font Name", size: defaultFontSize)!
-myLabel.font = UIFont.scaledFont(for: myCustomFont)
-
-// or
-myLabel.font = UIFont.scaledFont(withName: "Custom Font Name", ofSize: defaultFontSize)
-
-// Scalable system font
-myLabel.font = UIFont.scaledSystemFont(ofSize: defaultFontSize)
-
-// Scalable italic system font
-myLabel.font = UIFont.scaledItalicSystemFont(ofSize: defaultFontSize)
-
-// Scalable bold system font
-myLabel.font = UIFont.scaledBoldSystemFont(ofSize: defaultFontSize)
-
- -

While these extension APIs are available on tvOS as well, setting the font size in the system settings is not supported on this platforms.

- -

-

Logging with OSLog

- -

The Capable framework provides a logging mechanism that lets you keep track of what’s going on under the hood. You’ll get information regarding your current setup, warnings about anything that might cause issues further on, and errors that will lead to misbehavior.

- -

By default, all messages will be logged automatically by using Apple’s Unified Logging System. However, it also integrates with your specific logging environment by providing a custom closure that will be called instead. For example, you may want to send all errors coming from the Capable framework to your analytics service:

-
// Send error messages to your data backend
-Capable.onLog = { message, logType in
-    if logType == OSLogType.error {
-        sendLog("Capable Framework: \(message)")
-    }
-}
-
- -

Furthermore, you can specify the minimum log level that should be considered when logging messages:

-
// Configure logger to only log warnings and errors (.default, .error, and .fault)
-Capable.minLogType = OSLogType.default
-
- -

Here’s a list of the supported log types, their order, and what kind of messages they are used for:

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
OSLogTypeUsage
.debugVerbose logging *
.infoInformation regarding the framework setup and status changes
.defaultWarnings that may lead to unwanted behavior
.errorErrors caused by the framework
.faultErrors caused by the framework due to system issues *
- -

* Currently not being used by the framework when logging messages.

- -

-

Accessibility feature overview

- -

The following table contains all features that are available AND settable on each platform.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
iOSmacOStvOSwatchOS
.assistiveTouch:white_check_mark:
.boldText:white_check_mark::white_check_mark: :white_check_mark:*
.closedCaptioning:white_check_mark::white_check_mark:
.darkerSystemColors:white_check_mark:
.differentiateWithoutColor:white_check_mark::white_check_mark:
.fullKeyboardAccess :white_check_mark:*
.grayscale:white_check_mark::white_check_mark:
.guidedAccess:white_check_mark:
.hearingDevice:white_check_mark:
.increaseContrast:white_check_mark:
.invertColors:white_check_mark::white_check_mark::white_check_mark:
.largerText:white_check_mark: :white_check_mark:*
.monoAudio:white_check_mark::white_check_mark:
.onOffSwitchLabels:white_check_mark:
.reduceMotion:white_check_mark::white_check_mark::white_check_mark::white_check_mark:
.reduceTransparency:white_check_mark::white_check_mark::white_check_mark:
.shakeToUndo:white_check_mark:
.speakScreen:white_check_mark:
.speakSelection:white_check_mark:
.switchControl:white_check_mark::white_check_mark::white_check_mark:
.videoAutoplay:white_check_mark::white_check_mark:
.voiceOver:white_check_mark::white_check_mark::white_check_mark::white_check_mark:
- -

* Feature status can be read but notifications are not available.

- -

While most features can only have a statusMap value set to enabled or disabled, the .largerText and .hearingDevice feature do offer specific values:

-

LargerText

-

iOS

- -
    -
  • XS
  • -
  • S
  • -
  • M (default)
  • -
  • L
  • -
  • XL
  • -
  • XXL
  • -
  • XXXL
  • -
  • Accessibility M
  • -
  • Accessibility L
  • -
  • Accessibility XL
  • -
  • Accessibility XXL
  • -
  • Accessibility XXXL
  • -
  • Unknown
  • -
-

watchOS

- -
    -
  • XS
  • -
  • S (default watch with 38mm)
  • -
  • L (default watch with 42mm)
  • -
  • XL
  • -
  • XXL
  • -
  • XXXL
  • -
  • Unknown
  • -
-

HearingDevice

- -
    -
  • both
  • -
  • left
  • -
  • right
  • -
  • disabled
  • -
-

Resources

- - -

Contributions

- -

We’d love to see you contributing to this project by proposing or adding features, reporting bugs, or spreading the word. Please have a quick look at our contribution guidelines.

-

License

- -

Capable is available under the MIT license. See the LICENSE file for more info.

- -
-
- -
-
- - - diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/js/jazzy.js b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/js/jazzy.js deleted file mode 100755 index c31dc05..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/js/jazzy.js +++ /dev/null @@ -1,59 +0,0 @@ -window.jazzy = {'docset': false} -if (typeof window.dash != 'undefined') { - document.documentElement.className += ' dash' - window.jazzy.docset = true -} -if (navigator.userAgent.match(/xcode/i)) { - document.documentElement.className += ' xcode' - window.jazzy.docset = true -} - -function toggleItem($link, $content) { - var animationDuration = 300; - $link.toggleClass('token-open'); - $content.slideToggle(animationDuration); -} - -function itemLinkToContent($link) { - return $link.parent().parent().next(); -} - -// On doc load + hash-change, open any targetted item -function openCurrentItemIfClosed() { - if (window.jazzy.docset) { - return; - } - var $link = $(`.token[href="${location.hash}"]`); - $content = itemLinkToContent($link); - if ($content.is(':hidden')) { - toggleItem($link, $content); - } -} - -$(openCurrentItemIfClosed); -$(window).on('hashchange', openCurrentItemIfClosed); - -// On item link ('token') click, toggle its discussion -$('.token').on('click', function(event) { - if (window.jazzy.docset) { - return; - } - var $link = $(this); - toggleItem($link, itemLinkToContent($link)); - - // Keeps the document from jumping to the hash. - var href = $link.attr('href'); - if (history.pushState) { - history.pushState({}, '', href); - } else { - location.hash = href; - } - event.preventDefault(); -}); - -// Clicks on links to the current, closed, item need to open the item -$("a:not('.token')").on('click', function() { - if (location == this.href) { - openCurrentItemIfClosed(); - } -}); diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/js/jquery.min.js b/Documentation/docsets/Capable.docset/Contents/Resources/Documents/js/jquery.min.js deleted file mode 100644 index a1c07fd..0000000 --- a/Documentation/docsets/Capable.docset/Contents/Resources/Documents/js/jquery.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0Typealias used for colors. It maps to UIColor.

"},"Typealiases.html#/Font":{"name":"Font","abstract":"

Typealias used for fonts. It maps to UIFont.

"},"Typealiases.html#/s:7Capable5Colora":{"name":"Color","abstract":"

Typealias used for colors. It maps to NSColor.

"},"Typealiases.html#/s:7Capable4Fonta":{"name":"Font","abstract":"

Typealias used for fonts. It maps to NSFont.

"},"Typealiases.html#/Image":{"name":"Image","abstract":"

Typealias used for images. It maps to UIImage.

"},"Typealiases.html#/s:7Capable5Imagea":{"name":"Image","abstract":"

Typealias used for image. It maps to NSImage.

"},"Structs/HandicapStatus.html#/s:7Capable14HandicapStatusV8handicapAA0B0Vvp":{"name":"handicap","abstract":"

The Handicap that has changed.

","parent_name":"HandicapStatus"},"Structs/HandicapStatus.html#/s:7Capable14HandicapStatusV12statusStringSSvp":{"name":"statusString","abstract":"

The Handicap‘s status (enabled or disabled). Note that the status depends on the Handicap’s enabledIf value (see HandicapEnabledMode).

","parent_name":"HandicapStatus"},"Structs/Handicap.html#/s:7Capable8HandicapV8featuresSayAA0A7FeatureOGvp":{"name":"features","abstract":"

A list of CapableFeatures that are expected to be enabled if a user has this handicap.

","parent_name":"Handicap"},"Structs/Handicap.html#/s:7Capable8HandicapV4nameSSvp":{"name":"name","abstract":"

The name of the Handicap that can be used to uniquely identify the Handicap. This name is also used inside the status map.

","parent_name":"Handicap"},"Structs/Handicap.html#/s:7Capable8HandicapV9enabledIfAA0B11EnabledModeOvp":{"name":"enabledIf","abstract":"

This mode defines whether all features need to be enabled to set the Handicap‘s status to enabled or only one of them.

","parent_name":"Handicap"},"Structs/Handicap.html#/s:7Capable8HandicapV8features4name9enabledIfACSayAA0A7FeatureOG_SSAA0B11EnabledModeOtcfc":{"name":"init(features:name:enabledIf:)","abstract":"

Initializes a new Handicap object.

","parent_name":"Handicap"},"Structs/FeatureStatus.html#/s:7Capable13FeatureStatusV7featureAA0aB0Ovp":{"name":"feature","abstract":"

The feature type.

","parent_name":"FeatureStatus"},"Structs/FeatureStatus.html#/s:7Capable13FeatureStatusV12statusStringSSvp":{"name":"statusString","abstract":"

The feature’s status: While most features can only have a status set to enabled or disabled, the ‘.largerText` feature offers the font scale set by the user.

","parent_name":"FeatureStatus"},"Structs/Capable.html#/s:7CapableAAV12withFeaturesABSayAA0A7FeatureOG_tcfc":{"name":"init(withFeatures:)","abstract":"

Initializes the framework instance with a specified set of features. If no feature was provided, this defaults to all features available on the current platform.

","parent_name":"Capable"},"Structs/Capable.html#/s:7CapableAAV13withHandicapsABSayAA8HandicapVG_tcfc":{"name":"init(withHandicaps:)","abstract":"

Initializes the framework instance with a set of Handicaps.

","parent_name":"Capable"},"Structs/Capable.html#/s:7CapableAAV9statusMapSDyS2SGvp":{"name":"statusMap","abstract":"

The statusMap property returns a dictionary of all CapableFeatures or Handicaps , that the Capable instance has been initialized with along with their current statuses. This object is compatible with most analytic SDKs such as Fabric Answers, Firebase Analytics, AppCenter Analytics, or HockeyApp.","parent_name":"Capable"},"Structs/Capable.html#/s:7CapableAAV16isFeatureEnabled7featureSbAA0aC0O_tF":{"name":"isFeatureEnabled(feature:)","abstract":"

Provides information regarding the current status of a provided feature.

","parent_name":"Capable"},"Structs/Capable.html#/s:7CapableAAV17isHandicapEnabled12handicapNameSbSS_tF":{"name":"isHandicapEnabled(handicapName:)","abstract":"

Provides information regarding the current status of a provided Handicap.

","parent_name":"Capable"},"Structs/Capable.html#/s:7CapableAAV10minLogTypeSo13os_log_type_tavpZ":{"name":"minLogType","abstract":"

The minimum log level that should be considered when logging messages. Note that the custom ‘onLog’ closure will only be called for messages of this log type or higher. This value defaults to OSLogType.debug.

","parent_name":"Capable"},"Structs/Capable.html#/s:7CapableAAV5onLogyySS_So13os_log_type_tatcvpZ":{"name":"onLog","abstract":"

A custom closure that should be used by the logger for all Capable instances instead of the default os_log implementation.

","parent_name":"Capable"},"Structs/Capable.html":{"name":"Capable","abstract":"

This class defines the main interface of the Capable framework.

"},"Structs/FeatureStatus.html":{"name":"FeatureStatus","abstract":"

Model class that describes the content of a Capable notification (see Notification.Name.CapableFeatureStatusDidChange)

"},"Structs/Handicap.html":{"name":"Handicap","abstract":"

Model class that groups a number of CapableFeatures to represent a user’s handicap.

"},"Structs/HandicapStatus.html":{"name":"HandicapStatus","abstract":"

Model class that describes the content of a Capable notification (see Notification.Name.CapableHandicapStatusDidChange)

"},"Extensions/UIFont.html#/scaledFont(for:)":{"name":"scaledFont(for:)","abstract":"

Makes the given font scalable.

","parent_name":"UIFont"},"Extensions/UIFont.html#/scaledFont(withName:ofSize:)":{"name":"scaledFont(withName:ofSize:)","abstract":"

Creates a scalable font with the given font name and reference font size.

","parent_name":"UIFont"},"Extensions/UIFont.html#/scaledSystemFont(ofSize:)":{"name":"scaledSystemFont(ofSize:)","abstract":"

Creates a scalable system font with a given reference font size.

","parent_name":"UIFont"},"Extensions/UIFont.html#/scaledBoldSystemFont(ofSize:)":{"name":"scaledBoldSystemFont(ofSize:)","abstract":"

Creates a scalable bold system font with a given reference font size.

","parent_name":"UIFont"},"Extensions/UIFont.html#/scaledItalicSystemFont(ofSize:)":{"name":"scaledItalicSystemFont(ofSize:)","abstract":"

Creates a scalable italic system font with a given reference font size.

","parent_name":"UIFont"},"Extensions/Notification/Name.html#/s:So18NSNotificationNamea7CapableE0C22FeatureStatusDidChangeABvpZ":{"name":"CapableFeatureStatusDidChange","abstract":"

Name of the notification that gets fired whenever an observed accessibility feature status changes.

","parent_name":"Name"},"Extensions/Notification/Name.html#/s:So18NSNotificationNamea7CapableE0C23HandicapStatusDidChangeABvpZ":{"name":"CapableHandicapStatusDidChange","abstract":"

Name of the notification that gets fired whenever an observed Handicap status changes.

","parent_name":"Name"},"Extensions/Notification/Name.html":{"name":"Name","abstract":"

Extension that defines notification names provided by the Capable framework.

","parent_name":"Notification"},"Extensions/Color.html#/s:So7NSColorC7CapableE16getContrastRatio12forTextColor012onBackgroundH012CoreGraphics7CGFloatVSgAB_ABtFZ":{"name":"getContrastRatio(forTextColor:onBackgroundColor:)","abstract":"

Calculates the color ratio for a text color on a background color.

","parent_name":"Color"},"Extensions/Color.html#/s:So7NSColorC7CapableE12getTextColor012onBackgroundE0ABSgAB_tFZ":{"name":"getTextColor(onBackgroundColor:)","abstract":"

Returns the text color with the highest contrast (black or white) for a given background color.

","parent_name":"Color"},"Extensions/Color.html#/s:So7NSColorC7CapableE12getTextColor10fromColors8withFont012onBackgroundE016conformanceLevelABSgSayABG_So6NSFontCAbC011ConformanceM0OtFZ":{"name":"getTextColor(fromColors:withFont:onBackgroundColor:conformanceLevel:)","abstract":"

Calculates the contrast ratio of a given list of text colors and a background color. The first color that conforms to the conformance level defined gets returned. The default conformance level is .AA.

","parent_name":"Color"},"Extensions/Color.html#/s:So7NSColorC7CapableE12getTextColor17onBackgroundImage9imageAreaABSgSo7NSImageC_AC0hJ0OtFZ":{"name":"getTextColor(onBackgroundImage:imageArea:)","abstract":"

Returns the text color with the highest contrast (black or white) for a specific area of given background image.

","parent_name":"Color"},"Extensions/Color.html#/s:So7NSColorC7CapableE12getTextColor10fromColors8withFont17onBackgroundImage9imageArea16conformanceLevelABSgSayABG_So6NSFontCSo7NSImageCAC0lN0OAC011ConformanceP0OtFZ":{"name":"getTextColor(fromColors:withFont:onBackgroundImage:imageArea:conformanceLevel:)","abstract":"

Calculates the contrast ratio of a given list of text colors and a specific area of given background image. The first color that conforms to the conformance level defined gets returned. The default conformance level is .AA.

","parent_name":"Color"},"Extensions/Color.html#/s:So7NSColorC7CapableE18getBackgroundColor07forTextE0ABSgAB_tFZ":{"name":"getBackgroundColor(forTextColor:)","abstract":"

Returns the background color with the highest contrast (black or white) for a given text color.

","parent_name":"Color"},"Extensions/Color.html#/s:So7NSColorC7CapableE18getBackgroundColor10fromColors07forTextE08withFont16conformanceLevelABSgSayABG_ABSo6NSFontCAC011ConformanceM0OtFZ":{"name":"getBackgroundColor(fromColors:forTextColor:withFont:conformanceLevel:)","abstract":"

Calculates the contrast ratio of a given list of background colors and a text color. The first color that conforms to the conformance level defined gets returned. The default conformance level is .AA.

","parent_name":"Color"},"Extensions/Color.html":{"name":"Color","abstract":"

Extension that adds functionality for calculating WCAG compliant high contrast colors.

"},"Extensions/Notification.html":{"name":"Notification"},"Extensions/UIFont.html":{"name":"UIFont","abstract":"

Extension that adds functionality for creating scalable UIFont objects.

"},"Enums/HandicapEnabledMode.html#/s:7Capable19HandicapEnabledModeO010oneFeatureC0yA2CmF":{"name":"oneFeatureEnabled","abstract":"

The Handicap‘s status is enabled if one of its features is currently set to enabled.

","parent_name":"HandicapEnabledMode"},"Enums/HandicapEnabledMode.html#/s:7Capable19HandicapEnabledModeO011allFeaturesC0yA2CmF":{"name":"allFeaturesEnabled","abstract":"

The Handicap‘s status is enabled if all its features are currently set to enabled.

","parent_name":"HandicapEnabledMode"},"Enums/CapableFeature.html#/assistiveTouch":{"name":"assistiveTouch","abstract":"

Menu that helps people with motor skill impairments to do certain actions or gestures by using a single tap.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/darkerSystemColors":{"name":"darkerSystemColors","abstract":"

Enhances text contrast.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/guidedAccess":{"name":"guidedAccess","abstract":"

Restricts access to certain features of a single app to keep the user focused.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/hearingDevice":{"name":"hearingDevice","abstract":"

Pairing status of a hearing aid.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/onOffSwitchLabels":{"name":"onOffSwitchLabels","abstract":"

Displays on/off labels for UISwitch controls.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/shakeToUndo":{"name":"shakeToUndo","abstract":"

Deletes the last command by shaking the phone.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/speakScreen":{"name":"speakScreen","abstract":"

Reads out the content of the current screen.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/speakSelection":{"name":"speakSelection","abstract":"

Reads out the selected content.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/s:7Capable0A7FeatureO18fullKeyboardAccessyA2CmF":{"name":"fullKeyboardAccess","abstract":"

Enables users to navigate through items of the screen without having to use a mouse.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/s:7Capable0A7FeatureO16increaseContrastyA2CmF":{"name":"increaseContrast","abstract":"

Increases contrast to make out text and interface elements.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/closedCaptioning":{"name":"closedCaptioning","abstract":"

Displays subtitles when playing videos.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/grayscale":{"name":"grayscale","abstract":"

Makes the display more readable for color blind people by using gray tones instead of colors.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/monoAudio":{"name":"monoAudio","abstract":"

Merges stereo audio channels to help users that are hard of hearing or deaf in one ear.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/videoAutoplay":{"name":"videoAutoplay","abstract":"

Allows users who are sensitive to motion to disable automatic video playback.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/largerText":{"name":"largerText","abstract":"

Increases legibility by making fonts bigger.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/s:7Capable0A7FeatureO25differentiateWithoutColoryA2CmF":{"name":"differentiateWithoutColor","abstract":"

Helps color blind users to differentiate settings differently, e.g. by using shapes rather than colors.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/s:7Capable0A7FeatureO12invertColorsyA2CmF":{"name":"invertColors","abstract":"

Helps people with low vision, color blindness, or sensitivity to brightness to read the display content.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/s:7Capable0A7FeatureO18reduceTransparencyyA2CmF":{"name":"reduceTransparency","abstract":"

Removes transparency from layers to make them readable for users with visual impairment.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/s:7Capable0A7FeatureO13switchControlyA2CmF":{"name":"switchControl","abstract":"

Allows users with limited mobility to control their device with the help of ability switches and other adaptive devices.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/boldText":{"name":"boldText","abstract":"

Increases legibility by making fonts heavier.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/s:7Capable0A7FeatureO12reduceMotionyA2CmF":{"name":"reduceMotion","abstract":"

Reduces animations to help users with motion sickness and epilepsy issues.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/s:7Capable0A7FeatureO9voiceOveryA2CmF":{"name":"voiceOver","abstract":"

The screen reader available on Apple platforms.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/s:7Capable0A7FeatureO4keys11forFeaturesSaySSGSayACG_tFZ":{"name":"keys(forFeatures:)","abstract":"

Iterates through a given list of feature types and returns an array containing the feature names as strings.

","parent_name":"CapableFeature"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO4fullyA2CmF":{"name":"full","abstract":"

The full image size.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO6bottomyA2CmF":{"name":"bottom","abstract":"

The last vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO12bottomCenteryA2CmF":{"name":"bottomCenter","abstract":"

The second horizontal third of the last vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO10bottomLeftyA2CmF":{"name":"bottomLeft","abstract":"

The first horizontal third of the last vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO11bottomRightyA2CmF":{"name":"bottomRight","abstract":"

The last horizontal third of the last vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO6centeryA2CmF":{"name":"center","abstract":"

The second horizontal third of the second vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO10centerLeftyA2CmF":{"name":"centerLeft","abstract":"

The first horizontal third of the second vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO11centerRightyA2CmF":{"name":"centerRight","abstract":"

The last horizontal third of the second vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO6customyACSo6CGRectV_tcACmF":{"name":"custom(rect:)","abstract":"

A custom area of the image defined by a CGRect.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO16horizontalCenteryA2CmF":{"name":"horizontalCenter","abstract":"

The second vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO4leftyA2CmF":{"name":"left","abstract":"

The first horizontal third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO5rightyA2CmF":{"name":"right","abstract":"

The last horizontal third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO3topyA2CmF":{"name":"top","abstract":"

The first vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO9topCenteryA2CmF":{"name":"topCenter","abstract":"

The second horizontal third of the first vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO7topLeftyA2CmF":{"name":"topLeft","abstract":"

The first horizontal third of the first vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO8topRightyA2CmF":{"name":"topRight","abstract":"

The last horizontal third of the first vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO14verticalCenteryA2CmF":{"name":"verticalCenter","abstract":"

The second horizontal third.

","parent_name":"ImageArea"},"Enums/ConformanceLevel.html#/s:7Capable16ConformanceLevelO1AyA2CmF":{"name":"A","abstract":"

The minimum level of conformance.

","parent_name":"ConformanceLevel"},"Enums/ConformanceLevel.html#/s:7Capable16ConformanceLevelO2AAyA2CmF":{"name":"AA","abstract":"

The medium level of conformance including success criterias of level A.

","parent_name":"ConformanceLevel"},"Enums/ConformanceLevel.html#/s:7Capable16ConformanceLevelO3AAAyA2CmF":{"name":"AAA","abstract":"

The highest level of conformance including success criterias of level A and AA.

","parent_name":"ConformanceLevel"},"Enums/ConformanceLevel.html#/s:7Capable16ConformanceLevelO6failedyA2CmF":{"name":"failed","abstract":"

Indicates that no level of conformance has been reached.

","parent_name":"ConformanceLevel"},"Enums/ConformanceLevel.html#/s:7Capable16ConformanceLevelO13contrastRatio8fontSize10isBoldFontAC12CoreGraphics7CGFloatV_AISbtcfc":{"name":"init(contrastRatio:fontSize:isBoldFont:)","abstract":"

Initializes a ConformanceLevel based on a given contrast ratio and font information used for the text.

","parent_name":"ConformanceLevel"},"Enums/ConformanceLevel.html#/s:7Capable16ConformanceLevelO4textSSvp":{"name":"text","abstract":"

The text representation of the conformance level.

","parent_name":"ConformanceLevel"},"Enums/ConformanceLevel.html":{"name":"ConformanceLevel","abstract":"

An enum specifying all WCAG conformance levels.

"},"Enums/ImageArea.html":{"name":"ImageArea","abstract":"

Undocumented

"},"Enums/CapableFeature.html":{"name":"CapableFeature","abstract":"

An enum specifying all features available on the current platform.

"},"Enums/HandicapEnabledMode.html":{"name":"HandicapEnabledMode","abstract":"

This enum defines several modes which describe whether all features need to be enabled to set the Handicap‘s status to enabled or only one of them.

"},"Enums.html":{"name":"Enumerations","abstract":"

The following enumerations are available globally.

"},"Extensions.html":{"name":"Extensions","abstract":"

The following extensions are available globally.

"},"Structs.html":{"name":"Structures","abstract":"

The following structures are available globally.

"},"Typealiases.html":{"name":"Type Aliases","abstract":"

The following type aliases are available globally.

"}} \ No newline at end of file diff --git a/Documentation/docsets/Capable.docset/Contents/Resources/docSet.dsidx b/Documentation/docsets/Capable.docset/Contents/Resources/docSet.dsidx deleted file mode 100644 index 1343034..0000000 Binary files a/Documentation/docsets/Capable.docset/Contents/Resources/docSet.dsidx and /dev/null differ diff --git a/Documentation/docsets/Capable.tgz b/Documentation/docsets/Capable.tgz deleted file mode 100644 index 6a5a450..0000000 Binary files a/Documentation/docsets/Capable.tgz and /dev/null differ diff --git a/Documentation/img/carat.png b/Documentation/img/carat.png deleted file mode 100755 index 29d2f7f..0000000 Binary files a/Documentation/img/carat.png and /dev/null differ diff --git a/Documentation/img/dash.png b/Documentation/img/dash.png deleted file mode 100755 index 6f694c7..0000000 Binary files a/Documentation/img/dash.png and /dev/null differ diff --git a/Documentation/img/gh.png b/Documentation/img/gh.png deleted file mode 100755 index 628da97..0000000 Binary files a/Documentation/img/gh.png and /dev/null differ diff --git a/Documentation/index.html b/Documentation/index.html deleted file mode 100644 index 1862b85..0000000 --- a/Documentation/index.html +++ /dev/null @@ -1,723 +0,0 @@ - - - - Capable Reference - - - - - - - - - -
-
-

Capable Docs (98% documented)

-

View on GitHub

-
-
-
- -
-
- -
-
-
- -

-

- -
- -

Awesome -Build Status -Swift -Platforms -Carthage compatible -Cocoapods compatible -SPM -Documentation -codecov -Twitter

-

Accessibility for iOS, macOS, tvOS, and watchOS

- -

Check out the Example.xcworkspace to get a quick overview:

- -

Example project overview

-

1) Research: Do I need to care about accessibility?

- - - -

Have you ever thought about adopting accessibility features within you apps to gain your user base instead of spending a lot of time implementing features no-one really ever asked for?

- -

Most of us did, however there has never been an easy way to tell if anyone benefits from that. Adjusting layouts to be usable for people with low vision can be quite complex in some situations and tracking the user’s accessibility settings adds a lot of boilerplate code to your app.

- -

What if there was a simple way to figure out if there’s a real need to support accessibility right now. Or even better, which disability exists most across your user base.

-

2) React: Improve problematic screens

- - - -

Once you’ve figured out that users with specific handicaps get stuck at a certain stage, you can make use of various Capable APIs to enable/disable accessibility support based on the user’s accessibility settings or improve texts and colors used within your apps. Go back to step 1 to proof that the work helped users to succeed using your app.

-

3) Fault diagnosis

- -

Each Capable feature is backed by the built-in logging system, which will keep you in the loop about what might have been going wrong. Even if you are using your own logging solution, the Capable logger is fully compatible with it!

- - -

Documentation

- -

Capable offers a whole lot of features along with a bunch of configurations. To find more about how to use them inside the documentation section.

-

Installation

- -

There are currently four different ways to integrate Capable into your apps.

-

CocoaPods

-
use_frameworks!
-
-target 'MyApp' do
-
-  # all features + color and font extensions
-  pod 'Capable'
-
-  # all features, but exclude color and font extensions
-  pod 'Capable/Features'
-
-  # color extensions only
-  pod 'Capable/Colors'
-
-  # font extensions only
-  pod 'Capable/Fonts'
-end
-
-

Carthage

-
github "chrs1885/Capable"
-
-

Swift Package Manager

-
dependencies: [
-    .package(url: "https://github.com/chrs1885/Capable.git", from: "1.1.0")
-]
-
-

Manually

- -

Simply drop Capable.xcodeproj into your project. Also make sure to add -Capable.framework to your app’s embedded frameworks found in the General tab of your main project.

-

Usage

-

Register for (specific) accessibility settings

- -

Firstly, you need to import the Capable framework in your class by adding the following import statement:

-
import Capable
-
- -

There are two different ways to initialize the framework instance. You can either set it up to consider all accessibility features

-
let capable = Capable()
-
- -

or by passing in only specific feature names

-
let capable = Capable(withFeatures: [.largerText, .boldText, .shakeToUndo])
-
- -

You can find a list of all accessibility features available on each platform in the accessibility feature overview section.

- -

-

Get accessibility status

- -

If you are interested in a specific accessibility feature, you can retrieve its current status as follows:

-
let capable = Capable()
-let isVoiceOverEnabled: Bool = capable.isFeatureEnable(feature: .voiceOver)
-
- -

To get a dictionary of all features, that the Capable instance has been initialized with you can use:

-
let capable = Capable()
-let statusMap = capable.statusMap
-
- -

This will return each feature name (key) along with its current value as described in the accessibility feature overview section.

- -

-

Handicaps - grouped accessibility features

- -

You can also group accessibility features to represent a specific handicap:

-
// Define a set of features that represent a handicap
-let features: [CapableFeature] = [.voiceOver, .speakScreen, .speakSelection]
-
-// Use the Handicap object to group them
-let blindness = Handicap(features: features, name: "Blindness", enabledIf: .allFeaturesEnabled)
-
-// Initialize the framework instance by providing the Handicap
-let capable = Capable(withHandicaps: [blindness])
-
- -

The value of the name parameter will be used inside the statusMap provided by the Capable framework instance. Based on the value of enabledIf, you can specify if all features need to be set to enabled in order to set the Handicap to enabled as well.

- -

Just like accessibility features, the Handicap type works great with notifications.

- -

-

Send accessibility status

- -

The statusMap object is compatible with most analytic SDK APIs. Here’s a quick example of how to send your data along with user properties or custom events.

-
func sendMetrics() {
-    let statusMap = self.capable.statusMap
-    let eventName = "Capable features received"
-
-    // App Center
-    MSAnalytics.trackEvent(eventName, withProperties: statusMap)
-
-    // Firebase
-    Analytics.logEvent(eventName, parameters: statusMap)
-
-    // Fabric
-    Answers.logCustomEvent(withName: eventName, customAttributes: statusMap)
-}
-
- -

-

Listen for settings changes

- -

After initialization, notifications for all features that have been registered can be retrieved. To react to changes, you need to add your class as an observer as follows:

-
NotificationCenter.default.addObserver(
-    self,
-    selector: #selector(self.featureStatusChanged),
-    name: .CapableFeatureStatusDidChange,
-    object: nil)
-
- -

Inside your featureStatusChanged you can parse the specific feature and value:

-
@objc private func featureStatusChanged(notification: NSNotification) {
-    if let featureStatus = notification.object as? FeatureStatus {
-        let feature = featureStatus.feature
-        let currentValue = featureStatus.statusString
-    }
-}
-
- -

If your framework instance has been set up with Handicaps instead, you can use the CapableHandicapStatusDidChange notification:

-
NotificationCenter.default.addObserver(
-    self,
-    selector: #selector(self.handicapStatusChanged),
-    name: .CapableHandicapStatusDidChange,
-    object: nil)
-
- -

Once the notification has been sent, you can parse the Handicapand its current status as follows:

-
@objc private func handicapStatusChanged(notification: NSNotification) {
-    if let handicapStatus = notification.object as? HandicapStatus {
-        let handicap = handicapStatus.handicap
-        let currentValue = handicapStatus.statusString
-    }
-}
-
- -

Please note that when using notifications with Handicaps on macOS or watchOS, you might not get notified about all changes since not all accessibility features do support notifications, yet.

- -

-

High contrast colors (Capable UIColor/NSColor extension)

- -

The Web Content Accessibility Guidelines (WCAG) define minimum contrast ratios for a text and its background. The Capable framework extends UIColor and NSColor with functionality to use WCAG conformant colors within your apps to help people with visual disabilities to perceive content.

- -

Internally, the provided colors will be mapped to an equivalent of the sRGB color space. All functions will return nil and log warnings with further info in case any input color couldn’t be converted. Also note that semi-transparent text colors will be blended with its background color. However, the alpha value of semi-transparent background colors will be ignored since the underlying color can’t be determined.

-

Text colors

- -

Get a high contrast text color for a given background color as follows:

-
let textColor = UIColor.getTextColor(onBackgroundColor: UIColor.red)!
-
- -

This will return the text color with the highest possible contrast (black/white). Alternatively, you can define a list of possible text colors as well as a required conformance level. Since the WCAG requirements for contrast differ in text size and weight, you also need to provide the font used for the text. The following will return the first text color that satisfies the required conformance level (AA by default).

-
let textColor = UIColor.getTextColor(
-    fromColors: [UIColor.red, UIColor.yellow],
-    withFont: myLabel.font,
-    onBackgroundColor: view.backgroundColor,
-    conformanceLevel: .AA
-)!
-
-

Background colors

- -

This will also work the other way round. If you are looking for a high contrast background color:

-
let backgroundColor = UIColor.getBackgroundColor(forTextColor: UIColor.red)!
-
-// or
-
-let backgroundColor = UIColor.getBackgroundColor(
-    fromColors: [UIColor.red, UIColor.yellow],
-    forTextColor: myLabel.textColor,
-    withFont: myLabel.font,
-    conformanceLevel: .AA
-)!
-
- -

-

Image captions (iOS/tvOS/macOS)

- -

Get a high contrast text color for any given background image as follows:

-
let textColor = UIColor.getTextColor(onBackgroundImage: myImage imageArea: .full)!
-
- -

This will return the text color with the highest possible contrast (black/white) for a specific image area.

- -

Alternatively, you can define a list of possible text colors as well as a required conformance level. Since the WCAG requirements for contrast differ in text size and weight, you also need to provide the font used for the text. The following will return the first text color that satisfies the required conformance level (AA by default).

-
let textColor = UIColor.getTextColor(
-    fromColors: [UIColor.red, UIColor.yellow],
-    withFont: myLabel.font,
-    onBackgroundImage: view.backgroundColor,
-    imageArea: topLeft,
-    conformanceLevel: .AA
-)!
-
- -

You can find an overview of all image areas available in the documentation.

-

Calculating contrast ratios & WCAG conformance levels

- -

The contrast ratio of two opaque colors can be calculated as well:

-
let contrastRatio: CGFloat = UIColor.getContrastRatio(forTextColor: UIColor.red, onBackgroundColor: UIColor.yellow)!
-
- -

Once the contrast ratio has been determined, you can check the resulting conformance level specified by WCAG as follows:

-
let passedConformanceLevel = ConformanceLevel(contrastRatio: contrastRatio, fontSize: myLabel.font.pointSize, isBoldFont: true)
-
- -

Here’s an overview of available conformance levels:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LevelContrast ratioFont size
.ANot specified for text color-
.AA3.018.0 (or 14.0 and bold)
4.514.0
.AAA4.518.0 (or 14.0 and bold)
.AAA7.014.0
.failed.AA/.AAA not satisfied-
- -

-

Dynamic Type with custom fonts (Capable UIFont extension)

- -

Supporting Dynamic Type along with different OS versions such as iOS 10 and iOS 11 (watchOS 3 and watchOS 4) can be a huge pain, since both versions provide different APIs.

- -

Capable easily auto scales system fonts as well as your custom fonts by providing one line of code:

-
let myLabel = UILabel(frame: frame)
-
-// Scalable custom font
-let myCustomFont = UIFont(name: "Custom Font Name", size: defaultFontSize)!
-myLabel.font = UIFont.scaledFont(for: myCustomFont)
-
-// or
-myLabel.font = UIFont.scaledFont(withName: "Custom Font Name", ofSize: defaultFontSize)
-
-// Scalable system font
-myLabel.font = UIFont.scaledSystemFont(ofSize: defaultFontSize)
-
-// Scalable italic system font
-myLabel.font = UIFont.scaledItalicSystemFont(ofSize: defaultFontSize)
-
-// Scalable bold system font
-myLabel.font = UIFont.scaledBoldSystemFont(ofSize: defaultFontSize)
-
- -

While these extension APIs are available on tvOS as well, setting the font size in the system settings is not supported on this platforms.

- -

-

Logging with OSLog

- -

The Capable framework provides a logging mechanism that lets you keep track of what’s going on under the hood. You’ll get information regarding your current setup, warnings about anything that might cause issues further on, and errors that will lead to misbehavior.

- -

By default, all messages will be logged automatically by using Apple’s Unified Logging System. However, it also integrates with your specific logging environment by providing a custom closure that will be called instead. For example, you may want to send all errors coming from the Capable framework to your analytics service:

-
// Send error messages to your data backend
-Capable.onLog = { message, logType in
-    if logType == OSLogType.error {
-        sendLog("Capable Framework: \(message)")
-    }
-}
-
- -

Furthermore, you can specify the minimum log level that should be considered when logging messages:

-
// Configure logger to only log warnings and errors (.default, .error, and .fault)
-Capable.minLogType = OSLogType.default
-
- -

Here’s a list of the supported log types, their order, and what kind of messages they are used for:

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
OSLogTypeUsage
.debugVerbose logging *
.infoInformation regarding the framework setup and status changes
.defaultWarnings that may lead to unwanted behavior
.errorErrors caused by the framework
.faultErrors caused by the framework due to system issues *
- -

* Currently not being used by the framework when logging messages.

- -

-

Accessibility feature overview

- -

The following table contains all features that are available AND settable on each platform.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
iOSmacOStvOSwatchOS
.assistiveTouch:white_check_mark:
.boldText:white_check_mark::white_check_mark: :white_check_mark:*
.closedCaptioning:white_check_mark::white_check_mark:
.darkerSystemColors:white_check_mark:
.differentiateWithoutColor:white_check_mark::white_check_mark:
.fullKeyboardAccess :white_check_mark:*
.grayscale:white_check_mark::white_check_mark:
.guidedAccess:white_check_mark:
.hearingDevice:white_check_mark:
.increaseContrast:white_check_mark:
.invertColors:white_check_mark::white_check_mark::white_check_mark:
.largerText:white_check_mark: :white_check_mark:*
.monoAudio:white_check_mark::white_check_mark:
.onOffSwitchLabels:white_check_mark:
.reduceMotion:white_check_mark::white_check_mark::white_check_mark::white_check_mark:
.reduceTransparency:white_check_mark::white_check_mark::white_check_mark:
.shakeToUndo:white_check_mark:
.speakScreen:white_check_mark:
.speakSelection:white_check_mark:
.switchControl:white_check_mark::white_check_mark::white_check_mark:
.videoAutoplay:white_check_mark::white_check_mark:
.voiceOver:white_check_mark::white_check_mark::white_check_mark::white_check_mark:
- -

* Feature status can be read but notifications are not available.

- -

While most features can only have a statusMap value set to enabled or disabled, the .largerText and .hearingDevice feature do offer specific values:

-

LargerText

-

iOS

- -
    -
  • XS
  • -
  • S
  • -
  • M (default)
  • -
  • L
  • -
  • XL
  • -
  • XXL
  • -
  • XXXL
  • -
  • Accessibility M
  • -
  • Accessibility L
  • -
  • Accessibility XL
  • -
  • Accessibility XXL
  • -
  • Accessibility XXXL
  • -
  • Unknown
  • -
-

watchOS

- -
    -
  • XS
  • -
  • S (default watch with 38mm)
  • -
  • L (default watch with 42mm)
  • -
  • XL
  • -
  • XXL
  • -
  • XXXL
  • -
  • Unknown
  • -
-

HearingDevice

- -
    -
  • both
  • -
  • left
  • -
  • right
  • -
  • disabled
  • -
-

Resources

- - -

Contributions

- -

We’d love to see you contributing to this project by proposing or adding features, reporting bugs, or spreading the word. Please have a quick look at our contribution guidelines.

-

License

- -

Capable is available under the MIT license. See the LICENSE file for more info.

- -
-
- -
-
- - - diff --git a/Documentation/js/jazzy.js b/Documentation/js/jazzy.js deleted file mode 100755 index c31dc05..0000000 --- a/Documentation/js/jazzy.js +++ /dev/null @@ -1,59 +0,0 @@ -window.jazzy = {'docset': false} -if (typeof window.dash != 'undefined') { - document.documentElement.className += ' dash' - window.jazzy.docset = true -} -if (navigator.userAgent.match(/xcode/i)) { - document.documentElement.className += ' xcode' - window.jazzy.docset = true -} - -function toggleItem($link, $content) { - var animationDuration = 300; - $link.toggleClass('token-open'); - $content.slideToggle(animationDuration); -} - -function itemLinkToContent($link) { - return $link.parent().parent().next(); -} - -// On doc load + hash-change, open any targetted item -function openCurrentItemIfClosed() { - if (window.jazzy.docset) { - return; - } - var $link = $(`.token[href="${location.hash}"]`); - $content = itemLinkToContent($link); - if ($content.is(':hidden')) { - toggleItem($link, $content); - } -} - -$(openCurrentItemIfClosed); -$(window).on('hashchange', openCurrentItemIfClosed); - -// On item link ('token') click, toggle its discussion -$('.token').on('click', function(event) { - if (window.jazzy.docset) { - return; - } - var $link = $(this); - toggleItem($link, itemLinkToContent($link)); - - // Keeps the document from jumping to the hash. - var href = $link.attr('href'); - if (history.pushState) { - history.pushState({}, '', href); - } else { - location.hash = href; - } - event.preventDefault(); -}); - -// Clicks on links to the current, closed, item need to open the item -$("a:not('.token')").on('click', function() { - if (location == this.href) { - openCurrentItemIfClosed(); - } -}); diff --git a/Documentation/js/jquery.min.js b/Documentation/js/jquery.min.js deleted file mode 100644 index a1c07fd..0000000 --- a/Documentation/js/jquery.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0Typealias used for colors. It maps to UIColor.

"},"Typealiases.html#/Font":{"name":"Font","abstract":"

Typealias used for fonts. It maps to UIFont.

"},"Typealiases.html#/s:7Capable5Colora":{"name":"Color","abstract":"

Typealias used for colors. It maps to NSColor.

"},"Typealiases.html#/s:7Capable4Fonta":{"name":"Font","abstract":"

Typealias used for fonts. It maps to NSFont.

"},"Typealiases.html#/Image":{"name":"Image","abstract":"

Typealias used for images. It maps to UIImage.

"},"Typealiases.html#/s:7Capable5Imagea":{"name":"Image","abstract":"

Typealias used for image. It maps to NSImage.

"},"Structs/HandicapStatus.html#/s:7Capable14HandicapStatusV8handicapAA0B0Vvp":{"name":"handicap","abstract":"

The Handicap that has changed.

","parent_name":"HandicapStatus"},"Structs/HandicapStatus.html#/s:7Capable14HandicapStatusV12statusStringSSvp":{"name":"statusString","abstract":"

The Handicap‘s status (enabled or disabled). Note that the status depends on the Handicap’s enabledIf value (see HandicapEnabledMode).

","parent_name":"HandicapStatus"},"Structs/Handicap.html#/s:7Capable8HandicapV8featuresSayAA0A7FeatureOGvp":{"name":"features","abstract":"

A list of CapableFeatures that are expected to be enabled if a user has this handicap.

","parent_name":"Handicap"},"Structs/Handicap.html#/s:7Capable8HandicapV4nameSSvp":{"name":"name","abstract":"

The name of the Handicap that can be used to uniquely identify the Handicap. This name is also used inside the status map.

","parent_name":"Handicap"},"Structs/Handicap.html#/s:7Capable8HandicapV9enabledIfAA0B11EnabledModeOvp":{"name":"enabledIf","abstract":"

This mode defines whether all features need to be enabled to set the Handicap‘s status to enabled or only one of them.

","parent_name":"Handicap"},"Structs/Handicap.html#/s:7Capable8HandicapV8features4name9enabledIfACSayAA0A7FeatureOG_SSAA0B11EnabledModeOtcfc":{"name":"init(features:name:enabledIf:)","abstract":"

Initializes a new Handicap object.

","parent_name":"Handicap"},"Structs/FeatureStatus.html#/s:7Capable13FeatureStatusV7featureAA0aB0Ovp":{"name":"feature","abstract":"

The feature type.

","parent_name":"FeatureStatus"},"Structs/FeatureStatus.html#/s:7Capable13FeatureStatusV12statusStringSSvp":{"name":"statusString","abstract":"

The feature’s status: While most features can only have a status set to enabled or disabled, the ‘.largerText` feature offers the font scale set by the user.

","parent_name":"FeatureStatus"},"Structs/Capable.html#/s:7CapableAAV12withFeaturesABSayAA0A7FeatureOG_tcfc":{"name":"init(withFeatures:)","abstract":"

Initializes the framework instance with a specified set of features. If no feature was provided, this defaults to all features available on the current platform.

","parent_name":"Capable"},"Structs/Capable.html#/s:7CapableAAV13withHandicapsABSayAA8HandicapVG_tcfc":{"name":"init(withHandicaps:)","abstract":"

Initializes the framework instance with a set of Handicaps.

","parent_name":"Capable"},"Structs/Capable.html#/s:7CapableAAV9statusMapSDyS2SGvp":{"name":"statusMap","abstract":"

The statusMap property returns a dictionary of all CapableFeatures or Handicaps , that the Capable instance has been initialized with along with their current statuses. This object is compatible with most analytic SDKs such as Fabric Answers, Firebase Analytics, AppCenter Analytics, or HockeyApp.","parent_name":"Capable"},"Structs/Capable.html#/s:7CapableAAV16isFeatureEnabled7featureSbAA0aC0O_tF":{"name":"isFeatureEnabled(feature:)","abstract":"

Provides information regarding the current status of a provided feature.

","parent_name":"Capable"},"Structs/Capable.html#/s:7CapableAAV17isHandicapEnabled12handicapNameSbSS_tF":{"name":"isHandicapEnabled(handicapName:)","abstract":"

Provides information regarding the current status of a provided Handicap.

","parent_name":"Capable"},"Structs/Capable.html#/s:7CapableAAV10minLogTypeSo13os_log_type_tavpZ":{"name":"minLogType","abstract":"

The minimum log level that should be considered when logging messages. Note that the custom ‘onLog’ closure will only be called for messages of this log type or higher. This value defaults to OSLogType.debug.

","parent_name":"Capable"},"Structs/Capable.html#/s:7CapableAAV5onLogyySS_So13os_log_type_tatcvpZ":{"name":"onLog","abstract":"

A custom closure that should be used by the logger for all Capable instances instead of the default os_log implementation.

","parent_name":"Capable"},"Structs/Capable.html":{"name":"Capable","abstract":"

This class defines the main interface of the Capable framework.

"},"Structs/FeatureStatus.html":{"name":"FeatureStatus","abstract":"

Model class that describes the content of a Capable notification (see Notification.Name.CapableFeatureStatusDidChange)

"},"Structs/Handicap.html":{"name":"Handicap","abstract":"

Model class that groups a number of CapableFeatures to represent a user’s handicap.

"},"Structs/HandicapStatus.html":{"name":"HandicapStatus","abstract":"

Model class that describes the content of a Capable notification (see Notification.Name.CapableHandicapStatusDidChange)

"},"Extensions/UIFont.html#/scaledFont(for:)":{"name":"scaledFont(for:)","abstract":"

Makes the given font scalable.

","parent_name":"UIFont"},"Extensions/UIFont.html#/scaledFont(withName:ofSize:)":{"name":"scaledFont(withName:ofSize:)","abstract":"

Creates a scalable font with the given font name and reference font size.

","parent_name":"UIFont"},"Extensions/UIFont.html#/scaledSystemFont(ofSize:)":{"name":"scaledSystemFont(ofSize:)","abstract":"

Creates a scalable system font with a given reference font size.

","parent_name":"UIFont"},"Extensions/UIFont.html#/scaledBoldSystemFont(ofSize:)":{"name":"scaledBoldSystemFont(ofSize:)","abstract":"

Creates a scalable bold system font with a given reference font size.

","parent_name":"UIFont"},"Extensions/UIFont.html#/scaledItalicSystemFont(ofSize:)":{"name":"scaledItalicSystemFont(ofSize:)","abstract":"

Creates a scalable italic system font with a given reference font size.

","parent_name":"UIFont"},"Extensions/Notification/Name.html#/s:So18NSNotificationNamea7CapableE0C22FeatureStatusDidChangeABvpZ":{"name":"CapableFeatureStatusDidChange","abstract":"

Name of the notification that gets fired whenever an observed accessibility feature status changes.

","parent_name":"Name"},"Extensions/Notification/Name.html#/s:So18NSNotificationNamea7CapableE0C23HandicapStatusDidChangeABvpZ":{"name":"CapableHandicapStatusDidChange","abstract":"

Name of the notification that gets fired whenever an observed Handicap status changes.

","parent_name":"Name"},"Extensions/Notification/Name.html":{"name":"Name","abstract":"

Extension that defines notification names provided by the Capable framework.

","parent_name":"Notification"},"Extensions/Color.html#/s:So7NSColorC7CapableE16getContrastRatio12forTextColor012onBackgroundH012CoreGraphics7CGFloatVSgAB_ABtFZ":{"name":"getContrastRatio(forTextColor:onBackgroundColor:)","abstract":"

Calculates the color ratio for a text color on a background color.

","parent_name":"Color"},"Extensions/Color.html#/s:So7NSColorC7CapableE12getTextColor012onBackgroundE0ABSgAB_tFZ":{"name":"getTextColor(onBackgroundColor:)","abstract":"

Returns the text color with the highest contrast (black or white) for a given background color.

","parent_name":"Color"},"Extensions/Color.html#/s:So7NSColorC7CapableE12getTextColor10fromColors8withFont012onBackgroundE016conformanceLevelABSgSayABG_So6NSFontCAbC011ConformanceM0OtFZ":{"name":"getTextColor(fromColors:withFont:onBackgroundColor:conformanceLevel:)","abstract":"

Calculates the contrast ratio of a given list of text colors and a background color. The first color that conforms to the conformance level defined gets returned. The default conformance level is .AA.

","parent_name":"Color"},"Extensions/Color.html#/s:So7NSColorC7CapableE12getTextColor17onBackgroundImage9imageAreaABSgSo7NSImageC_AC0hJ0OtFZ":{"name":"getTextColor(onBackgroundImage:imageArea:)","abstract":"

Returns the text color with the highest contrast (black or white) for a specific area of given background image.

","parent_name":"Color"},"Extensions/Color.html#/s:So7NSColorC7CapableE12getTextColor10fromColors8withFont17onBackgroundImage9imageArea16conformanceLevelABSgSayABG_So6NSFontCSo7NSImageCAC0lN0OAC011ConformanceP0OtFZ":{"name":"getTextColor(fromColors:withFont:onBackgroundImage:imageArea:conformanceLevel:)","abstract":"

Calculates the contrast ratio of a given list of text colors and a specific area of given background image. The first color that conforms to the conformance level defined gets returned. The default conformance level is .AA.

","parent_name":"Color"},"Extensions/Color.html#/s:So7NSColorC7CapableE18getBackgroundColor07forTextE0ABSgAB_tFZ":{"name":"getBackgroundColor(forTextColor:)","abstract":"

Returns the background color with the highest contrast (black or white) for a given text color.

","parent_name":"Color"},"Extensions/Color.html#/s:So7NSColorC7CapableE18getBackgroundColor10fromColors07forTextE08withFont16conformanceLevelABSgSayABG_ABSo6NSFontCAC011ConformanceM0OtFZ":{"name":"getBackgroundColor(fromColors:forTextColor:withFont:conformanceLevel:)","abstract":"

Calculates the contrast ratio of a given list of background colors and a text color. The first color that conforms to the conformance level defined gets returned. The default conformance level is .AA.

","parent_name":"Color"},"Extensions/Color.html":{"name":"Color","abstract":"

Extension that adds functionality for calculating WCAG compliant high contrast colors.

"},"Extensions/Notification.html":{"name":"Notification"},"Extensions/UIFont.html":{"name":"UIFont","abstract":"

Extension that adds functionality for creating scalable UIFont objects.

"},"Enums/HandicapEnabledMode.html#/s:7Capable19HandicapEnabledModeO010oneFeatureC0yA2CmF":{"name":"oneFeatureEnabled","abstract":"

The Handicap‘s status is enabled if one of its features is currently set to enabled.

","parent_name":"HandicapEnabledMode"},"Enums/HandicapEnabledMode.html#/s:7Capable19HandicapEnabledModeO011allFeaturesC0yA2CmF":{"name":"allFeaturesEnabled","abstract":"

The Handicap‘s status is enabled if all its features are currently set to enabled.

","parent_name":"HandicapEnabledMode"},"Enums/CapableFeature.html#/assistiveTouch":{"name":"assistiveTouch","abstract":"

Menu that helps people with motor skill impairments to do certain actions or gestures by using a single tap.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/darkerSystemColors":{"name":"darkerSystemColors","abstract":"

Enhances text contrast.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/guidedAccess":{"name":"guidedAccess","abstract":"

Restricts access to certain features of a single app to keep the user focused.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/hearingDevice":{"name":"hearingDevice","abstract":"

Pairing status of a hearing aid.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/onOffSwitchLabels":{"name":"onOffSwitchLabels","abstract":"

Displays on/off labels for UISwitch controls.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/shakeToUndo":{"name":"shakeToUndo","abstract":"

Deletes the last command by shaking the phone.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/speakScreen":{"name":"speakScreen","abstract":"

Reads out the content of the current screen.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/speakSelection":{"name":"speakSelection","abstract":"

Reads out the selected content.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/s:7Capable0A7FeatureO18fullKeyboardAccessyA2CmF":{"name":"fullKeyboardAccess","abstract":"

Enables users to navigate through items of the screen without having to use a mouse.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/s:7Capable0A7FeatureO16increaseContrastyA2CmF":{"name":"increaseContrast","abstract":"

Increases contrast to make out text and interface elements.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/closedCaptioning":{"name":"closedCaptioning","abstract":"

Displays subtitles when playing videos.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/grayscale":{"name":"grayscale","abstract":"

Makes the display more readable for color blind people by using gray tones instead of colors.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/monoAudio":{"name":"monoAudio","abstract":"

Merges stereo audio channels to help users that are hard of hearing or deaf in one ear.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/videoAutoplay":{"name":"videoAutoplay","abstract":"

Allows users who are sensitive to motion to disable automatic video playback.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/largerText":{"name":"largerText","abstract":"

Increases legibility by making fonts bigger.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/s:7Capable0A7FeatureO25differentiateWithoutColoryA2CmF":{"name":"differentiateWithoutColor","abstract":"

Helps color blind users to differentiate settings differently, e.g. by using shapes rather than colors.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/s:7Capable0A7FeatureO12invertColorsyA2CmF":{"name":"invertColors","abstract":"

Helps people with low vision, color blindness, or sensitivity to brightness to read the display content.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/s:7Capable0A7FeatureO18reduceTransparencyyA2CmF":{"name":"reduceTransparency","abstract":"

Removes transparency from layers to make them readable for users with visual impairment.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/s:7Capable0A7FeatureO13switchControlyA2CmF":{"name":"switchControl","abstract":"

Allows users with limited mobility to control their device with the help of ability switches and other adaptive devices.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/boldText":{"name":"boldText","abstract":"

Increases legibility by making fonts heavier.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/s:7Capable0A7FeatureO12reduceMotionyA2CmF":{"name":"reduceMotion","abstract":"

Reduces animations to help users with motion sickness and epilepsy issues.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/s:7Capable0A7FeatureO9voiceOveryA2CmF":{"name":"voiceOver","abstract":"

The screen reader available on Apple platforms.

","parent_name":"CapableFeature"},"Enums/CapableFeature.html#/s:7Capable0A7FeatureO4keys11forFeaturesSaySSGSayACG_tFZ":{"name":"keys(forFeatures:)","abstract":"

Iterates through a given list of feature types and returns an array containing the feature names as strings.

","parent_name":"CapableFeature"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO4fullyA2CmF":{"name":"full","abstract":"

The full image size.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO6bottomyA2CmF":{"name":"bottom","abstract":"

The last vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO12bottomCenteryA2CmF":{"name":"bottomCenter","abstract":"

The second horizontal third of the last vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO10bottomLeftyA2CmF":{"name":"bottomLeft","abstract":"

The first horizontal third of the last vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO11bottomRightyA2CmF":{"name":"bottomRight","abstract":"

The last horizontal third of the last vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO6centeryA2CmF":{"name":"center","abstract":"

The second horizontal third of the second vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO10centerLeftyA2CmF":{"name":"centerLeft","abstract":"

The first horizontal third of the second vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO11centerRightyA2CmF":{"name":"centerRight","abstract":"

The last horizontal third of the second vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO6customyACSo6CGRectV_tcACmF":{"name":"custom(rect:)","abstract":"

A custom area of the image defined by a CGRect.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO16horizontalCenteryA2CmF":{"name":"horizontalCenter","abstract":"

The second vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO4leftyA2CmF":{"name":"left","abstract":"

The first horizontal third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO5rightyA2CmF":{"name":"right","abstract":"

The last horizontal third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO3topyA2CmF":{"name":"top","abstract":"

The first vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO9topCenteryA2CmF":{"name":"topCenter","abstract":"

The second horizontal third of the first vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO7topLeftyA2CmF":{"name":"topLeft","abstract":"

The first horizontal third of the first vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO8topRightyA2CmF":{"name":"topRight","abstract":"

The last horizontal third of the first vertical third.

","parent_name":"ImageArea"},"Enums/ImageArea.html#/s:7Capable9ImageAreaO14verticalCenteryA2CmF":{"name":"verticalCenter","abstract":"

The second horizontal third.

","parent_name":"ImageArea"},"Enums/ConformanceLevel.html#/s:7Capable16ConformanceLevelO1AyA2CmF":{"name":"A","abstract":"

The minimum level of conformance.

","parent_name":"ConformanceLevel"},"Enums/ConformanceLevel.html#/s:7Capable16ConformanceLevelO2AAyA2CmF":{"name":"AA","abstract":"

The medium level of conformance including success criterias of level A.

","parent_name":"ConformanceLevel"},"Enums/ConformanceLevel.html#/s:7Capable16ConformanceLevelO3AAAyA2CmF":{"name":"AAA","abstract":"

The highest level of conformance including success criterias of level A and AA.

","parent_name":"ConformanceLevel"},"Enums/ConformanceLevel.html#/s:7Capable16ConformanceLevelO6failedyA2CmF":{"name":"failed","abstract":"

Indicates that no level of conformance has been reached.

","parent_name":"ConformanceLevel"},"Enums/ConformanceLevel.html#/s:7Capable16ConformanceLevelO13contrastRatio8fontSize10isBoldFontAC12CoreGraphics7CGFloatV_AISbtcfc":{"name":"init(contrastRatio:fontSize:isBoldFont:)","abstract":"

Initializes a ConformanceLevel based on a given contrast ratio and font information used for the text.

","parent_name":"ConformanceLevel"},"Enums/ConformanceLevel.html#/s:7Capable16ConformanceLevelO4textSSvp":{"name":"text","abstract":"

The text representation of the conformance level.

","parent_name":"ConformanceLevel"},"Enums/ConformanceLevel.html":{"name":"ConformanceLevel","abstract":"

An enum specifying all WCAG conformance levels.

"},"Enums/ImageArea.html":{"name":"ImageArea","abstract":"

Undocumented

"},"Enums/CapableFeature.html":{"name":"CapableFeature","abstract":"

An enum specifying all features available on the current platform.

"},"Enums/HandicapEnabledMode.html":{"name":"HandicapEnabledMode","abstract":"

This enum defines several modes which describe whether all features need to be enabled to set the Handicap‘s status to enabled or only one of them.

"},"Enums.html":{"name":"Enumerations","abstract":"

The following enumerations are available globally.

"},"Extensions.html":{"name":"Extensions","abstract":"

The following extensions are available globally.

"},"Structs.html":{"name":"Structures","abstract":"

The following structures are available globally.

"},"Typealiases.html":{"name":"Type Aliases","abstract":"

The following type aliases are available globally.

"}} \ No newline at end of file diff --git a/Documentation/undocumented.json b/Documentation/undocumented.json deleted file mode 100644 index 38d6a7e..0000000 --- a/Documentation/undocumented.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "warnings": [ - { - "file": "/Users/d0286949/Documents/Workspace/Capable/Source/Colors/Models/ImageArea.swift", - "line": 12, - "symbol": "ImageArea", - "symbol_kind": "source.lang.swift.decl.enum", - "warning": "undocumented" - } - ], - "source_directory": "/Users/d0286949/Documents/Workspace/Capable" -} \ No newline at end of file diff --git a/Example/Example.xcodeproj/project.pbxproj b/Example/Example.xcodeproj/project.pbxproj index e413dec..658a4a2 100644 --- a/Example/Example.xcodeproj/project.pbxproj +++ b/Example/Example.xcodeproj/project.pbxproj @@ -7,15 +7,105 @@ objects = { /* Begin PBXBuildFile section */ + 0450E523122D2663B49B0F3D /* Pods_Tests_macOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B78C620EDD88E25833A2D67 /* Pods_Tests_macOS.framework */; }; + 0D1A1A4F2381DEF54EEEABCC /* Pods_Tests_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D3608C5EC986382E365A8FF4 /* Pods_Tests_iOS.framework */; }; 29882843319156428E5159E1 /* Pods_Example_macOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A9D86F10DB1D691B906F54E /* Pods_Example_macOS.framework */; }; 4478927B210B4073000D5939 /* FontsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4478927A210B4073000D5939 /* FontsViewController.swift */; }; 4478927D210B4288000D5939 /* FontRowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4478927C210B4288000D5939 /* FontRowController.swift */; }; 4478927E210B4401000D5939 /* Cardo-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 83C6F6232078138D00F0C74D /* Cardo-Regular.ttf */; }; 44789280210B4AEA000D5939 /* FontsConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4478927F210B4AEA000D5939 /* FontsConstants.swift */; }; 44789281210B4AED000D5939 /* FontsConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4478927F210B4AEA000D5939 /* FontsConstants.swift */; }; + 4494E5DE23550E5A0082C217 /* NotificationsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5BF23550BF00082C217 /* NotificationsTests.swift */; }; + 4494E5DF23550E5A0082C217 /* HandicapNotificationsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C023550BF00082C217 /* HandicapNotificationsTests.swift */; }; + 4494E5E023550E5A0082C217 /* CapableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C123550BF00082C217 /* CapableTests.swift */; }; + 4494E5E123550E5A0082C217 /* FeatureNotificationsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C223550BF00082C217 /* FeatureNotificationsTests.swift */; }; + 4494E5E223550E5A0082C217 /* FeatureStatusesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C323550BF00082C217 /* FeatureStatusesTests.swift */; }; + 4494E5E323550E5A0082C217 /* HandicapStatusesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C423550BF00082C217 /* HandicapStatusesTests.swift */; }; + 4494E5E423550E5A0082C217 /* FeatureStatusesProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C523550BF00082C217 /* FeatureStatusesProviderTests.swift */; }; + 4494E5E523550E5A0082C217 /* HandicapTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C623550BF00082C217 /* HandicapTests.swift */; }; + 4494E5E623550E5A0082C217 /* CapablePerfTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C723550BF00082C217 /* CapablePerfTests.swift */; }; + 4494E5E723550E5A0082C217 /* NotificationsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5BF23550BF00082C217 /* NotificationsTests.swift */; }; + 4494E5E823550E5A0082C217 /* HandicapNotificationsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C023550BF00082C217 /* HandicapNotificationsTests.swift */; }; + 4494E5E923550E5A0082C217 /* CapableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C123550BF00082C217 /* CapableTests.swift */; }; + 4494E5EA23550E5A0082C217 /* FeatureNotificationsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C223550BF00082C217 /* FeatureNotificationsTests.swift */; }; + 4494E5EB23550E5A0082C217 /* FeatureStatusesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C323550BF00082C217 /* FeatureStatusesTests.swift */; }; + 4494E5EC23550E5A0082C217 /* HandicapStatusesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C423550BF00082C217 /* HandicapStatusesTests.swift */; }; + 4494E5ED23550E5A0082C217 /* FeatureStatusesProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C523550BF00082C217 /* FeatureStatusesProviderTests.swift */; }; + 4494E5EE23550E5A0082C217 /* HandicapTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C623550BF00082C217 /* HandicapTests.swift */; }; + 4494E5EF23550E5A0082C217 /* CapablePerfTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C723550BF00082C217 /* CapablePerfTests.swift */; }; + 4494E5F023550E5B0082C217 /* NotificationsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5BF23550BF00082C217 /* NotificationsTests.swift */; }; + 4494E5F123550E5B0082C217 /* HandicapNotificationsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C023550BF00082C217 /* HandicapNotificationsTests.swift */; }; + 4494E5F223550E5B0082C217 /* CapableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C123550BF00082C217 /* CapableTests.swift */; }; + 4494E5F323550E5B0082C217 /* FeatureNotificationsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C223550BF00082C217 /* FeatureNotificationsTests.swift */; }; + 4494E5F423550E5B0082C217 /* FeatureStatusesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C323550BF00082C217 /* FeatureStatusesTests.swift */; }; + 4494E5F523550E5B0082C217 /* HandicapStatusesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C423550BF00082C217 /* HandicapStatusesTests.swift */; }; + 4494E5F623550E5B0082C217 /* FeatureStatusesProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C523550BF00082C217 /* FeatureStatusesProviderTests.swift */; }; + 4494E5F723550E5B0082C217 /* HandicapTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C623550BF00082C217 /* HandicapTests.swift */; }; + 4494E5F823550E5B0082C217 /* CapablePerfTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C723550BF00082C217 /* CapablePerfTests.swift */; }; + 4494E5F923550E670082C217 /* HandicapStatusesMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5BB23550BF00082C217 /* HandicapStatusesMock.swift */; }; + 4494E5FA23550E670082C217 /* NotificationCenterMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5BC23550BF00082C217 /* NotificationCenterMock.swift */; }; + 4494E5FB23550E670082C217 /* FeatureStatusesProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5BD23550BF00082C217 /* FeatureStatusesProviderMock.swift */; }; + 4494E5FC23550E670082C217 /* FeatureStatusesMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5BE23550BF00082C217 /* FeatureStatusesMock.swift */; }; + 4494E5FD23550E680082C217 /* HandicapStatusesMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5BB23550BF00082C217 /* HandicapStatusesMock.swift */; }; + 4494E5FE23550E680082C217 /* NotificationCenterMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5BC23550BF00082C217 /* NotificationCenterMock.swift */; }; + 4494E5FF23550E680082C217 /* FeatureStatusesProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5BD23550BF00082C217 /* FeatureStatusesProviderMock.swift */; }; + 4494E60023550E680082C217 /* FeatureStatusesMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5BE23550BF00082C217 /* FeatureStatusesMock.swift */; }; + 4494E60123550E690082C217 /* HandicapStatusesMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5BB23550BF00082C217 /* HandicapStatusesMock.swift */; }; + 4494E60223550E690082C217 /* NotificationCenterMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5BC23550BF00082C217 /* NotificationCenterMock.swift */; }; + 4494E60323550E690082C217 /* FeatureStatusesProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5BD23550BF00082C217 /* FeatureStatusesProviderMock.swift */; }; + 4494E60423550E690082C217 /* FeatureStatusesMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5BE23550BF00082C217 /* FeatureStatusesMock.swift */; }; + 4494E60523550ECA0082C217 /* LoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C923550BF00082C217 /* LoggerTests.swift */; }; + 4494E60623550ECB0082C217 /* LoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C923550BF00082C217 /* LoggerTests.swift */; }; + 4494E60723550ECC0082C217 /* LoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5C923550BF00082C217 /* LoggerTests.swift */; }; + 4494E60823550ED40082C217 /* NSFontFontPropsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5CD23550BF00082C217 /* NSFontFontPropsTests.swift */; }; + 4494E60923550ED40082C217 /* ImageAreaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5CE23550BF00082C217 /* ImageAreaTests.swift */; }; + 4494E60A23550ED40082C217 /* ColorWcagTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5CF23550BF00082C217 /* ColorWcagTests.swift */; }; + 4494E60B23550ED40082C217 /* FontPropsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D023550BF00082C217 /* FontPropsTests.swift */; }; + 4494E60C23550ED40082C217 /* UIFontFontPropsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D123550BF00082C217 /* UIFontFontPropsTests.swift */; }; + 4494E60D23550ED40082C217 /* RGBAColorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D223550BF00082C217 /* RGBAColorTests.swift */; }; + 4494E60E23550ED40082C217 /* ImageAverageColorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D323550BF00082C217 /* ImageAverageColorTests.swift */; }; + 4494E60F23550ED40082C217 /* ConformanceLevelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D423550BF00082C217 /* ConformanceLevelTests.swift */; }; + 4494E61023550ED50082C217 /* NSFontFontPropsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5CD23550BF00082C217 /* NSFontFontPropsTests.swift */; }; + 4494E61123550ED50082C217 /* ImageAreaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5CE23550BF00082C217 /* ImageAreaTests.swift */; }; + 4494E61223550ED50082C217 /* ColorWcagTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5CF23550BF00082C217 /* ColorWcagTests.swift */; }; + 4494E61323550ED50082C217 /* FontPropsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D023550BF00082C217 /* FontPropsTests.swift */; }; + 4494E61423550ED50082C217 /* UIFontFontPropsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D123550BF00082C217 /* UIFontFontPropsTests.swift */; }; + 4494E61523550ED50082C217 /* RGBAColorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D223550BF00082C217 /* RGBAColorTests.swift */; }; + 4494E61623550ED50082C217 /* ImageAverageColorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D323550BF00082C217 /* ImageAverageColorTests.swift */; }; + 4494E61723550ED50082C217 /* ConformanceLevelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D423550BF00082C217 /* ConformanceLevelTests.swift */; }; + 4494E61823550ED50082C217 /* NSFontFontPropsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5CD23550BF00082C217 /* NSFontFontPropsTests.swift */; }; + 4494E61923550ED50082C217 /* ImageAreaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5CE23550BF00082C217 /* ImageAreaTests.swift */; }; + 4494E61A23550ED50082C217 /* ColorWcagTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5CF23550BF00082C217 /* ColorWcagTests.swift */; }; + 4494E61B23550ED50082C217 /* FontPropsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D023550BF00082C217 /* FontPropsTests.swift */; }; + 4494E61C23550ED50082C217 /* UIFontFontPropsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D123550BF00082C217 /* UIFontFontPropsTests.swift */; }; + 4494E61D23550ED50082C217 /* RGBAColorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D223550BF00082C217 /* RGBAColorTests.swift */; }; + 4494E61E23550ED50082C217 /* ImageAverageColorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D323550BF00082C217 /* ImageAverageColorTests.swift */; }; + 4494E61F23550ED50082C217 /* ConformanceLevelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D423550BF00082C217 /* ConformanceLevelTests.swift */; }; + 4494E62023550EE40082C217 /* Image+mock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5CC23550BF00082C217 /* Image+mock.swift */; }; + 4494E62123550EE40082C217 /* Image+mock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5CC23550BF00082C217 /* Image+mock.swift */; }; + 4494E62223550EE40082C217 /* Image+mock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5CC23550BF00082C217 /* Image+mock.swift */; }; + 4494E62323550F240082C217 /* FontMetricsProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5DB23550BF00082C217 /* FontMetricsProviderTests.swift */; }; + 4494E62423550F240082C217 /* FontMetricsSupportTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5DA23550BF00082C217 /* FontMetricsSupportTests.swift */; }; + 4494E62523550F240082C217 /* FontMetricsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5DC23550BF00082C217 /* FontMetricsTests.swift */; }; + 4494E62623550F240082C217 /* FontMetricsProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5DB23550BF00082C217 /* FontMetricsProviderTests.swift */; }; + 4494E62723550F240082C217 /* FontMetricsSupportTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5DA23550BF00082C217 /* FontMetricsSupportTests.swift */; }; + 4494E62823550F240082C217 /* FontMetricsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5DC23550BF00082C217 /* FontMetricsTests.swift */; }; + 4494E62923550F250082C217 /* FontMetricsProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5DB23550BF00082C217 /* FontMetricsProviderTests.swift */; }; + 4494E62A23550F250082C217 /* FontMetricsSupportTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5DA23550BF00082C217 /* FontMetricsSupportTests.swift */; }; + 4494E62B23550F250082C217 /* FontMetricsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5DC23550BF00082C217 /* FontMetricsTests.swift */; }; + 4494E62C23550F360082C217 /* FontMetricsMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D823550BF00082C217 /* FontMetricsMock.swift */; }; + 4494E62D23550F360082C217 /* FontMetricsProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D723550BF00082C217 /* FontMetricsProviderMock.swift */; }; + 4494E62E23550F360082C217 /* OsVersionProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D923550BF00082C217 /* OsVersionProviderMock.swift */; }; + 4494E62F23550F360082C217 /* FontMetricsMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D823550BF00082C217 /* FontMetricsMock.swift */; }; + 4494E63023550F360082C217 /* FontMetricsProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D723550BF00082C217 /* FontMetricsProviderMock.swift */; }; + 4494E63123550F360082C217 /* OsVersionProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D923550BF00082C217 /* OsVersionProviderMock.swift */; }; + 4494E63223550F380082C217 /* FontMetricsMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D823550BF00082C217 /* FontMetricsMock.swift */; }; + 4494E63323550F380082C217 /* FontMetricsProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D723550BF00082C217 /* FontMetricsProviderMock.swift */; }; + 4494E63423550F380082C217 /* OsVersionProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4494E5D923550BF00082C217 /* OsVersionProviderMock.swift */; }; 44D0B935233F833900A9B136 /* CaptionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44FD13172336CD3B001C6C7A /* CaptionsViewController.swift */; }; 44D0B93A233F926100A9B136 /* CaptionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44D0B938233F900700A9B136 /* CaptionsViewController.swift */; }; 44FD13182336CD3B001C6C7A /* CaptionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44FD13172336CD3B001C6C7A /* CaptionsViewController.swift */; }; + 4CE26EFC3410DC97869F3522 /* Pods_Tests_tvOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDACB4A868A3168E8898DF12 /* Pods_Tests_tvOS.framework */; }; 55A2015AF8E67D0BAC01DA73 /* Pods_Example_watchOS_Extension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 06A4614933CCE311EC4CAD3C /* Pods_Example_watchOS_Extension.framework */; }; 6180FD25002FD5791E4E3C36 /* Pods_Example_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61C8CF8E1603FFD70061B7CA /* Pods_Example_iOS.framework */; }; 791054B3341540F931275BD6 /* Pods_Example_watchOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CDA97E99795B6631F2DB0EB5 /* Pods_Example_watchOS.framework */; }; @@ -64,6 +154,27 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 4494E59723550B700082C217 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 83C6F5D420780FE700F0C74D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 83C6F5DB20780FE700F0C74D; + remoteInfo = "Example-iOS"; + }; + 4494E5A523550B870082C217 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 83C6F5D420780FE700F0C74D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 832953D321121EAA00072EB9; + remoteInfo = "Example-macOS"; + }; + 4494E5B323550BA30082C217 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 83C6F5D420780FE700F0C74D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 831B4F1320A4D4F200F1BB94; + remoteInfo = "Example-tvOS"; + }; 837C192420AA27970003D237 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 83C6F5D420780FE700F0C74D /* Project object */; @@ -129,15 +240,54 @@ 06A4614933CCE311EC4CAD3C /* Pods_Example_watchOS_Extension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example_watchOS_Extension.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 0DC32891E19486D26B764F86 /* Pods-Example-watchOS Extension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-watchOS Extension.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Example-watchOS Extension/Pods-Example-watchOS Extension.debug.xcconfig"; sourceTree = ""; }; 1004E7F9A4E366DF66B525B0 /* Pods-Example-watchOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-watchOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Example-watchOS/Pods-Example-watchOS.release.xcconfig"; sourceTree = ""; }; + 1021B1BF9523C4E2D4946FE7 /* Pods-Tests-iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests-iOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Tests-iOS/Pods-Tests-iOS.debug.xcconfig"; sourceTree = ""; }; 1A9D86F10DB1D691B906F54E /* Pods_Example_macOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example_macOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 2718FA59414252A3E57D1724 /* Pods-Tests-macOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests-macOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Tests-macOS/Pods-Tests-macOS.debug.xcconfig"; sourceTree = ""; }; 4478927A210B4073000D5939 /* FontsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontsViewController.swift; sourceTree = ""; }; 4478927C210B4288000D5939 /* FontRowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontRowController.swift; sourceTree = ""; }; 4478927F210B4AEA000D5939 /* FontsConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontsConstants.swift; sourceTree = ""; }; + 4494E59223550B700082C217 /* Tests-iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Tests-iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4494E59623550B700082C217 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 4494E5A023550B870082C217 /* Tests-macOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Tests-macOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4494E5A423550B870082C217 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 4494E5AE23550BA30082C217 /* Tests-tvOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Tests-tvOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4494E5B223550BA30082C217 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 4494E5BB23550BF00082C217 /* HandicapStatusesMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HandicapStatusesMock.swift; sourceTree = ""; }; + 4494E5BC23550BF00082C217 /* NotificationCenterMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationCenterMock.swift; sourceTree = ""; }; + 4494E5BD23550BF00082C217 /* FeatureStatusesProviderMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureStatusesProviderMock.swift; sourceTree = ""; }; + 4494E5BE23550BF00082C217 /* FeatureStatusesMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureStatusesMock.swift; sourceTree = ""; }; + 4494E5BF23550BF00082C217 /* NotificationsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsTests.swift; sourceTree = ""; }; + 4494E5C023550BF00082C217 /* HandicapNotificationsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HandicapNotificationsTests.swift; sourceTree = ""; }; + 4494E5C123550BF00082C217 /* CapableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CapableTests.swift; sourceTree = ""; }; + 4494E5C223550BF00082C217 /* FeatureNotificationsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureNotificationsTests.swift; sourceTree = ""; }; + 4494E5C323550BF00082C217 /* FeatureStatusesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureStatusesTests.swift; sourceTree = ""; }; + 4494E5C423550BF00082C217 /* HandicapStatusesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HandicapStatusesTests.swift; sourceTree = ""; }; + 4494E5C523550BF00082C217 /* FeatureStatusesProviderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureStatusesProviderTests.swift; sourceTree = ""; }; + 4494E5C623550BF00082C217 /* HandicapTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HandicapTests.swift; sourceTree = ""; }; + 4494E5C723550BF00082C217 /* CapablePerfTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CapablePerfTests.swift; sourceTree = ""; }; + 4494E5C923550BF00082C217 /* LoggerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggerTests.swift; sourceTree = ""; }; + 4494E5CC23550BF00082C217 /* Image+mock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Image+mock.swift"; sourceTree = ""; }; + 4494E5CD23550BF00082C217 /* NSFontFontPropsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSFontFontPropsTests.swift; sourceTree = ""; }; + 4494E5CE23550BF00082C217 /* ImageAreaTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageAreaTests.swift; sourceTree = ""; }; + 4494E5CF23550BF00082C217 /* ColorWcagTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorWcagTests.swift; sourceTree = ""; }; + 4494E5D023550BF00082C217 /* FontPropsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontPropsTests.swift; sourceTree = ""; }; + 4494E5D123550BF00082C217 /* UIFontFontPropsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFontFontPropsTests.swift; sourceTree = ""; }; + 4494E5D223550BF00082C217 /* RGBAColorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RGBAColorTests.swift; sourceTree = ""; }; + 4494E5D323550BF00082C217 /* ImageAverageColorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageAverageColorTests.swift; sourceTree = ""; }; + 4494E5D423550BF00082C217 /* ConformanceLevelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConformanceLevelTests.swift; sourceTree = ""; }; + 4494E5D723550BF00082C217 /* FontMetricsProviderMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontMetricsProviderMock.swift; sourceTree = ""; }; + 4494E5D823550BF00082C217 /* FontMetricsMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontMetricsMock.swift; sourceTree = ""; }; + 4494E5D923550BF00082C217 /* OsVersionProviderMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OsVersionProviderMock.swift; sourceTree = ""; }; + 4494E5DA23550BF00082C217 /* FontMetricsSupportTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontMetricsSupportTests.swift; sourceTree = ""; }; + 4494E5DB23550BF00082C217 /* FontMetricsProviderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontMetricsProviderTests.swift; sourceTree = ""; }; + 4494E5DC23550BF00082C217 /* FontMetricsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontMetricsTests.swift; sourceTree = ""; }; 44D0B938233F900700A9B136 /* CaptionsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CaptionsViewController.swift; sourceTree = ""; }; 44FD13172336CD3B001C6C7A /* CaptionsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CaptionsViewController.swift; sourceTree = ""; }; 4A59D50AB7E59EBA9F953814 /* Pods-Example-watchOS Extension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-watchOS Extension.release.xcconfig"; path = "Pods/Target Support Files/Pods-Example-watchOS Extension/Pods-Example-watchOS Extension.release.xcconfig"; sourceTree = ""; }; + 4E60CC370BEED5BC72BF9333 /* Pods-Tests-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests-iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Tests-iOS/Pods-Tests-iOS.release.xcconfig"; sourceTree = ""; }; 61C8CF8E1603FFD70061B7CA /* Pods_Example_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 73A34BF8D95976311A017335 /* Pods_Example_tvOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example_tvOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7B78C620EDD88E25833A2D67 /* Pods_Tests_macOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Tests_macOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 831AA4DB212B356D00AEAC44 /* HandicapOverviewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HandicapOverviewController.swift; sourceTree = ""; }; 831B4F1420A4D4F200F1BB94 /* Example-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 831B4F1D20A4D4F200F1BB94 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; @@ -181,17 +331,46 @@ 83FF01FC2129FE8D00D26E0D /* HandicapViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HandicapViewController.swift; sourceTree = ""; }; 83FF01FE2129FEAB00D26E0D /* HandicapTableCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HandicapTableCellView.swift; sourceTree = ""; }; 83FF0203212B21C800D26E0D /* HandicapRowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HandicapRowController.swift; sourceTree = ""; }; + 8FF58CFC45A3E07A160D697E /* Pods-Tests-macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests-macOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Tests-macOS/Pods-Tests-macOS.release.xcconfig"; sourceTree = ""; }; 9C45A1F5FCFA4768DC33403B /* Pods-Example-macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-macOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Example-macOS/Pods-Example-macOS.release.xcconfig"; sourceTree = ""; }; A5DCF956DE661B9787EAE334 /* Pods-Example-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Example-iOS/Pods-Example-iOS.release.xcconfig"; sourceTree = ""; }; A69A8636A1A206955AF20AA4 /* Pods-Example-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-tvOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Example-tvOS/Pods-Example-tvOS.debug.xcconfig"; sourceTree = ""; }; B607B9D61AC82056D25E2B77 /* Pods-Example-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-tvOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Example-tvOS/Pods-Example-tvOS.release.xcconfig"; sourceTree = ""; }; B707690BAFBA32861CBBF6F3 /* Pods-Example-iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-iOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Example-iOS/Pods-Example-iOS.debug.xcconfig"; sourceTree = ""; }; + BF9562DEC091BFDE381F3882 /* Pods-Tests-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests-tvOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Tests-tvOS/Pods-Tests-tvOS.release.xcconfig"; sourceTree = ""; }; + CCD5A28B0848B7B5B546E759 /* Pods-Tests-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests-tvOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Tests-tvOS/Pods-Tests-tvOS.debug.xcconfig"; sourceTree = ""; }; CDA97E99795B6631F2DB0EB5 /* Pods_Example_watchOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example_watchOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D3608C5EC986382E365A8FF4 /* Pods_Tests_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Tests_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; EB296F840F14F09371040629 /* Pods-Example-macOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-macOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Example-macOS/Pods-Example-macOS.debug.xcconfig"; sourceTree = ""; }; + EDACB4A868A3168E8898DF12 /* Pods_Tests_tvOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Tests_tvOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; FEECBAFC5F7980884EBE6AA3 /* Pods-Example-watchOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-watchOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Example-watchOS/Pods-Example-watchOS.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 4494E58F23550B700082C217 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 0D1A1A4F2381DEF54EEEABCC /* Pods_Tests_iOS.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4494E59D23550B870082C217 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 0450E523122D2663B49B0F3D /* Pods_Tests_macOS.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4494E5AB23550BA30082C217 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CE26EFC3410DC97869F3522 /* Pods_Tests_tvOS.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 831B4F1120A4D4F200F1BB94 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -235,6 +414,125 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 4494E59323550B700082C217 /* Tests-iOS */ = { + isa = PBXGroup; + children = ( + 4494E59623550B700082C217 /* Info.plist */, + ); + path = "Tests-iOS"; + sourceTree = ""; + }; + 4494E5A123550B870082C217 /* Tests-macOS */ = { + isa = PBXGroup; + children = ( + 4494E5A423550B870082C217 /* Info.plist */, + ); + path = "Tests-macOS"; + sourceTree = ""; + }; + 4494E5AF23550BA30082C217 /* Tests-tvOS */ = { + isa = PBXGroup; + children = ( + 4494E5B223550BA30082C217 /* Info.plist */, + ); + path = "Tests-tvOS"; + sourceTree = ""; + }; + 4494E5B823550BF00082C217 /* Tests */ = { + isa = PBXGroup; + children = ( + 4494E5B923550BF00082C217 /* Features */, + 4494E5C823550BF00082C217 /* Common */, + 4494E5CA23550BF00082C217 /* Colors */, + 4494E5D523550BF00082C217 /* Fonts */, + 4494E59323550B700082C217 /* Tests-iOS */, + 4494E5A123550B870082C217 /* Tests-macOS */, + 4494E5AF23550BA30082C217 /* Tests-tvOS */, + ); + path = Tests; + sourceTree = ""; + }; + 4494E5B923550BF00082C217 /* Features */ = { + isa = PBXGroup; + children = ( + 4494E5BA23550BF00082C217 /* Mocks */, + 4494E5C723550BF00082C217 /* CapablePerfTests.swift */, + 4494E5C123550BF00082C217 /* CapableTests.swift */, + 4494E5C223550BF00082C217 /* FeatureNotificationsTests.swift */, + 4494E5C323550BF00082C217 /* FeatureStatusesTests.swift */, + 4494E5C523550BF00082C217 /* FeatureStatusesProviderTests.swift */, + 4494E5C023550BF00082C217 /* HandicapNotificationsTests.swift */, + 4494E5C423550BF00082C217 /* HandicapStatusesTests.swift */, + 4494E5C623550BF00082C217 /* HandicapTests.swift */, + 4494E5BF23550BF00082C217 /* NotificationsTests.swift */, + ); + path = Features; + sourceTree = ""; + }; + 4494E5BA23550BF00082C217 /* Mocks */ = { + isa = PBXGroup; + children = ( + 4494E5BB23550BF00082C217 /* HandicapStatusesMock.swift */, + 4494E5BE23550BF00082C217 /* FeatureStatusesMock.swift */, + 4494E5BD23550BF00082C217 /* FeatureStatusesProviderMock.swift */, + 4494E5BC23550BF00082C217 /* NotificationCenterMock.swift */, + ); + path = Mocks; + sourceTree = ""; + }; + 4494E5C823550BF00082C217 /* Common */ = { + isa = PBXGroup; + children = ( + 4494E5C923550BF00082C217 /* LoggerTests.swift */, + ); + path = Common; + sourceTree = ""; + }; + 4494E5CA23550BF00082C217 /* Colors */ = { + isa = PBXGroup; + children = ( + 4494E5CB23550BF00082C217 /* Mocks */, + 4494E5CF23550BF00082C217 /* ColorWcagTests.swift */, + 4494E5D423550BF00082C217 /* ConformanceLevelTests.swift */, + 4494E5D023550BF00082C217 /* FontPropsTests.swift */, + 4494E5CE23550BF00082C217 /* ImageAreaTests.swift */, + 4494E5D323550BF00082C217 /* ImageAverageColorTests.swift */, + 4494E5CD23550BF00082C217 /* NSFontFontPropsTests.swift */, + 4494E5D223550BF00082C217 /* RGBAColorTests.swift */, + 4494E5D123550BF00082C217 /* UIFontFontPropsTests.swift */, + ); + path = Colors; + sourceTree = ""; + }; + 4494E5CB23550BF00082C217 /* Mocks */ = { + isa = PBXGroup; + children = ( + 4494E5CC23550BF00082C217 /* Image+mock.swift */, + ); + path = Mocks; + sourceTree = ""; + }; + 4494E5D523550BF00082C217 /* Fonts */ = { + isa = PBXGroup; + children = ( + 4494E5DB23550BF00082C217 /* FontMetricsProviderTests.swift */, + 4494E5DA23550BF00082C217 /* FontMetricsSupportTests.swift */, + 4494E5DC23550BF00082C217 /* FontMetricsTests.swift */, + 4494E5D623550BF00082C217 /* Mocks */, + ); + path = Fonts; + sourceTree = ""; + }; + 4494E5D623550BF00082C217 /* Mocks */ = { + isa = PBXGroup; + children = ( + 4494E5D823550BF00082C217 /* FontMetricsMock.swift */, + 4494E5D723550BF00082C217 /* FontMetricsProviderMock.swift */, + 4494E5D923550BF00082C217 /* OsVersionProviderMock.swift */, + ); + path = Mocks; + sourceTree = ""; + }; 831B4F2520A4D51D00F1BB94 /* iOS */ = { isa = PBXGroup; children = ( @@ -304,8 +602,9 @@ 83C6F5D320780FE700F0C74D = { isa = PBXGroup; children = ( - 83C6F6202078138D00F0C74D /* Ressources */, + 83C6F6202078138D00F0C74D /* Resources */, 83C6F6242078138E00F0C74D /* Source */, + 4494E5B823550BF00082C217 /* Tests */, 83C6F5DD20780FE700F0C74D /* Products */, 83C6F6352078189700F0C74D /* Frameworks */, A6B09A9FE714175C42D90ACA /* Pods */, @@ -320,17 +619,20 @@ 837C191620AA27960003D237 /* Example-watchOS.app */, 837C192220AA27970003D237 /* Example-watchOS Extension.appex */, 832953D421121EAA00072EB9 /* Example-macOS.app */, + 4494E59223550B700082C217 /* Tests-iOS.xctest */, + 4494E5A023550B870082C217 /* Tests-macOS.xctest */, + 4494E5AE23550BA30082C217 /* Tests-tvOS.xctest */, ); name = Products; sourceTree = ""; }; - 83C6F6202078138D00F0C74D /* Ressources */ = { + 83C6F6202078138D00F0C74D /* Resources */ = { isa = PBXGroup; children = ( 83C6F6212078138D00F0C74D /* Assets.xcassets */, 83C6F6222078138D00F0C74D /* Fonts */, ); - path = Ressources; + path = Resources; sourceTree = ""; }; 83C6F6222078138D00F0C74D /* Fonts */ = { @@ -371,6 +673,9 @@ CDA97E99795B6631F2DB0EB5 /* Pods_Example_watchOS.framework */, 06A4614933CCE311EC4CAD3C /* Pods_Example_watchOS_Extension.framework */, 1A9D86F10DB1D691B906F54E /* Pods_Example_macOS.framework */, + D3608C5EC986382E365A8FF4 /* Pods_Tests_iOS.framework */, + 7B78C620EDD88E25833A2D67 /* Pods_Tests_macOS.framework */, + EDACB4A868A3168E8898DF12 /* Pods_Tests_tvOS.framework */, ); name = Frameworks; sourceTree = ""; @@ -388,6 +693,12 @@ 4A59D50AB7E59EBA9F953814 /* Pods-Example-watchOS Extension.release.xcconfig */, EB296F840F14F09371040629 /* Pods-Example-macOS.debug.xcconfig */, 9C45A1F5FCFA4768DC33403B /* Pods-Example-macOS.release.xcconfig */, + 1021B1BF9523C4E2D4946FE7 /* Pods-Tests-iOS.debug.xcconfig */, + 4E60CC370BEED5BC72BF9333 /* Pods-Tests-iOS.release.xcconfig */, + 2718FA59414252A3E57D1724 /* Pods-Tests-macOS.debug.xcconfig */, + 8FF58CFC45A3E07A160D697E /* Pods-Tests-macOS.release.xcconfig */, + CCD5A28B0848B7B5B546E759 /* Pods-Tests-tvOS.debug.xcconfig */, + BF9562DEC091BFDE381F3882 /* Pods-Tests-tvOS.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -395,6 +706,66 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 4494E59123550B700082C217 /* Tests-iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4494E59B23550B700082C217 /* Build configuration list for PBXNativeTarget "Tests-iOS" */; + buildPhases = ( + 2ED1CAB3964CEF52A8A01928 /* [CP] Check Pods Manifest.lock */, + 4494E58E23550B700082C217 /* Sources */, + 4494E58F23550B700082C217 /* Frameworks */, + 4494E59023550B700082C217 /* Resources */, + BFB7E06181A4734FA448C13E /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 4494E59823550B700082C217 /* PBXTargetDependency */, + ); + name = "Tests-iOS"; + productName = "Tests-iOS"; + productReference = 4494E59223550B700082C217 /* Tests-iOS.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 4494E59F23550B870082C217 /* Tests-macOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4494E5A723550B870082C217 /* Build configuration list for PBXNativeTarget "Tests-macOS" */; + buildPhases = ( + 078EE6FC1D2B2FEB0A4B6772 /* [CP] Check Pods Manifest.lock */, + 4494E59C23550B870082C217 /* Sources */, + 4494E59D23550B870082C217 /* Frameworks */, + 4494E59E23550B870082C217 /* Resources */, + D32706A5F70834ABC6328786 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 4494E5A623550B870082C217 /* PBXTargetDependency */, + ); + name = "Tests-macOS"; + productName = "Tests-macOS"; + productReference = 4494E5A023550B870082C217 /* Tests-macOS.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 4494E5AD23550BA30082C217 /* Tests-tvOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4494E5B523550BA30082C217 /* Build configuration list for PBXNativeTarget "Tests-tvOS" */; + buildPhases = ( + F8FA57791175301B6ECDDAD7 /* [CP] Check Pods Manifest.lock */, + 4494E5AA23550BA30082C217 /* Sources */, + 4494E5AB23550BA30082C217 /* Frameworks */, + 4494E5AC23550BA30082C217 /* Resources */, + ECCE1F6322AC3096D3A2CE98 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 4494E5B423550BA30082C217 /* PBXTargetDependency */, + ); + name = "Tests-tvOS"; + productName = "Tests-tvOS"; + productReference = 4494E5AE23550BA30082C217 /* Tests-tvOS.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 831B4F1320A4D4F200F1BB94 /* Example-tvOS */ = { isa = PBXNativeTarget; buildConfigurationList = 831B4F2220A4D4F200F1BB94 /* Build configuration list for PBXNativeTarget "Example-tvOS" */; @@ -404,7 +775,7 @@ 831B4F1120A4D4F200F1BB94 /* Frameworks */, 831B4F1220A4D4F200F1BB94 /* Resources */, 83E67A2B20CD946200FE6FC2 /* Embed Frameworks */, - CD63CA07C089828CF543BBC4 /* [CP] Embed Pods Frameworks */, + A788BE5E33D95CA689982915 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -423,8 +794,8 @@ 832953D021121EAA00072EB9 /* Sources */, 832953D121121EAA00072EB9 /* Frameworks */, 832953D221121EAA00072EB9 /* Resources */, - 66EBB1053BB87E5FD2CD23AA /* [CP] Embed Pods Frameworks */, 83FF01F62129FDF900D26E0D /* Embed Frameworks */, + A61EE5A19738AB2C58021A36 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -462,7 +833,7 @@ 837C191E20AA27970003D237 /* Sources */, 837C191F20AA27970003D237 /* Frameworks */, 837C192020AA27970003D237 /* Resources */, - F67097C47BDCE4F9878E7D3B /* [CP] Embed Pods Frameworks */, + D34178DF1102C7F98B632D87 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -500,10 +871,25 @@ 83C6F5D420780FE700F0C74D /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 0940; + LastSwiftUpdateCheck = 1110; LastUpgradeCheck = 0940; ORGANIZATIONNAME = "Christoph Wendt"; TargetAttributes = { + 4494E59123550B700082C217 = { + CreatedOnToolsVersion = 11.1; + ProvisioningStyle = Automatic; + TestTargetID = 83C6F5DB20780FE700F0C74D; + }; + 4494E59F23550B870082C217 = { + CreatedOnToolsVersion = 11.1; + ProvisioningStyle = Automatic; + TestTargetID = 832953D321121EAA00072EB9; + }; + 4494E5AD23550BA30082C217 = { + CreatedOnToolsVersion = 11.1; + ProvisioningStyle = Automatic; + TestTargetID = 831B4F1320A4D4F200F1BB94; + }; 831B4F1320A4D4F200F1BB94 = { CreatedOnToolsVersion = 9.2; LastSwiftMigration = 1000; @@ -548,11 +934,35 @@ 831B4F1320A4D4F200F1BB94 /* Example-tvOS */, 837C191520AA27960003D237 /* Example-watchOS */, 837C192120AA27970003D237 /* Example-watchOS Extension */, + 4494E59123550B700082C217 /* Tests-iOS */, + 4494E59F23550B870082C217 /* Tests-macOS */, + 4494E5AD23550BA30082C217 /* Tests-tvOS */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 4494E59023550B700082C217 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4494E59E23550B870082C217 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4494E5AC23550BA30082C217 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 831B4F1220A4D4F200F1BB94 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -629,6 +1039,28 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Example-iOS/Pods-Example-iOS-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; + 078EE6FC1D2B2FEB0A4B6772 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Tests-macOS-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 0B305DAF6497E3528DC81849 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -647,22 +1079,26 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 66EBB1053BB87E5FD2CD23AA /* [CP] Embed Pods Frameworks */ = { + 2ED1CAB3964CEF52A8A01928 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Example-macOS/Pods-Example-macOS-frameworks.sh", - "${BUILT_PRODUCTS_DIR}/Capable-macOS/Capable.framework", + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( ); - name = "[CP] Embed Pods Frameworks"; outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Capable.framework", + "$(DERIVED_FILE_DIR)/Pods-Tests-iOS-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Example-macOS/Pods-Example-macOS-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; 908CD651F925C69DAD7AE2BB /* [CP] Check Pods Manifest.lock */ = { @@ -701,6 +1137,62 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + A61EE5A19738AB2C58021A36 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Example-macOS/Pods-Example-macOS-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/Capable-macOS/Capable.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Capable.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Example-macOS/Pods-Example-macOS-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + A788BE5E33D95CA689982915 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Example-tvOS/Pods-Example-tvOS-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/Capable-tvOS/Capable.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Capable.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Example-tvOS/Pods-Example-tvOS-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + BFB7E06181A4734FA448C13E /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Tests-iOS/Pods-Tests-iOS-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/Nimble-iOS/Nimble.framework", + "${BUILT_PRODUCTS_DIR}/Quick-iOS/Quick.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Nimble.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Quick.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Tests-iOS/Pods-Tests-iOS-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; C70D01AECEEE31D19B3E4595 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -719,14 +1211,34 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - CD63CA07C089828CF543BBC4 /* [CP] Embed Pods Frameworks */ = { + D32706A5F70834ABC6328786 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Example-tvOS/Pods-Example-tvOS-frameworks.sh", - "${BUILT_PRODUCTS_DIR}/Capable-tvOS/Capable.framework", + "${PODS_ROOT}/Target Support Files/Pods-Tests-macOS/Pods-Tests-macOS-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/Nimble-macOS/Nimble.framework", + "${BUILT_PRODUCTS_DIR}/Quick-macOS/Quick.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Nimble.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Quick.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Tests-macOS/Pods-Tests-macOS-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + D34178DF1102C7F98B632D87 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Example-watchOS Extension/Pods-Example-watchOS Extension-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/Capable-watchOS/Capable.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( @@ -734,7 +1246,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Example-tvOS/Pods-Example-tvOS-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Example-watchOS Extension/Pods-Example-watchOS Extension-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; E0FC5F3AA5CB3DA8BF3D6D8B /* [CP] Check Pods Manifest.lock */ = { @@ -755,27 +1267,159 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - F67097C47BDCE4F9878E7D3B /* [CP] Embed Pods Frameworks */ = { + ECCE1F6322AC3096D3A2CE98 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Example-watchOS Extension/Pods-Example-watchOS Extension-frameworks.sh", - "${BUILT_PRODUCTS_DIR}/Capable-watchOS/Capable.framework", + "${PODS_ROOT}/Target Support Files/Pods-Tests-tvOS/Pods-Tests-tvOS-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/Nimble-tvOS/Nimble.framework", + "${BUILT_PRODUCTS_DIR}/Quick-tvOS/Quick.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Capable.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Nimble.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Quick.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Example-watchOS Extension/Pods-Example-watchOS Extension-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Tests-tvOS/Pods-Tests-tvOS-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + F8FA57791175301B6ECDDAD7 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Tests-tvOS-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 4494E58E23550B700082C217 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4494E62523550F240082C217 /* FontMetricsTests.swift in Sources */, + 4494E5E023550E5A0082C217 /* CapableTests.swift in Sources */, + 4494E60D23550ED40082C217 /* RGBAColorTests.swift in Sources */, + 4494E5F923550E670082C217 /* HandicapStatusesMock.swift in Sources */, + 4494E62E23550F360082C217 /* OsVersionProviderMock.swift in Sources */, + 4494E5E523550E5A0082C217 /* HandicapTests.swift in Sources */, + 4494E60C23550ED40082C217 /* UIFontFontPropsTests.swift in Sources */, + 4494E62323550F240082C217 /* FontMetricsProviderTests.swift in Sources */, + 4494E62D23550F360082C217 /* FontMetricsProviderMock.swift in Sources */, + 4494E5E323550E5A0082C217 /* HandicapStatusesTests.swift in Sources */, + 4494E60F23550ED40082C217 /* ConformanceLevelTests.swift in Sources */, + 4494E62123550EE40082C217 /* Image+mock.swift in Sources */, + 4494E5FC23550E670082C217 /* FeatureStatusesMock.swift in Sources */, + 4494E60A23550ED40082C217 /* ColorWcagTests.swift in Sources */, + 4494E60823550ED40082C217 /* NSFontFontPropsTests.swift in Sources */, + 4494E60E23550ED40082C217 /* ImageAverageColorTests.swift in Sources */, + 4494E60523550ECA0082C217 /* LoggerTests.swift in Sources */, + 4494E5E623550E5A0082C217 /* CapablePerfTests.swift in Sources */, + 4494E60B23550ED40082C217 /* FontPropsTests.swift in Sources */, + 4494E5DF23550E5A0082C217 /* HandicapNotificationsTests.swift in Sources */, + 4494E5FA23550E670082C217 /* NotificationCenterMock.swift in Sources */, + 4494E5E423550E5A0082C217 /* FeatureStatusesProviderTests.swift in Sources */, + 4494E62423550F240082C217 /* FontMetricsSupportTests.swift in Sources */, + 4494E5DE23550E5A0082C217 /* NotificationsTests.swift in Sources */, + 4494E5E123550E5A0082C217 /* FeatureNotificationsTests.swift in Sources */, + 4494E62C23550F360082C217 /* FontMetricsMock.swift in Sources */, + 4494E5E223550E5A0082C217 /* FeatureStatusesTests.swift in Sources */, + 4494E60923550ED40082C217 /* ImageAreaTests.swift in Sources */, + 4494E5FB23550E670082C217 /* FeatureStatusesProviderMock.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4494E59C23550B870082C217 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4494E62823550F240082C217 /* FontMetricsTests.swift in Sources */, + 4494E5E923550E5A0082C217 /* CapableTests.swift in Sources */, + 4494E61523550ED50082C217 /* RGBAColorTests.swift in Sources */, + 4494E5FD23550E680082C217 /* HandicapStatusesMock.swift in Sources */, + 4494E63123550F360082C217 /* OsVersionProviderMock.swift in Sources */, + 4494E5EE23550E5A0082C217 /* HandicapTests.swift in Sources */, + 4494E61423550ED50082C217 /* UIFontFontPropsTests.swift in Sources */, + 4494E62623550F240082C217 /* FontMetricsProviderTests.swift in Sources */, + 4494E63023550F360082C217 /* FontMetricsProviderMock.swift in Sources */, + 4494E5EC23550E5A0082C217 /* HandicapStatusesTests.swift in Sources */, + 4494E61723550ED50082C217 /* ConformanceLevelTests.swift in Sources */, + 4494E62223550EE40082C217 /* Image+mock.swift in Sources */, + 4494E60023550E680082C217 /* FeatureStatusesMock.swift in Sources */, + 4494E61223550ED50082C217 /* ColorWcagTests.swift in Sources */, + 4494E61023550ED50082C217 /* NSFontFontPropsTests.swift in Sources */, + 4494E61623550ED50082C217 /* ImageAverageColorTests.swift in Sources */, + 4494E60623550ECB0082C217 /* LoggerTests.swift in Sources */, + 4494E5EF23550E5A0082C217 /* CapablePerfTests.swift in Sources */, + 4494E61323550ED50082C217 /* FontPropsTests.swift in Sources */, + 4494E5E823550E5A0082C217 /* HandicapNotificationsTests.swift in Sources */, + 4494E5FE23550E680082C217 /* NotificationCenterMock.swift in Sources */, + 4494E5ED23550E5A0082C217 /* FeatureStatusesProviderTests.swift in Sources */, + 4494E62723550F240082C217 /* FontMetricsSupportTests.swift in Sources */, + 4494E5E723550E5A0082C217 /* NotificationsTests.swift in Sources */, + 4494E5EA23550E5A0082C217 /* FeatureNotificationsTests.swift in Sources */, + 4494E62F23550F360082C217 /* FontMetricsMock.swift in Sources */, + 4494E5EB23550E5A0082C217 /* FeatureStatusesTests.swift in Sources */, + 4494E61123550ED50082C217 /* ImageAreaTests.swift in Sources */, + 4494E5FF23550E680082C217 /* FeatureStatusesProviderMock.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4494E5AA23550BA30082C217 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4494E62B23550F250082C217 /* FontMetricsTests.swift in Sources */, + 4494E5F223550E5B0082C217 /* CapableTests.swift in Sources */, + 4494E61D23550ED50082C217 /* RGBAColorTests.swift in Sources */, + 4494E60123550E690082C217 /* HandicapStatusesMock.swift in Sources */, + 4494E63423550F380082C217 /* OsVersionProviderMock.swift in Sources */, + 4494E5F723550E5B0082C217 /* HandicapTests.swift in Sources */, + 4494E61C23550ED50082C217 /* UIFontFontPropsTests.swift in Sources */, + 4494E62923550F250082C217 /* FontMetricsProviderTests.swift in Sources */, + 4494E63323550F380082C217 /* FontMetricsProviderMock.swift in Sources */, + 4494E5F523550E5B0082C217 /* HandicapStatusesTests.swift in Sources */, + 4494E61F23550ED50082C217 /* ConformanceLevelTests.swift in Sources */, + 4494E62023550EE40082C217 /* Image+mock.swift in Sources */, + 4494E60423550E690082C217 /* FeatureStatusesMock.swift in Sources */, + 4494E61A23550ED50082C217 /* ColorWcagTests.swift in Sources */, + 4494E61823550ED50082C217 /* NSFontFontPropsTests.swift in Sources */, + 4494E61E23550ED50082C217 /* ImageAverageColorTests.swift in Sources */, + 4494E60723550ECC0082C217 /* LoggerTests.swift in Sources */, + 4494E5F823550E5B0082C217 /* CapablePerfTests.swift in Sources */, + 4494E61B23550ED50082C217 /* FontPropsTests.swift in Sources */, + 4494E5F123550E5B0082C217 /* HandicapNotificationsTests.swift in Sources */, + 4494E60223550E690082C217 /* NotificationCenterMock.swift in Sources */, + 4494E5F623550E5B0082C217 /* FeatureStatusesProviderTests.swift in Sources */, + 4494E62A23550F250082C217 /* FontMetricsSupportTests.swift in Sources */, + 4494E5F023550E5B0082C217 /* NotificationsTests.swift in Sources */, + 4494E5F323550E5B0082C217 /* FeatureNotificationsTests.swift in Sources */, + 4494E63223550F380082C217 /* FontMetricsMock.swift in Sources */, + 4494E5F423550E5B0082C217 /* FeatureStatusesTests.swift in Sources */, + 4494E61923550ED50082C217 /* ImageAreaTests.swift in Sources */, + 4494E60323550E690082C217 /* FeatureStatusesProviderMock.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 831B4F1020A4D4F200F1BB94 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -840,6 +1484,21 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 4494E59823550B700082C217 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 83C6F5DB20780FE700F0C74D /* Example-iOS */; + targetProxy = 4494E59723550B700082C217 /* PBXContainerItemProxy */; + }; + 4494E5A623550B870082C217 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 832953D321121EAA00072EB9 /* Example-macOS */; + targetProxy = 4494E5A523550B870082C217 /* PBXContainerItemProxy */; + }; + 4494E5B423550BA30082C217 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 831B4F1320A4D4F200F1BB94 /* Example-tvOS */; + targetProxy = 4494E5B323550BA30082C217 /* PBXContainerItemProxy */; + }; 837C192520AA27970003D237 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 837C192120AA27970003D237 /* Example-watchOS Extension */; @@ -896,6 +1555,127 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 4494E59923550B700082C217 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1021B1BF9523C4E2D4946FE7 /* Pods-Tests-iOS.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ENABLE_OBJC_WEAK = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = "Tests/Tests-iOS/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 13.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.chrs1885..Tests-iOS"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example-iOS.app/Example-iOS"; + }; + name = Debug; + }; + 4494E59A23550B700082C217 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4E60CC370BEED5BC72BF9333 /* Pods-Tests-iOS.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ENABLE_OBJC_WEAK = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = "Tests/Tests-iOS/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 13.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.chrs1885..Tests-iOS"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example-iOS.app/Example-iOS"; + }; + name = Release; + }; + 4494E5A823550B870082C217 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2718FA59414252A3E57D1724 /* Pods-Tests-macOS.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ENABLE_OBJC_WEAK = YES; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = "Tests/Tests-macOS/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.chrs1885..Tests-macOS"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example-macOS.app/Contents/MacOS/Example-macOS"; + }; + name = Debug; + }; + 4494E5A923550B870082C217 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8FF58CFC45A3E07A160D697E /* Pods-Tests-macOS.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ENABLE_OBJC_WEAK = YES; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = "Tests/Tests-macOS/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.chrs1885..Tests-macOS"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example-macOS.app/Contents/MacOS/Example-macOS"; + }; + name = Release; + }; + 4494E5B623550BA30082C217 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = CCD5A28B0848B7B5B546E759 /* Pods-Tests-tvOS.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ENABLE_OBJC_WEAK = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = "Tests/Tests-tvOS/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.chrs1885..Tests-tvOS"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example-tvOS.app/Example-tvOS"; + TVOS_DEPLOYMENT_TARGET = 13.0; + }; + name = Debug; + }; + 4494E5B723550BA30082C217 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BF9562DEC091BFDE381F3882 /* Pods-Tests-tvOS.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ENABLE_OBJC_WEAK = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = "Tests/Tests-tvOS/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.chrs1885..Tests-tvOS"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example-tvOS.app/Example-tvOS"; + TVOS_DEPLOYMENT_TARGET = 13.0; + }; + name = Release; + }; 831B4F2320A4D4F200F1BB94 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = A69A8636A1A206955AF20AA4 /* Pods-Example-tvOS.debug.xcconfig */; @@ -1202,6 +1982,33 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 4494E59B23550B700082C217 /* Build configuration list for PBXNativeTarget "Tests-iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4494E59923550B700082C217 /* Debug */, + 4494E59A23550B700082C217 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4494E5A723550B870082C217 /* Build configuration list for PBXNativeTarget "Tests-macOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4494E5A823550B870082C217 /* Debug */, + 4494E5A923550B870082C217 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4494E5B523550BA30082C217 /* Build configuration list for PBXNativeTarget "Tests-tvOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4494E5B623550BA30082C217 /* Debug */, + 4494E5B723550BA30082C217 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 831B4F2220A4D4F200F1BB94 /* Build configuration list for PBXNativeTarget "Example-tvOS" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Capable.xcodeproj/xcshareddata/xcschemes/Capable.xcscheme b/Example/Example.xcodeproj/xcshareddata/xcschemes/Example-macOS.xcscheme similarity index 57% rename from Capable.xcodeproj/xcshareddata/xcschemes/Capable.xcscheme rename to Example/Example.xcodeproj/xcshareddata/xcschemes/Example-macOS.xcscheme index bbf6dc5..bb47a0e 100644 --- a/Capable.xcodeproj/xcshareddata/xcschemes/Capable.xcscheme +++ b/Example/Example.xcodeproj/xcshareddata/xcschemes/Example-macOS.xcscheme @@ -1,6 +1,6 @@ + BlueprintIdentifier = "832953D321121EAA00072EB9" + BuildableName = "Example-macOS.app" + BlueprintName = "Example-macOS" + ReferencedContainer = "container:Example.xcodeproj"> @@ -26,16 +26,16 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + shouldUseLaunchSchemeArgsEnv = "YES" codeCoverageEnabled = "YES" - onlyGenerateCoverageForSpecifiedTargets = "YES" - shouldUseLaunchSchemeArgsEnv = "YES"> + onlyGenerateCoverageForSpecifiedTargets = "YES"> + BlueprintName = "Capable-macOS" + ReferencedContainer = "container:Pods/Pods.xcodeproj"> @@ -43,24 +43,13 @@ skipped = "NO"> + BlueprintIdentifier = "4494E59F23550B870082C217" + BuildableName = "Tests-macOS.xctest" + BlueprintName = "Tests-macOS" + ReferencedContainer = "container:Example.xcodeproj"> - - - - - - - + + BlueprintIdentifier = "832953D321121EAA00072EB9" + BuildableName = "Example-macOS.app" + BlueprintName = "Example-macOS" + ReferencedContainer = "container:Example.xcodeproj"> - - - + - + + BlueprintIdentifier = "832953D321121EAA00072EB9" + BuildableName = "Example-macOS.app" + BlueprintName = "Example-macOS" + ReferencedContainer = "container:Example.xcodeproj"> - + diff --git a/Example/Example.xcodeproj/xcshareddata/xcschemes/Example-tvOS.xcscheme b/Example/Example.xcodeproj/xcshareddata/xcschemes/Example-tvOS.xcscheme new file mode 100644 index 0000000..245bb93 --- /dev/null +++ b/Example/Example.xcodeproj/xcshareddata/xcschemes/Example-tvOS.xcscheme @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme b/Example/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme index 3fb75ae..715048e 100644 --- a/Example/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme +++ b/Example/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme @@ -26,29 +26,9 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES"> - - - - - - - - - - + shouldUseLaunchSchemeArgsEnv = "YES" + codeCoverageEnabled = "YES" + onlyGenerateCoverageForSpecifiedTargets = "YES"> - - + + + + + + + + + + - - - - diff --git a/Example/Podfile b/Example/Podfile index 4b4a79b..3654203 100644 --- a/Example/Podfile +++ b/Example/Podfile @@ -1,41 +1,57 @@ +use_frameworks! + def sharedPods pod 'Capable', path: '../' end +def testPods + inherit! :search_paths + + pod 'Quick', '~> 2.2.0' + pod 'Nimble', '~> 8.0.4' +end + target 'Example-iOS' do platform :ios, '11.0' - use_frameworks! sharedPods - pod 'SheetyColors', '1.0.0' + pod 'SheetyColors', '1.0.1' pod 'AppCenter/Analytics' pod 'Fabric' pod 'Answers' pod 'Firebase/Core' + + target 'Tests-iOS' do + testPods + end end target 'Example-macOS' do platform :osx, '10.12' - use_frameworks! sharedPods + + target 'Tests-macOS' do + testPods + end end target 'Example-tvOS' do platform :tvos, '10.0' - use_frameworks! sharedPods + + target 'Tests-tvOS' do + testPods + end end target 'Example-watchOS' do platform :watchos, '4.0' - use_frameworks! end target 'Example-watchOS Extension' do platform :watchos, '4.0' - use_frameworks! sharedPods end diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 2b726cb..b93ab3e 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -4,13 +4,13 @@ PODS: - AppCenter/Analytics (2.4.0): - AppCenter/Core - AppCenter/Core (2.4.0) - - Capable (1.0.1): - - Capable/Colors (= 1.0.1) - - Capable/Features (= 1.0.1) - - Capable/Fonts (= 1.0.1) - - Capable/Colors (1.0.1) - - Capable/Features (1.0.1) - - Capable/Fonts (1.0.1) + - Capable (1.1.1): + - Capable/Colors (= 1.1.1) + - Capable/Features (= 1.1.1) + - Capable/Fonts (= 1.1.1) + - Capable/Colors (1.1.1) + - Capable/Features (1.1.1) + - Capable/Fonts (1.1.1) - Fabric (1.10.2) - Firebase/Core (6.10.0): - Firebase/CoreOnly @@ -75,8 +75,10 @@ PODS: - nanopb/encode (= 0.3.901) - nanopb/decode (0.3.901) - nanopb/encode (0.3.901) - - SheetyColors (1.0.0): - - Capable/Colors (~> 1.0.0) + - Nimble (8.0.4) + - Quick (2.2.0) + - SheetyColors (1.0.1): + - Capable/Colors (~> 1.0) DEPENDENCIES: - Answers @@ -84,7 +86,9 @@ DEPENDENCIES: - Capable (from `../`) - Fabric - Firebase/Core - - SheetyColors (= 1.0.0) + - Nimble (~> 8.0.4) + - Quick (~> 2.2.0) + - SheetyColors (= 1.0.1) SPEC REPOS: https://github.com/cocoapods/specs.git: @@ -102,6 +106,8 @@ SPEC REPOS: - GoogleDataTransportCCTSupport - GoogleUtilities - nanopb + - Nimble + - Quick - SheetyColors EXTERNAL SOURCES: @@ -111,7 +117,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: Answers: 7d5ff1f77fea900eb75032b37b4288482b824055 AppCenter: 49a9ffe114c00e2bf5374aeda816d47eabf1978a - Capable: 49d8637d06ee50dac258757071ea27cbce0e1bf6 + Capable: c9a4ee37bb727af2255879f32e56b5cfa04857a5 Fabric: 706c8b8098fff96c33c0db69cbf81f9c551d0d74 Firebase: 5e6b7b12bf9adb90986688edc06b156c37e109cd FirebaseAnalytics: 0e3ecff2c5d86070f7d4325e21f1edabfbd558dc @@ -124,8 +130,10 @@ SPEC CHECKSUMS: GoogleDataTransportCCTSupport: 862418a8cdda520c4dd4af83a756d04efe4a6990 GoogleUtilities: f895fde57977df4e0233edda0dbeac490e3703b6 nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 - SheetyColors: dbf4b6b427d10f0316a2237b8a00cd8d576466dd + Nimble: 18d5360282923225d62b09d781f63abc1a0111fc + Quick: 7fb19e13be07b5dfb3b90d4f9824c855a11af40e + SheetyColors: ae8c3a5d04d310e8e2d08e4aa0bd543519d02252 -PODFILE CHECKSUM: 281f4c067013ef97112498d527050bb7d1b70f3b +PODFILE CHECKSUM: 1ddad2d76c31989ac603b5e5ffa5a72726b31819 COCOAPODS: 1.7.5 diff --git a/Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Contents.json b/Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Contents.json similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Contents.json rename to Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Contents.json diff --git a/Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-20x20@1x.png b/Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-20x20@1x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-20x20@1x.png rename to Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-20x20@1x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-20x20@2x-1.png b/Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-20x20@2x-1.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-20x20@2x-1.png rename to Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-20x20@2x-1.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-20x20@2x.png b/Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-20x20@2x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-20x20@2x.png rename to Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-20x20@2x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-20x20@3x.png b/Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-20x20@3x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-20x20@3x.png rename to Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-20x20@3x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-29x29@1x.png b/Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-29x29@1x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-29x29@1x.png rename to Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-29x29@1x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-29x29@2x-1.png b/Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-29x29@2x-1.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-29x29@2x-1.png rename to Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-29x29@2x-1.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-29x29@2x.png b/Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-29x29@2x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-29x29@2x.png rename to Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-29x29@2x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-29x29@3x.png b/Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-29x29@3x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-29x29@3x.png rename to Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-29x29@3x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-40x40@1x.png b/Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-40x40@1x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-40x40@1x.png rename to Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-40x40@1x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-40x40@2x-1.png b/Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-40x40@2x-1.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-40x40@2x-1.png rename to Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-40x40@2x-1.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-40x40@2x.png b/Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-40x40@2x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-40x40@2x.png rename to Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-40x40@2x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-40x40@3x.png b/Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-40x40@3x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-40x40@3x.png rename to Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-40x40@3x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-60x60@2x.png b/Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-60x60@2x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-60x60@2x.png rename to Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-60x60@2x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-60x60@3x.png b/Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-60x60@3x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-60x60@3x.png rename to Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-60x60@3x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-76x76@1x.png b/Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-76x76@1x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-76x76@1x.png rename to Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-76x76@1x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-76x76@2x.png b/Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-76x76@2x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-76x76@2x.png rename to Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-76x76@2x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-83.5x83.5@2x.png b/Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-83.5x83.5@2x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-83.5x83.5@2x.png rename to Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/Icon-App-83.5x83.5@2x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/ItunesArtwork@2x.png b/Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/ItunesArtwork@2x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-iOS.appiconset/ItunesArtwork@2x.png rename to Example/Resources/Assets.xcassets/AppIcon-iOS.appiconset/ItunesArtwork@2x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Contents.json b/Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Contents.json similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Contents.json rename to Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Contents.json diff --git a/Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-128x128@1x.png b/Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-128x128@1x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-128x128@1x.png rename to Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-128x128@1x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-128x128@2x.png b/Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-128x128@2x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-128x128@2x.png rename to Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-128x128@2x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-16x16@1x.png b/Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-16x16@1x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-16x16@1x.png rename to Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-16x16@1x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-16x16@2x.png b/Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-16x16@2x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-16x16@2x.png rename to Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-16x16@2x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-256x256@1x.png b/Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-256x256@1x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-256x256@1x.png rename to Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-256x256@1x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-256x256@2x.png b/Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-256x256@2x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-256x256@2x.png rename to Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-256x256@2x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-32x32@1x.png b/Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-32x32@1x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-32x32@1x.png rename to Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-32x32@1x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-32x32@2x.png b/Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-32x32@2x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-32x32@2x.png rename to Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-32x32@2x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-512x512@1x.png b/Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-512x512@1x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-512x512@1x.png rename to Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-512x512@1x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-512x512@2x.png b/Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-512x512@2x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-512x512@2x.png rename to Example/Resources/Assets.xcassets/AppIcon-macOS.appiconset/Icon-App-512x512@2x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-watchOS.appiconset/Contents.json b/Example/Resources/Assets.xcassets/AppIcon-watchOS.appiconset/Contents.json similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-watchOS.appiconset/Contents.json rename to Example/Resources/Assets.xcassets/AppIcon-watchOS.appiconset/Contents.json diff --git a/Example/Ressources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-24@2x.png b/Example/Resources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-24@2x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-24@2x.png rename to Example/Resources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-24@2x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-27.5@2x.png b/Example/Resources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-27.5@2x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-27.5@2x.png rename to Example/Resources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-27.5@2x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-29@2x.png b/Example/Resources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-29@2x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-29@2x.png rename to Example/Resources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-29@2x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-29@3x.png b/Example/Resources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-29@3x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-29@3x.png rename to Example/Resources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-29@3x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-40@2x.png b/Example/Resources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-40@2x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-40@2x.png rename to Example/Resources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-40@2x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-86@2x.png b/Example/Resources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-86@2x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-86@2x.png rename to Example/Resources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-86@2x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-98@2x.png b/Example/Resources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-98@2x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-98@2x.png rename to Example/Resources/Assets.xcassets/AppIcon-watchOS.appiconset/Icon-98@2x.png diff --git a/Example/Ressources/Assets.xcassets/AppIcon-watchOS.appiconset/iTunesArtwork@2x.png b/Example/Resources/Assets.xcassets/AppIcon-watchOS.appiconset/iTunesArtwork@2x.png similarity index 100% rename from Example/Ressources/Assets.xcassets/AppIcon-watchOS.appiconset/iTunesArtwork@2x.png rename to Example/Resources/Assets.xcassets/AppIcon-watchOS.appiconset/iTunesArtwork@2x.png diff --git a/Example/Ressources/Assets.xcassets/Contents.json b/Example/Resources/Assets.xcassets/Contents.json similarity index 100% rename from Example/Ressources/Assets.xcassets/Contents.json rename to Example/Resources/Assets.xcassets/Contents.json diff --git a/Example/Ressources/Assets.xcassets/LaunchImage.launchimage/Contents.json b/Example/Resources/Assets.xcassets/LaunchImage.launchimage/Contents.json similarity index 100% rename from Example/Ressources/Assets.xcassets/LaunchImage.launchimage/Contents.json rename to Example/Resources/Assets.xcassets/LaunchImage.launchimage/Contents.json diff --git a/Example/Ressources/Assets.xcassets/captions_gradient.imageset/Contents.json b/Example/Resources/Assets.xcassets/captions_gradient.imageset/Contents.json similarity index 100% rename from Example/Ressources/Assets.xcassets/captions_gradient.imageset/Contents.json rename to Example/Resources/Assets.xcassets/captions_gradient.imageset/Contents.json diff --git a/Example/Ressources/Assets.xcassets/captions_gradient.imageset/captions_gradient.png b/Example/Resources/Assets.xcassets/captions_gradient.imageset/captions_gradient.png similarity index 100% rename from Example/Ressources/Assets.xcassets/captions_gradient.imageset/captions_gradient.png rename to Example/Resources/Assets.xcassets/captions_gradient.imageset/captions_gradient.png diff --git a/Example/Ressources/Assets.xcassets/colors.imageset/Contents.json b/Example/Resources/Assets.xcassets/colors.imageset/Contents.json similarity index 100% rename from Example/Ressources/Assets.xcassets/colors.imageset/Contents.json rename to Example/Resources/Assets.xcassets/colors.imageset/Contents.json diff --git a/Example/Ressources/Assets.xcassets/colors.imageset/Paint Color Palette.pdf b/Example/Resources/Assets.xcassets/colors.imageset/Paint Color Palette.pdf similarity index 100% rename from Example/Ressources/Assets.xcassets/colors.imageset/Paint Color Palette.pdf rename to Example/Resources/Assets.xcassets/colors.imageset/Paint Color Palette.pdf diff --git a/Example/Ressources/Assets.xcassets/groups.imageset/Contents.json b/Example/Resources/Assets.xcassets/groups.imageset/Contents.json similarity index 100% rename from Example/Ressources/Assets.xcassets/groups.imageset/Contents.json rename to Example/Resources/Assets.xcassets/groups.imageset/Contents.json diff --git a/Example/Ressources/Assets.xcassets/groups.imageset/Layers.pdf b/Example/Resources/Assets.xcassets/groups.imageset/Layers.pdf similarity index 100% rename from Example/Ressources/Assets.xcassets/groups.imageset/Layers.pdf rename to Example/Resources/Assets.xcassets/groups.imageset/Layers.pdf diff --git a/Example/Ressources/Assets.xcassets/image.imageset/Contents.json b/Example/Resources/Assets.xcassets/image.imageset/Contents.json similarity index 100% rename from Example/Ressources/Assets.xcassets/image.imageset/Contents.json rename to Example/Resources/Assets.xcassets/image.imageset/Contents.json diff --git a/Example/Ressources/Assets.xcassets/image.imageset/image.pdf b/Example/Resources/Assets.xcassets/image.imageset/image.pdf similarity index 100% rename from Example/Ressources/Assets.xcassets/image.imageset/image.pdf rename to Example/Resources/Assets.xcassets/image.imageset/image.pdf diff --git a/Example/Ressources/Assets.xcassets/list.imageset/Clipboard List.pdf b/Example/Resources/Assets.xcassets/list.imageset/Clipboard List.pdf similarity index 100% rename from Example/Ressources/Assets.xcassets/list.imageset/Clipboard List.pdf rename to Example/Resources/Assets.xcassets/list.imageset/Clipboard List.pdf diff --git a/Example/Ressources/Assets.xcassets/list.imageset/Contents.json b/Example/Resources/Assets.xcassets/list.imageset/Contents.json similarity index 100% rename from Example/Ressources/Assets.xcassets/list.imageset/Contents.json rename to Example/Resources/Assets.xcassets/list.imageset/Contents.json diff --git a/Example/Ressources/Assets.xcassets/pencil.imageset/Contents.json b/Example/Resources/Assets.xcassets/pencil.imageset/Contents.json similarity index 100% rename from Example/Ressources/Assets.xcassets/pencil.imageset/Contents.json rename to Example/Resources/Assets.xcassets/pencil.imageset/Contents.json diff --git a/Example/Ressources/Assets.xcassets/pencil.imageset/Pen.pdf b/Example/Resources/Assets.xcassets/pencil.imageset/Pen.pdf similarity index 100% rename from Example/Ressources/Assets.xcassets/pencil.imageset/Pen.pdf rename to Example/Resources/Assets.xcassets/pencil.imageset/Pen.pdf diff --git a/Example/Ressources/Fonts/Cardo-Regular.ttf b/Example/Resources/Fonts/Cardo-Regular.ttf similarity index 100% rename from Example/Ressources/Fonts/Cardo-Regular.ttf rename to Example/Resources/Fonts/Cardo-Regular.ttf diff --git a/Example/Source/AppDelegate.swift b/Example/Source/AppDelegate.swift index 09bf90e..5fbffdc 100644 --- a/Example/Source/AppDelegate.swift +++ b/Example/Source/AppDelegate.swift @@ -12,32 +12,30 @@ import UIKit class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. return true } - func applicationWillResignActive(_ application: UIApplication) { + func applicationWillResignActive(_: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. } - func applicationDidEnterBackground(_ application: UIApplication) { + func applicationDidEnterBackground(_: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } - func applicationWillEnterForeground(_ application: UIApplication) { + func applicationWillEnterForeground(_: UIApplication) { // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. } - func applicationDidBecomeActive(_ application: UIApplication) { + func applicationDidBecomeActive(_: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } - func applicationWillTerminate(_ application: UIApplication) { + func applicationWillTerminate(_: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } - - } diff --git a/Example/Source/CaptionsViewController.swift b/Example/Source/CaptionsViewController.swift index a705275..d78781b 100644 --- a/Example/Source/CaptionsViewController.swift +++ b/Example/Source/CaptionsViewController.swift @@ -6,21 +6,21 @@ // Copyright © 2019 Christoph Wendt. All rights reserved. // -import UIKit import Capable +import UIKit class CaptionsViewController: UIViewController { - @IBOutlet weak var activityIndicator: UIActivityIndicatorView! - @IBOutlet weak var content: UIView! - @IBOutlet weak var topLeftLabel: UILabel! - @IBOutlet weak var topCenterLabel: UILabel! - @IBOutlet weak var topRightLabel: UILabel! - @IBOutlet weak var centerLeftLabel: UILabel! - @IBOutlet weak var centerLabel: UILabel! - @IBOutlet weak var centerRightLabel: UILabel! - @IBOutlet weak var bottomLeftLabel: UILabel! - @IBOutlet weak var bottomCenterLabel: UILabel! - @IBOutlet weak var bottomRightLabel: UILabel! + @IBOutlet var activityIndicator: UIActivityIndicatorView! + @IBOutlet var content: UIView! + @IBOutlet var topLeftLabel: UILabel! + @IBOutlet var topCenterLabel: UILabel! + @IBOutlet var topRightLabel: UILabel! + @IBOutlet var centerLeftLabel: UILabel! + @IBOutlet var centerLabel: UILabel! + @IBOutlet var centerRightLabel: UILabel! + @IBOutlet var bottomLeftLabel: UILabel! + @IBOutlet var bottomCenterLabel: UILabel! + @IBOutlet var bottomRightLabel: UILabel! var isLoading: Bool = true { didSet { @@ -43,7 +43,7 @@ class CaptionsViewController: UIViewController { private func setupLabelColors() { let backgroundImage = UIImage(named: "captions_gradient")! - let labels: [UILabel:ImageArea] = [ + let labels: [UILabel: ImageArea] = [ topLeftLabel: .topLeft, topCenterLabel: .topCenter, topRightLabel: .topRight, @@ -52,7 +52,7 @@ class CaptionsViewController: UIViewController { centerRightLabel: .centerRight, bottomLeftLabel: .bottomLeft, bottomCenterLabel: .bottomCenter, - bottomRightLabel: .bottomRight + bottomRightLabel: .bottomRight, ] isLoading = true diff --git a/Example/Source/Color+capable.swift b/Example/Source/Color+capable.swift index fa147c3..dd42786 100644 --- a/Example/Source/Color+capable.swift +++ b/Example/Source/Color+capable.swift @@ -8,13 +8,13 @@ #if os(iOS) -import UIKit -typealias Color = UIColor + import UIKit + typealias Color = UIColor #elseif os(OSX) -import AppKit -typealias Color = NSColor + import AppKit + typealias Color = NSColor #endif diff --git a/Example/Source/ConformanceLevelView.swift b/Example/Source/ConformanceLevelView.swift index 1071607..d35fd56 100644 --- a/Example/Source/ConformanceLevelView.swift +++ b/Example/Source/ConformanceLevelView.swift @@ -8,17 +8,17 @@ #if os(iOS) -import UIKit -typealias Font = UIFont -typealias Label = UILabel -typealias View = UIView + import UIKit + typealias Font = UIFont + typealias Label = UILabel + typealias View = UIView #elseif os(OSX) -import AppKit -typealias Font = NSFont -typealias Label = NSTextField -typealias View = NSView + import AppKit + typealias Font = NSFont + typealias Label = NSTextField + typealias View = NSView #endif @@ -28,10 +28,10 @@ class ConformanceLevelView: View { var text: String = "" { didSet { #if os(iOS) - self.textLabel.text = text + textLabel.text = text #elseif os(OSX) - self.textLabel.stringValue = text - self.textLabel.isEditable = false + textLabel.stringValue = text + textLabel.isEditable = false #endif } } @@ -49,8 +49,8 @@ class ConformanceLevelView: View { } func setupView() { - self.addSubview(textLabel) - self.textLabel.font = Font.systemFont(ofSize: 13.0) + addSubview(textLabel) + textLabel.font = Font.systemFont(ofSize: 13.0) textLabel.translatesAutoresizingMaskIntoConstraints = false let views: [String: Any] = ["textLabel": self.textLabel] @@ -59,6 +59,6 @@ class ConformanceLevelView: View { allConstraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|-8-[textLabel]-8-|", metrics: nil, views: views) NSLayoutConstraint.activate(allConstraints) - self.isPassing = true + isPassing = true } } diff --git a/Example/Source/FeatureOverviewController.swift b/Example/Source/FeatureOverviewController.swift index 00b55ac..6d20eb6 100644 --- a/Example/Source/FeatureOverviewController.swift +++ b/Example/Source/FeatureOverviewController.swift @@ -5,76 +5,79 @@ // Created by Christoph Wendt on 23.03.18. // -import UIKit import Capable +import UIKit #if os(iOS) -import Fabric -import Answers -import AppCenter -import AppCenterAnalytics -import Firebase + + import Answers + import AppCenter + import AppCenterAnalytics + import Fabric + import Firebase + #endif class FeatureOverviewController: UITableViewController { var alert: UIAlertController? var objects: [String: String]? var capable: Capable? - + override func viewDidLoad() { super.viewDidLoad() // self.capable = Capable(withFeatures: [.largerText, .boldText, .shakeToUndo]) - self.capable = Capable() - self.registerObservers() - self.refreshData() + capable = Capable() + registerObservers() + refreshData() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - self.registerObservers() + registerObservers() } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) - self.unregisterObservers() + unregisterObservers() } - + func refreshData() { if let capable = self.capable { - self.objects = capable.statusMap + objects = capable.statusMap } } - + func sendMetrics() { // The purpose of this function is to test API compatibility. To actually send telemetry, register each SDK // in the AppDelegate's didFinishLaunchingWithOptions callback #if os(iOS) - if let statusMap = self.capable?.statusMap { - let eventName = "Capable features received" - MSAnalytics.trackEvent(eventName, withProperties: statusMap) - Analytics.logEvent(eventName, parameters: statusMap) - Answers.logCustomEvent(withName: eventName, customAttributes: statusMap) - } + if let statusMap = self.capable?.statusMap { + let eventName = "Capable features received" + MSAnalytics.trackEvent(eventName, withProperties: statusMap) + Analytics.logEvent(eventName, parameters: statusMap) + Answers.logCustomEvent(withName: eventName, customAttributes: statusMap) + } #endif } } // MARK: - Table View + extension FeatureOverviewController { - override func numberOfSections(in tableView: UITableView) -> Int { + override func numberOfSections(in _: UITableView) -> Int { return 1 } - - override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return self.objects?.count ?? 0 + + override func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int { + return objects?.count ?? 0 } - + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) - let feature = self.value(forRow: indexPath.row) + let feature = value(forRow: indexPath.row) cell.textLabel!.text = feature.key cell.detailTextLabel!.text = feature.value - + return cell } @@ -88,21 +91,23 @@ extension FeatureOverviewController { } // MARK: Capable Notification + extension FeatureOverviewController { @objc private func featureStatusChanged(notification: NSNotification) { if let featureStatus = notification.object as? FeatureStatus { - self.showAlert(for: featureStatus) + showAlert(for: featureStatus) refreshData() - self.tableView.reloadData() + tableView.reloadData() } } func registerObservers() { NotificationCenter.default.addObserver( self, - selector: #selector(self.featureStatusChanged), + selector: #selector(featureStatusChanged), name: .CapableFeatureStatusDidChange, - object: nil) + object: nil + ) } func unregisterObservers() { @@ -111,6 +116,7 @@ extension FeatureOverviewController { } // MARK: Alert + extension FeatureOverviewController { private func showAlert(for featureStatus: FeatureStatus) { let showNewAlert = { @@ -122,13 +128,13 @@ extension FeatureOverviewController { self.present(alert, animated: true) } } - - self.dismissAlertIfNeeded(completion: showNewAlert) + + dismissAlertIfNeeded(completion: showNewAlert) } - - private func dismissAlertIfNeeded(completion: @escaping () -> ()) { - if self.alert != nil, self.presentedViewController == self.alert { - self.alert!.dismiss(animated: false) { + + private func dismissAlertIfNeeded(completion: @escaping () -> Void) { + if alert != nil, presentedViewController == alert { + alert!.dismiss(animated: false) { completion() } } else { diff --git a/Example/Source/FontsConstants.swift b/Example/Source/FontsConstants.swift index c2cabc6..5493548 100644 --- a/Example/Source/FontsConstants.swift +++ b/Example/Source/FontsConstants.swift @@ -36,6 +36,6 @@ struct FontsConstants { ( font: UIFont.scaledItalicSystemFont(ofSize: defaultFontSize), description: "Scaled Italic System Font" - ) + ), ] } diff --git a/Example/Source/HandicapViewController.swift b/Example/Source/HandicapViewController.swift index 0bddaee..c5bedb3 100644 --- a/Example/Source/HandicapViewController.swift +++ b/Example/Source/HandicapViewController.swift @@ -6,8 +6,8 @@ // Copyright © 2018 Christoph Wendt. All rights reserved. // -import UIKit import Capable +import UIKit class HandicapViewController: UITableViewController { var alert: UIAlertController? @@ -19,49 +19,50 @@ class HandicapViewController: UITableViewController { super.viewDidLoad() #if os(iOS) let blindness = Handicap(features: [.speakScreen, .speakSelection, .voiceOver], name: "Blindness", enabledIf: .oneFeatureEnabled) - self.capable = Capable(withHandicaps: [blindness]) - self.handicaps = [blindness] + capable = Capable(withHandicaps: [blindness]) + handicaps = [blindness] #else let lowVision = Handicap(features: [.boldText, .invertColors, .reduceTransparency], name: "Low Vision ", enabledIf: .oneFeatureEnabled) - self.capable = Capable(withHandicaps: [lowVision]) - self.handicaps = [lowVision] + capable = Capable(withHandicaps: [lowVision]) + handicaps = [lowVision] #endif - self.registerObservers() - self.refreshData() + registerObservers() + refreshData() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - self.registerObservers() + registerObservers() } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) - self.unregisterObservers() + unregisterObservers() } func refreshData() { if let capable = self.capable { - self.objects = capable.statusMap + objects = capable.statusMap } } } // MARK: - Table View + extension HandicapViewController { - override func numberOfSections(in tableView: UITableView) -> Int { + override func numberOfSections(in _: UITableView) -> Int { return 1 } - override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return self.objects?.count ?? 0 + override func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int { + return objects?.count ?? 0 } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) let row = indexPath.row - let status = self.value(forRow: row) + let status = value(forRow: row) let handicap = self.handicap(forName: status.key) cell.textLabel!.text = handicap.name cell.detailTextLabel!.text = CapableFeature.keys(forFeatures: handicap.features).joined(separator: ", ") @@ -79,7 +80,7 @@ extension HandicapViewController { } private func handicap(forName name: String) -> Handicap { - for handicap in self.handicaps! { + for handicap in handicaps! { if handicap.name == name { return handicap } @@ -89,29 +90,32 @@ extension HandicapViewController { } // MARK: Capable Notification + extension HandicapViewController { @objc private func handicapStatusChanged(notification: NSNotification) { if let handicapStatus = notification.object as? HandicapStatus { - self.showAlert(for: handicapStatus) + showAlert(for: handicapStatus) refreshData() - self.tableView.reloadData() + tableView.reloadData() } } func registerObservers() { NotificationCenter.default.addObserver( self, - selector: #selector(self.handicapStatusChanged), + selector: #selector(handicapStatusChanged), name: .CapableHandicapStatusDidChange, - object: nil) + object: nil + ) } - func unregisterObservers(){ + func unregisterObservers() { NotificationCenter.default.removeObserver(self) } } // MARK: Alert + extension HandicapViewController { private func showAlert(for handicapStatus: HandicapStatus) { let showNewAlert = { @@ -124,12 +128,12 @@ extension HandicapViewController { } } - self.dismissAlertIfNeeded(completion: showNewAlert) + dismissAlertIfNeeded(completion: showNewAlert) } - private func dismissAlertIfNeeded(completion: @escaping () -> ()) { - if self.alert != nil, self.presentedViewController == self.alert { - self.alert!.dismiss(animated: false) { + private func dismissAlertIfNeeded(completion: @escaping () -> Void) { + if alert != nil, presentedViewController == alert { + alert!.dismiss(animated: false) { completion() } } else { @@ -137,5 +141,3 @@ extension HandicapViewController { } } } - - diff --git a/Example/Source/iOS/ColorsViewController.swift b/Example/Source/iOS/ColorsViewController.swift index 1e0dcfb..a9dd31f 100644 --- a/Example/Source/iOS/ColorsViewController.swift +++ b/Example/Source/iOS/ColorsViewController.swift @@ -6,9 +6,9 @@ // Copyright © 2019 Christoph Wendt. All rights reserved. // -import UIKit import Capable import SheetyColors +import UIKit enum ColorType: String { case textColor = "Text Color" @@ -16,13 +16,13 @@ enum ColorType: String { } class ColorsViewController: UIViewController { - @IBOutlet weak var textColorButton: UIButton! - @IBOutlet weak var backgroundColorButton: UIButton! - @IBOutlet weak var contrastRatioLabel: UILabel! - @IBOutlet weak var aaSmallTextView: ConformanceLevelView! - @IBOutlet weak var aaaSmallTextView: ConformanceLevelView! - @IBOutlet weak var aaLargeTextView: ConformanceLevelView! - @IBOutlet weak var aaaLargeTextView: ConformanceLevelView! + @IBOutlet var textColorButton: UIButton! + @IBOutlet var backgroundColorButton: UIButton! + @IBOutlet var contrastRatioLabel: UILabel! + @IBOutlet var aaSmallTextView: ConformanceLevelView! + @IBOutlet var aaaSmallTextView: ConformanceLevelView! + @IBOutlet var aaLargeTextView: ConformanceLevelView! + @IBOutlet var aaaLargeTextView: ConformanceLevelView! var textColor: UIColor = .capableGreen var backgroundColor: UIColor = .black @@ -31,22 +31,23 @@ class ColorsViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - self.contrastRatio = UIColor.getContrastRatio(forTextColor: self.textColor, onBackgroundColor: self.backgroundColor)! + contrastRatio = UIColor.getContrastRatio(forTextColor: textColor, onBackgroundColor: backgroundColor)! setupView() } } // MARK: - Updating Views + extension ColorsViewController { func setupView() { - updateColorButton(button: self.textColorButton, withColor: self.textColor) - updateColorButton(button: self.backgroundColorButton, withColor: self.backgroundColor) + updateColorButton(button: textColorButton, withColor: textColor) + updateColorButton(button: backgroundColorButton, withColor: backgroundColor) updateContrastRatioLabel() - self.aaSmallTextView.text = "AA" - self.aaaSmallTextView.text = "AAA" - self.aaLargeTextView.text = "AA (Large Text)" - self.aaaLargeTextView.text = "AAA (Large Text)" + aaSmallTextView.text = "AA" + aaaSmallTextView.text = "AAA" + aaLargeTextView.text = "AA (Large Text)" + aaaLargeTextView.text = "AAA (Large Text)" updateConformanceLevelViews() } @@ -59,26 +60,27 @@ extension ColorsViewController { func updateConformanceLevelViews() { guard let contrastRatio = self.contrastRatio else { return } - self.aaSmallTextView.isPassing = contrastRatio >= 4.5 - self.aaaSmallTextView.isPassing = contrastRatio >= 7.0 - self.aaLargeTextView.isPassing = contrastRatio >= 3.0 - self.aaaLargeTextView.isPassing = contrastRatio >= 4.5 + aaSmallTextView.isPassing = contrastRatio >= 4.5 + aaaSmallTextView.isPassing = contrastRatio >= 7.0 + aaLargeTextView.isPassing = contrastRatio >= 3.0 + aaaLargeTextView.isPassing = contrastRatio >= 4.5 } func updateContrastRatioLabel() { guard let contrastRatio = self.contrastRatio else { return } - self.contrastRatioLabel.text = String(format: "%.2f", contrastRatio) + contrastRatioLabel.text = String(format: "%.2f", contrastRatio) } } // MARK: - Handling User Interaction + extension ColorsViewController { @IBAction func colorButtonPressed(_ sender: Any) { let button = sender as! UIButton - let colorType: ColorType = button == self.textColorButton ? .textColor : .backgroundColor - let color = colorType == .textColor ? self.textColor : self.backgroundColor + let colorType: ColorType = button == textColorButton ? .textColor : .backgroundColor + let color = colorType == .textColor ? textColor : backgroundColor let alphaEnabled = colorType == .textColor - + let config = SheetyColorsConfig(alphaEnabled: alphaEnabled, hapticFeedbackEnabled: true, initialColor: color, title: "Select a \(colorType.rawValue)", type: .rgb) let sheetyColors = SheetyColorsController(withConfig: config) let selectAction = UIAlertAction(title: "Save Color", style: .default, handler: { _ in @@ -88,14 +90,14 @@ extension ColorsViewController { } else { self.backgroundColor = selectedColor } - + self.contrastRatio = UIColor.getContrastRatio(forTextColor: self.textColor, onBackgroundColor: self.backgroundColor)! self.updateColorButton(button: button, withColor: selectedColor) self.updateContrastRatioLabel() self.updateConformanceLevelViews() }) sheetyColors.addAction(selectAction) - + let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) sheetyColors.addAction(cancelAction) diff --git a/Example/Source/iOS/FontsViewController.swift b/Example/Source/iOS/FontsViewController.swift index 7b9be55..ae4d87f 100644 --- a/Example/Source/iOS/FontsViewController.swift +++ b/Example/Source/iOS/FontsViewController.swift @@ -5,32 +5,32 @@ // Created by Christoph Wendt on 31.03.18. // -import UIKit -import Foundation import Capable +import Foundation +import UIKit class FontsController: UITableViewController { - override func numberOfSections(in tableView: UITableView) -> Int { + override func numberOfSections(in _: UITableView) -> Int { return 1 } - - override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + + override func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int { return FontsConstants.fontsList.count } - + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) let row = indexPath.row - + cell.textLabel!.text = FontsConstants.defaultText cell.textLabel?.font = FontsConstants.fontsList[row].font cell.textLabel?.adjustsFontForContentSizeCategory = true cell.textLabel?.lineBreakMode = .byWordWrapping cell.textLabel?.numberOfLines = 0 - + cell.detailTextLabel!.text = FontsConstants.fontsList[row].description cell.detailTextLabel!.font = UIFont.systemFont(ofSize: 13.0) - + return cell } } diff --git a/Example/Source/macOS/AppDelegate.swift b/Example/Source/macOS/AppDelegate.swift index d1c70ff..2f65443 100644 --- a/Example/Source/macOS/AppDelegate.swift +++ b/Example/Source/macOS/AppDelegate.swift @@ -10,13 +10,11 @@ import Cocoa @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { - - func applicationDidFinishLaunching(_ aNotification: Notification) { + func applicationDidFinishLaunching(_: Notification) { // Insert code here to initialize your application } - func applicationWillTerminate(_ aNotification: Notification) { + func applicationWillTerminate(_: Notification) { // Insert code here to tear down your application } } - diff --git a/Example/Source/macOS/CaptionsViewController.swift b/Example/Source/macOS/CaptionsViewController.swift index baa722f..b933f50 100644 --- a/Example/Source/macOS/CaptionsViewController.swift +++ b/Example/Source/macOS/CaptionsViewController.swift @@ -10,17 +10,17 @@ import AppKit import Capable class CaptionsViewController: NSViewController { - @IBOutlet weak var progressIndicator: NSProgressIndicator! - @IBOutlet weak var content: NSView! - @IBOutlet weak var topLeftLabel: NSTextField! - @IBOutlet weak var topCenterLabel: NSTextField! - @IBOutlet weak var topRightLabel: NSTextField! - @IBOutlet weak var centerLeftLabel: NSTextField! - @IBOutlet weak var centerLabel: NSTextField! - @IBOutlet weak var centerRightLabel: NSTextField! - @IBOutlet weak var bottomLeftLabel: NSTextField! - @IBOutlet weak var bottomCenterLabel: NSTextField! - @IBOutlet weak var bottomRightLabel: NSTextField! + @IBOutlet var progressIndicator: NSProgressIndicator! + @IBOutlet var content: NSView! + @IBOutlet var topLeftLabel: NSTextField! + @IBOutlet var topCenterLabel: NSTextField! + @IBOutlet var topRightLabel: NSTextField! + @IBOutlet var centerLeftLabel: NSTextField! + @IBOutlet var centerLabel: NSTextField! + @IBOutlet var centerRightLabel: NSTextField! + @IBOutlet var bottomLeftLabel: NSTextField! + @IBOutlet var bottomCenterLabel: NSTextField! + @IBOutlet var bottomRightLabel: NSTextField! var isLoading: Bool = true { didSet { @@ -43,7 +43,7 @@ class CaptionsViewController: NSViewController { private func setupLabelColors() { let backgroundImage = NSImage(named: "captions_gradient")! - let labels: [NSTextField:ImageArea] = [ + let labels: [NSTextField: ImageArea] = [ topLeftLabel: .topLeft, topCenterLabel: .topCenter, topRightLabel: .topRight, @@ -52,7 +52,7 @@ class CaptionsViewController: NSViewController { centerRightLabel: .centerRight, bottomLeftLabel: .bottomLeft, bottomCenterLabel: .bottomCenter, - bottomRightLabel: .bottomRight + bottomRightLabel: .bottomRight, ] isLoading = true diff --git a/Example/Source/macOS/ColorsViewController.swift b/Example/Source/macOS/ColorsViewController.swift index b26b32e..dc053e3 100644 --- a/Example/Source/macOS/ColorsViewController.swift +++ b/Example/Source/macOS/ColorsViewController.swift @@ -10,13 +10,13 @@ import AppKit import Capable class ColorsViewController: NSViewController { - @IBOutlet weak var textColorWell: NSColorWell! - @IBOutlet weak var backgroundColorWell: NSColorWell! - @IBOutlet weak var contrastRatioLabel: NSTextField! - @IBOutlet weak var aaSmallTextView: ConformanceLevelView! - @IBOutlet weak var aaaSmallTextView: ConformanceLevelView! - @IBOutlet weak var aaLargeTextView: ConformanceLevelView! - @IBOutlet weak var aaaLargeTextView: ConformanceLevelView! + @IBOutlet var textColorWell: NSColorWell! + @IBOutlet var backgroundColorWell: NSColorWell! + @IBOutlet var contrastRatioLabel: NSTextField! + @IBOutlet var aaSmallTextView: ConformanceLevelView! + @IBOutlet var aaaSmallTextView: ConformanceLevelView! + @IBOutlet var aaLargeTextView: ConformanceLevelView! + @IBOutlet var aaaLargeTextView: ConformanceLevelView! var textColor: NSColor = .capableGreen var backgroundColor: NSColor = .black @@ -34,43 +34,45 @@ class ColorsViewController: NSViewController { } // MARK: - Updating Views + extension ColorsViewController { func setupView() { - self.textColorWell.color = self.textColor - self.backgroundColorWell.color = self.backgroundColor + textColorWell.color = textColor + backgroundColorWell.color = backgroundColor updateContrastRatio() - self.aaSmallTextView.text = "AA" - self.aaaSmallTextView.text = "AAA" - self.aaLargeTextView.text = "AA (Large Text)" - self.aaaLargeTextView.text = "AAA (Large Text)" + aaSmallTextView.text = "AA" + aaaSmallTextView.text = "AAA" + aaLargeTextView.text = "AA (Large Text)" + aaaLargeTextView.text = "AAA (Large Text)" updateConformanceLevelViews() } func updateConformanceLevelViews() { guard let contrastRatio = self.contrastRatio else { return } - self.aaSmallTextView.isPassing = contrastRatio >= 4.5 - self.aaaSmallTextView.isPassing = contrastRatio >= 7.0 - self.aaLargeTextView.isPassing = contrastRatio >= 3.0 - self.aaaLargeTextView.isPassing = contrastRatio >= 4.5 + aaSmallTextView.isPassing = contrastRatio >= 4.5 + aaaSmallTextView.isPassing = contrastRatio >= 7.0 + aaLargeTextView.isPassing = contrastRatio >= 3.0 + aaaLargeTextView.isPassing = contrastRatio >= 4.5 } func updateContrastRatio() { if let contrastRatio = NSColor.getContrastRatio(forTextColor: self.textColor, onBackgroundColor: self.backgroundColor) { self.contrastRatio = contrastRatio - self.contrastRatioLabel.stringValue = String(format: "%.2f", contrastRatio) + contrastRatioLabel.stringValue = String(format: "%.2f", contrastRatio) } } } // MARK: - Handling Color Selection + extension ColorsViewController { - func colorChanged(_ sender : NSColorWell) { - if sender == self.textColorWell { - self.textColor = sender.color - } else if sender == self.backgroundColorWell { - self.backgroundColor = sender.color + func colorChanged(_ sender: NSColorWell) { + if sender == textColorWell { + textColor = sender.color + } else if sender == backgroundColorWell { + backgroundColor = sender.color } updateContrastRatio() @@ -79,19 +81,20 @@ extension ColorsViewController { } // MARK: - ColorWell Observation + extension ColorsViewController { func registerObservers() { - self.textColorWell.addObserver(self, forKeyPath: "color", options: .new, context: nil) - self.backgroundColorWell.addObserver(self, forKeyPath: "color", options: .new, context: nil) + textColorWell.addObserver(self, forKeyPath: "color", options: .new, context: nil) + backgroundColorWell.addObserver(self, forKeyPath: "color", options: .new, context: nil) } func unregisterObservers() { - self.textColorWell.removeObserver(self, forKeyPath:"color") - self.backgroundColorWell.removeObserver(self, forKeyPath:"color") + textColorWell.removeObserver(self, forKeyPath: "color") + backgroundColorWell.removeObserver(self, forKeyPath: "color") } - override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { - if (keyPath! == "color") { + override func observeValue(forKeyPath keyPath: String?, of object: Any?, change _: [NSKeyValueChangeKey: Any]?, context _: UnsafeMutableRawPointer?) { + if keyPath! == "color" { guard let colorWell = object as? NSColorWell else { return } @@ -100,4 +103,3 @@ extension ColorsViewController { } } } - diff --git a/Example/Source/macOS/FeatureOverviewController.swift b/Example/Source/macOS/FeatureOverviewController.swift index af17e36..9d40b66 100644 --- a/Example/Source/macOS/FeatureOverviewController.swift +++ b/Example/Source/macOS/FeatureOverviewController.swift @@ -6,47 +6,48 @@ // Copyright © 2018 Christoph Wendt. All rights reserved. // -import Cocoa import Capable +import Cocoa class FeatureOverviewController: NSViewController { - @IBOutlet weak var featuresTableView: NSTableView! + @IBOutlet var featuresTableView: NSTableView! var objects: [String: String]? var capable: Capable? var alert: NSAlert? override func viewDidLoad() { super.viewDidLoad() - self.capable = Capable() - self.refreshData() + capable = Capable() + refreshData() } override func viewWillAppear() { super.viewWillAppear() - self.registerObservers() + registerObservers() } override func viewWillDisappear() { super.viewWillDisappear() - self.unregisterObservers() + unregisterObservers() } func refreshData() { if let capable = self.capable { - self.objects = capable.statusMap + objects = capable.statusMap } } } // MARK: - Table View -extension FeatureOverviewController: NSTableViewDataSource, NSTableViewDelegate{ - func numberOfRows(in tableView: NSTableView) -> Int { + +extension FeatureOverviewController: NSTableViewDataSource, NSTableViewDelegate { + func numberOfRows(in _: NSTableView) -> Int { return objects?.count ?? 0 } - func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView?{ + func tableView(_ tableView: NSTableView, viewFor _: NSTableColumn?, row: Int) -> NSView? { let cell: FeatureTableCellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "FeatureRow"), owner: self) as! FeatureTableCellView - let feature = self.value(forRow: row) + let feature = value(forRow: row) cell.textLabel.stringValue = feature.key cell.detailTextLabel.stringValue = feature.value @@ -63,29 +64,32 @@ extension FeatureOverviewController: NSTableViewDataSource, NSTableViewDelegate{ } // MARK: - Toolbar actions + extension FeatureOverviewController { - @IBAction func refresh(_ sender: Any) { - self.refreshData() - self.featuresTableView.reloadData() + @IBAction func refresh(_: Any) { + refreshData() + featuresTableView.reloadData() } } // MARK: Capable Notification + extension FeatureOverviewController { @objc private func featureStatusChanged(notification: NSNotification) { if let featureStatus = notification.object as? FeatureStatus { - self.showAlert(for: featureStatus) + showAlert(for: featureStatus) refreshData() - self.featuresTableView.reloadData() + featuresTableView.reloadData() } } func registerObservers() { NotificationCenter.default.addObserver( self, - selector: #selector(self.featureStatusChanged), + selector: #selector(featureStatusChanged), name: .CapableFeatureStatusDidChange, - object: nil) + object: nil + ) } func unregisterObservers() { @@ -94,6 +98,7 @@ extension FeatureOverviewController { } // MARK: Alert + extension FeatureOverviewController { private func showAlert(for featureStatus: FeatureStatus) { let alert = NSAlert() diff --git a/Example/Source/macOS/FeatureTableCellView.swift b/Example/Source/macOS/FeatureTableCellView.swift index e302e21..384f583 100644 --- a/Example/Source/macOS/FeatureTableCellView.swift +++ b/Example/Source/macOS/FeatureTableCellView.swift @@ -6,10 +6,10 @@ // Copyright © 2018 Christoph Wendt. All rights reserved. // -import Foundation import Cocoa +import Foundation class FeatureTableCellView: NSTableCellView { - @IBOutlet weak var textLabel: NSTextField! - @IBOutlet weak var detailTextLabel: NSTextField! + @IBOutlet var textLabel: NSTextField! + @IBOutlet var detailTextLabel: NSTextField! } diff --git a/Example/Source/macOS/HandicapTableCellView.swift b/Example/Source/macOS/HandicapTableCellView.swift index 220b468..185ad49 100644 --- a/Example/Source/macOS/HandicapTableCellView.swift +++ b/Example/Source/macOS/HandicapTableCellView.swift @@ -6,11 +6,11 @@ // Copyright © 2018 Christoph Wendt. All rights reserved. // -import Foundation import Cocoa +import Foundation class HandicapTableCellView: NSTableCellView { - @IBOutlet weak var textLabel: NSTextField! - @IBOutlet weak var subtitleTextLabel: NSTextField! - @IBOutlet weak var detailTextLabel: NSTextField! + @IBOutlet var textLabel: NSTextField! + @IBOutlet var subtitleTextLabel: NSTextField! + @IBOutlet var detailTextLabel: NSTextField! } diff --git a/Example/Source/macOS/HandicapViewController.swift b/Example/Source/macOS/HandicapViewController.swift index a7fbe8c..281d0d1 100644 --- a/Example/Source/macOS/HandicapViewController.swift +++ b/Example/Source/macOS/HandicapViewController.swift @@ -6,11 +6,11 @@ // Copyright © 2018 Christoph Wendt. All rights reserved. // -import Cocoa import Capable +import Cocoa class HandicapViewController: NSViewController { - @IBOutlet weak var handicapTableView: NSTableView! + @IBOutlet var handicapTableView: NSTableView! var capable: Capable? var objects: [String: String]? var handicaps: [Handicap]? @@ -19,37 +19,38 @@ class HandicapViewController: NSViewController { override func viewDidLoad() { super.viewDidLoad() let lowVision = Handicap(features: [.increaseContrast, .invertColors, .reduceTransparency], name: "Low Vision", enabledIf: .oneFeatureEnabled) - self.capable = Capable(withHandicaps: [lowVision]) - self.handicaps = [lowVision] - self.refreshData() + capable = Capable(withHandicaps: [lowVision]) + handicaps = [lowVision] + refreshData() } override func viewWillAppear() { super.viewWillAppear() - self.registerObservers() + registerObservers() } override func viewWillDisappear() { super.viewWillDisappear() - self.unregisterObservers() + unregisterObservers() } func refreshData() { if let capable = self.capable { - self.objects = capable.statusMap + objects = capable.statusMap } } } // MARK: - Table View -extension HandicapViewController: NSTableViewDataSource, NSTableViewDelegate{ - func numberOfRows(in tableView: NSTableView) -> Int { + +extension HandicapViewController: NSTableViewDataSource, NSTableViewDelegate { + func numberOfRows(in _: NSTableView) -> Int { return objects?.count ?? 0 } - func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView?{ + func tableView(_ tableView: NSTableView, viewFor _: NSTableColumn?, row: Int) -> NSView? { let cell: HandicapTableCellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "HandicapRow"), owner: self) as! HandicapTableCellView - let status = self.value(forRow: row) + let status = value(forRow: row) let handicap = self.handicap(forName: status.key) cell.textLabel!.stringValue = handicap.name cell.subtitleTextLabel!.stringValue = CapableFeature.keys(forFeatures: handicap.features).joined(separator: ", ") @@ -67,7 +68,7 @@ extension HandicapViewController: NSTableViewDataSource, NSTableViewDelegate{ } func handicap(forName name: String) -> Handicap { - for handicap in self.handicaps! { + for handicap in handicaps! { if handicap.name == name { return handicap } @@ -77,29 +78,32 @@ extension HandicapViewController: NSTableViewDataSource, NSTableViewDelegate{ } // MARK: - Toolbar actions + extension HandicapViewController { - @IBAction func refresh(_ sender: Any) { - self.refreshData() - self.handicapTableView.reloadData() + @IBAction func refresh(_: Any) { + refreshData() + handicapTableView.reloadData() } } // MARK: Capable Notification + extension HandicapViewController { @objc private func handicapStatusChanged(notification: NSNotification) { if let handicapStatus = notification.object as? HandicapStatus { - self.showAlert(for: handicapStatus) + showAlert(for: handicapStatus) refreshData() - self.handicapTableView.reloadData() + handicapTableView.reloadData() } } func registerObservers() { NotificationCenter.default.addObserver( self, - selector: #selector(self.handicapStatusChanged), + selector: #selector(handicapStatusChanged), name: .CapableHandicapStatusDidChange, - object: nil) + object: nil + ) } func unregisterObservers() { @@ -108,6 +112,7 @@ extension HandicapViewController { } // MARK: Alert + extension HandicapViewController { private func showAlert(for handicapStatus: HandicapStatus) { let alert = NSAlert() @@ -120,4 +125,3 @@ extension HandicapViewController { self.alert?.runModal() } } - diff --git a/Example/Source/macOS/NSView+backgroundColor.swift b/Example/Source/macOS/NSView+backgroundColor.swift index 2fa24b4..56f5457 100644 --- a/Example/Source/macOS/NSView+backgroundColor.swift +++ b/Example/Source/macOS/NSView+backgroundColor.swift @@ -9,7 +9,6 @@ import AppKit extension NSView { - var backgroundColor: NSColor? { get { if let colorRef = self.layer?.backgroundColor { @@ -19,8 +18,8 @@ extension NSView { } } set { - self.wantsLayer = true - self.layer?.backgroundColor = newValue?.cgColor + wantsLayer = true + layer?.backgroundColor = newValue?.cgColor } } } diff --git a/Example/Source/watchOS/Extension/ExtensionDelegate.swift b/Example/Source/watchOS/Extension/ExtensionDelegate.swift index abfcce9..d815782 100644 --- a/Example/Source/watchOS/Extension/ExtensionDelegate.swift +++ b/Example/Source/watchOS/Extension/ExtensionDelegate.swift @@ -9,7 +9,6 @@ import WatchKit class ExtensionDelegate: NSObject, WKExtensionDelegate { - func applicationDidFinishLaunching() { // Perform any final initialization of your application. } @@ -46,5 +45,4 @@ class ExtensionDelegate: NSObject, WKExtensionDelegate { } } } - } diff --git a/Example/Source/watchOS/Extension/FeatureOverviewController.swift b/Example/Source/watchOS/Extension/FeatureOverviewController.swift index 35f0dfe..291b7fc 100644 --- a/Example/Source/watchOS/Extension/FeatureOverviewController.swift +++ b/Example/Source/watchOS/Extension/FeatureOverviewController.swift @@ -6,47 +6,47 @@ // Copyright © 2018 Christoph Wendt. All rights reserved. // -import WatchKit -import Foundation import Capable +import Foundation +import WatchKit class FeatureOverviewController: WKInterfaceController { var objects: [String: String]? var capable: Capable? @IBOutlet var featuresTable: WKInterfaceTable! - + override func awake(withContext context: Any?) { super.awake(withContext: context) - self.capable = Capable() - self.refreshData() - self.populateTableData() + capable = Capable() + refreshData() + populateTableData() } override func didAppear() { - self.registerObservers() + registerObservers() } override func willDisappear() { - self.unregisterObservers() + unregisterObservers() } func populateTableData() { if let objects = self.objects { - self.featuresTable.setNumberOfRows(objects.count, withRowType: "FeatureRow") - for index in 0.. (key: String, value: String) { if let objects = self.objects { let featuresArray = Array(objects) @@ -57,34 +57,36 @@ class FeatureOverviewController: WKInterfaceController { } // MARK: Capable Notification + extension FeatureOverviewController { @objc private func featureStatusChanged(notification: NSNotification) { if let featureStatus = notification.object as? FeatureStatus { - self.refreshData() - self.showAlert(for: featureStatus) + refreshData() + showAlert(for: featureStatus) } } func registerObservers() { NotificationCenter.default.addObserver( self, - selector: #selector(self.featureStatusChanged), + selector: #selector(featureStatusChanged), name: .CapableFeatureStatusDidChange, - object: nil) + object: nil + ) } func unregisterObservers() { NotificationCenter.default.removeObserver(self) } - + func showAlert(for featureStatus: FeatureStatus) { let alertTitle = "Feature status changed" let alertMessage = "\(featureStatus.feature.rawValue) changed to \(featureStatus.statusString)" let okAction = WKAlertAction(title: "OK", style: WKAlertActionStyle.default) {} presentAlert(withTitle: alertTitle, - message: alertMessage, - preferredStyle: WKAlertControllerStyle.alert, - actions: [okAction]) + message: alertMessage, + preferredStyle: WKAlertControllerStyle.alert, + actions: [okAction]) } } diff --git a/Example/Source/watchOS/Extension/FeatureRowController.swift b/Example/Source/watchOS/Extension/FeatureRowController.swift index 1503d55..f19cb68 100644 --- a/Example/Source/watchOS/Extension/FeatureRowController.swift +++ b/Example/Source/watchOS/Extension/FeatureRowController.swift @@ -6,14 +6,14 @@ // Copyright © 2018 Christoph Wendt. All rights reserved. // -import Foundation import Capable +import Foundation import WatchKit class FeatureRowController: NSObject { @IBOutlet var titleLabel: WKInterfaceLabel! @IBOutlet var statusLabel: WKInterfaceLabel! - + var feature: (key: String, value: String)? { didSet { guard let feature = feature else { return } diff --git a/Example/Source/watchOS/Extension/FontsViewController.swift b/Example/Source/watchOS/Extension/FontsViewController.swift index a3ee579..5ffe896 100644 --- a/Example/Source/watchOS/Extension/FontsViewController.swift +++ b/Example/Source/watchOS/Extension/FontsViewController.swift @@ -6,16 +6,16 @@ // Copyright © 2018 Christoph Wendt. All rights reserved. // -import WatchKit import Foundation +import WatchKit class FontsViewController: WKInterfaceController { @IBOutlet var fontsTable: WKInterfaceTable! override func awake(withContext context: Any?) { super.awake(withContext: context) - self.fontsTable.setNumberOfRows(FontsConstants.fontsList.count, withRowType: "FontRow") - for index in 0.. Handicap { - for handicap in self.handicaps! { + for handicap in handicaps! { if handicap.name == name { return handicap } @@ -71,20 +71,22 @@ class HandicapOverviewController: WKInterfaceController { } // MARK: Capable Notification + extension HandicapOverviewController { @objc private func handicapStatusChanged(notification: NSNotification) { if let handicapStatus = notification.object as? HandicapStatus { - self.refreshData() - self.showAlert(for: handicapStatus) + refreshData() + showAlert(for: handicapStatus) } } func registerObservers() { NotificationCenter.default.addObserver( self, - selector: #selector(self.handicapStatusChanged), + selector: #selector(handicapStatusChanged), name: .CapableHandicapStatusDidChange, - object: nil) + object: nil + ) } func unregisterObservers() { diff --git a/Example/Source/watchOS/Extension/OverviewController.swift b/Example/Source/watchOS/Extension/OverviewController.swift index 799db4f..23ea859 100644 --- a/Example/Source/watchOS/Extension/OverviewController.swift +++ b/Example/Source/watchOS/Extension/OverviewController.swift @@ -6,8 +6,8 @@ // Copyright © 2018 Christoph Wendt. All rights reserved. // -import WatchKit import Foundation +import WatchKit class OverviewController: WKInterfaceController { @IBOutlet var overviewTable: WKInterfaceTable! @@ -21,15 +21,15 @@ class OverviewController: WKInterfaceController { override func awake(withContext context: Any?) { super.awake(withContext: context) - self.overviewTable.setNumberOfRows(Content.items.count, withRowType: "OverviewRow") - for index in 0.. Image { + #if os(iOS) || os(tvOS) + + UIGraphicsBeginImageContext(rect.size) + let context = UIGraphicsGetCurrentContext() + context!.setFillColor(color.cgColor) + context!.fill(rect) + let image = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + return image! + + #elseif os(OSX) + + let rgbaColor = color.rgbaColor! + let ciColor = CIColor(red: rgbaColor.red, green: rgbaColor.green, blue: rgbaColor.blue, alpha: rgbaColor.alpha) + let ciImage = CIImage(color: ciColor) + let context = CIContext(options: nil) + guard let cgImage = context.createCGImage(ciImage, from: rect) else { + fatalError("Error creating the mock image.") + } + + return Image(cgImage: cgImage, size: rect.size) + + #endif + } +} diff --git a/Example/Tests/Colors/NSFontFontPropsTests.swift b/Example/Tests/Colors/NSFontFontPropsTests.swift new file mode 100644 index 0000000..4d6fd8c --- /dev/null +++ b/Example/Tests/Colors/NSFontFontPropsTests.swift @@ -0,0 +1,62 @@ +// +// NSFontFontPropsTests.swift +// CapableTests +// +// Created by Christoph Wendt on 23.12.18. +// + +#if os(OSX) + + @testable import Capable + import Nimble + import Quick + + class NSFontFontPropsTests: QuickSpec { + override func spec() { + describe("The NSFont class") { + var sut: FontProps? + + context("when initialized with a regular font") { + var testFont: NSFont? + + beforeEach { + testFont = NSFont.systemFont(ofSize: 23.0) + } + + context("when calling fontProps") { + beforeEach { + sut = testFont!.fontProps + } + + it("returns a fontProps instance that holds the correct font size") { + expect(sut!.fontSize).to(equal(testFont?.pointSize)) + } + + it("returns a fontProps instance that has the isBoldFont property set to false") { + expect(sut!.isBoldFont).to(beFalse()) + } + } + } + + context("when initialized with a bold font") { + var testFont: NSFont? + + beforeEach { + testFont = NSFont.boldSystemFont(ofSize: 23.0) + } + + context("when calling fontProps") { + beforeEach { + sut = testFont!.fontProps + } + + it("returns a fontProps instance that has the isBoldFont property set to true") { + expect(sut!.isBoldFont).to(beTrue()) + } + } + } + } + } + } + +#endif diff --git a/Tests/Colors/RGBAColorTests.swift b/Example/Tests/Colors/RGBAColorTests.swift similarity index 100% rename from Tests/Colors/RGBAColorTests.swift rename to Example/Tests/Colors/RGBAColorTests.swift index 1729214..9bdf43b 100644 --- a/Tests/Colors/RGBAColorTests.swift +++ b/Example/Tests/Colors/RGBAColorTests.swift @@ -5,9 +5,9 @@ // Created by Christoph Wendt on 24.11.18. // -import Quick -import Nimble @testable import Capable +import Nimble +import Quick class RGBAColorTests: QuickSpec { override func spec() { diff --git a/Example/Tests/Colors/UIFontFontPropsTests.swift b/Example/Tests/Colors/UIFontFontPropsTests.swift new file mode 100644 index 0000000..53cd948 --- /dev/null +++ b/Example/Tests/Colors/UIFontFontPropsTests.swift @@ -0,0 +1,62 @@ +// +// UIFontFontPropsTests.swift +// CapableTests +// +// Created by Christoph Wendt on 03.01.19. +// + +#if os(iOS) || os(tvOS) + + @testable import Capable + import Nimble + import Quick + + class UIFontFontPropsTests: QuickSpec { + override func spec() { + describe("The UIFont class") { + var sut: FontProps? + + context("when initialized with a regular font") { + var testFont: UIFont? + + beforeEach { + testFont = UIFont.systemFont(ofSize: 23.0) + } + + context("when calling fontProps") { + beforeEach { + sut = testFont!.fontProps + } + + it("returns a fontProps instance that holds the correct font size") { + expect(sut!.fontSize).to(equal(testFont?.pointSize)) + } + + it("returns a fontProps instance that has the isBoldFont property set to false") { + expect(sut!.isBoldFont).to(beFalse()) + } + } + } + + context("when initialized with a bold font") { + var testFont: UIFont? + + beforeEach { + testFont = UIFont.boldSystemFont(ofSize: 23.0) + } + + context("when calling fontProps") { + beforeEach { + sut = testFont!.fontProps + } + + it("returns a fontProps instance that has the isBoldFont property set to true") { + expect(sut!.isBoldFont).to(beTrue()) + } + } + } + } + } + } + +#endif diff --git a/Tests/Common/LoggerTests.swift b/Example/Tests/Common/LoggerTests.swift similarity index 98% rename from Tests/Common/LoggerTests.swift rename to Example/Tests/Common/LoggerTests.swift index ad8f605..9147c10 100644 --- a/Tests/Common/LoggerTests.swift +++ b/Example/Tests/Common/LoggerTests.swift @@ -5,10 +5,10 @@ // Created by Christoph Wendt on 09.11.18. // -import Quick +@testable import Capable import Nimble import os.log -@testable import Capable +import Quick class LoggerTests: QuickSpec { override func spec() { @@ -18,7 +18,7 @@ class LoggerTests: QuickSpec { beforeEach { testLoggedMessagesTypes = [] - testOnLog = { message, logType in + testOnLog = { _, logType in testLoggedMessagesTypes?.append(logType) } Logger.onLog = testOnLog! diff --git a/Example/Tests/Features/CapablePerfTests.swift b/Example/Tests/Features/CapablePerfTests.swift new file mode 100644 index 0000000..7a6b2dc --- /dev/null +++ b/Example/Tests/Features/CapablePerfTests.swift @@ -0,0 +1,28 @@ +// +// CapablePerfTests.swift +// CapableTests +// +// Created by Wendt, Christoph on 16.08.18. +// + +#if os(iOS) || os(tvOS) || os(OSX) + + import Capable + import XCTest + + class CapablePerfTests: XCTestCase { + var sut: Capable? + + override func setUp() { + super.setUp() + sut = Capable(withFeatures: CapableFeature.allCases) + } + + func testStatusMapPerformance() { + measure { + _ = sut!.statusMap + } + } + } + +#endif diff --git a/Example/Tests/Features/CapableTests.swift b/Example/Tests/Features/CapableTests.swift new file mode 100644 index 0000000..993c32f --- /dev/null +++ b/Example/Tests/Features/CapableTests.swift @@ -0,0 +1,243 @@ +// +// CapableTests.swift +// CapableTests +// +// Created by Christoph Wendt on 23.03.18. +// + +#if os(iOS) || os(tvOS) || os(OSX) + + @testable import Capable + import Nimble + import os.log + import Quick + + class CapableTests: QuickSpec { + override func spec() { + describe("The Capable class") { + var featureStatusesProviderMock: FeatureStatusesProviderMock? + + beforeEach { + featureStatusesProviderMock = FeatureStatusesProviderMock() + } + + context("after initialization with features") { + context("when providing specific features") { + var sut: Capable? + var testedFeatures: [CapableFeature]? + + beforeEach { + testedFeatures = [.reduceMotion, .voiceOver] + sut = Capable(withFeatures: testedFeatures!) + } + + it("creates a Capable instance") { + expect(sut!).to(beAnInstanceOf(Capable.self)) + } + + it("initializes its feature statuses provider correctly") { + expect(sut!.featureStatusesProvider).to(beAnInstanceOf(FeatureStatusesProvider.self)) + } + + it("initializes its statuses module correctly") { + expect(sut!.statusesModule).to(beAnInstanceOf(FeatureStatuses.self)) + // swiftlint:disable force_cast + let featureStatuses = sut!.statusesModule as! FeatureStatuses + // swiftlint:enable force_cast + expect(featureStatuses.features).to(equal(sut!.features)) + expect(featureStatuses.featureStatusesProvider).to(be(sut!.featureStatusesProvider)) + } + + it("initializes its notifications module correctly") { + expect(sut!.notificationsModule).to(beAnInstanceOf(FeatureNotifications.self)) + // swiftlint:disable force_cast + let featureNotifications = sut!.notificationsModule as! FeatureNotifications + // swiftlint:enable force_cast + + expect(featureNotifications.featureStatusesProvider).to(be(sut!.featureStatusesProvider)) + expect(featureNotifications.targetNotificationCenter).to(equal(NotificationCenter.default)) + + #if os(OSX) + expect(featureNotifications.systemNotificationCenter).to(equal(NSWorkspace.shared.notificationCenter)) + #else + expect(featureNotifications.systemNotificationCenter).to(equal(NotificationCenter.default)) + #endif + } + + it("sets the features property correctly") { + expect(sut!.features).to(equal(testedFeatures)) + } + } + + context("when providing no parameters") { + var sut: Capable? + + beforeEach { + sut = Capable() + } + + it("registeres all features") { + expect(sut!.features).to(equal(CapableFeature.allCases)) + } + } + + context("after initialization") { + var sut: Capable? + var testStatuses: FeatureStatusesMock? + + beforeEach { + testStatuses = FeatureStatusesMock() + sut = Capable(withFeatures: [], featureStatusesProvider: featureStatusesProviderMock!, statusesModule: testStatuses!, notificationModule: FeatureNotifications(featureStatusesProvider: featureStatusesProviderMock!)) + } + + context("when calling statusMap") { + beforeEach { + _ = sut!.statusMap + } + + it("requests the status map from the statuses module") { + expect(testStatuses!.didCallStatusMap).to(beTrue()) + } + } + + context("when calling isFeatureEnabled") { + beforeEach { + _ = sut!.isFeatureEnabled(feature: .voiceOver) + } + + it("requests the status map from the statuses module") { + expect(featureStatusesProviderMock!.didCallIsFeatureEnabled).to(beTrue()) + } + } + } + } + + context("after initialization with Handicaps") { + context("when providing a Handicap ") { + var sut: Capable? + var testHandicap: Handicap? + + beforeEach { + testHandicap = Handicap(features: [.voiceOver], name: "TestHandicap", enabledIf: .allFeaturesEnabled) + sut = Capable(withHandicaps: [testHandicap!]) + } + + it("creates a Capable instance") { + expect(sut!).to(beAnInstanceOf(Capable.self)) + } + + it("initializes its feature statuses provider correctly") { + expect(sut!.featureStatusesProvider).to(beAnInstanceOf(FeatureStatusesProvider.self)) + } + + it("initializes its statuses module correctly") { + expect(sut!.statusesModule).to(beAnInstanceOf(HandicapStatuses.self)) + // swiftlint:disable force_cast + let handicapStatuses = sut!.statusesModule as! HandicapStatuses + // swiftlint:enable force_cast + expect(handicapStatuses.featureStatusesProvider).to(be(sut!.featureStatusesProvider)) + } + + it("initializes its notifications module correctly") { + expect(sut!.notificationsModule).to(beAnInstanceOf(HandicapNotifications.self)) + // swiftlint:disable force_cast + let handicapNotifications = sut!.notificationsModule as! HandicapNotifications + // swiftlint:enable force_cast + expect(handicapNotifications.featureStatusesProvider).to(be(sut!.featureStatusesProvider)) + expect(handicapNotifications.targetNotificationCenter).to(equal(NotificationCenter.default)) + + #if os(OSX) + expect(handicapNotifications.systemNotificationCenter).to(equal(NSWorkspace.shared.notificationCenter)) + #else + expect(handicapNotifications.systemNotificationCenter).to(equal(NotificationCenter.default)) + #endif + } + + it("sets the handicaps property correctly") { + expect(sut!.handicaps).to(equal([testHandicap])) + } + } + + context("after initialization") { + var sut: Capable? + var testStatuses: HandicapStatusesMock? + + beforeEach { + testStatuses = HandicapStatusesMock() + sut = Capable(withHandicaps: [], featureStatusesProvider: featureStatusesProviderMock!, statusesModule: testStatuses!, notificationModule: HandicapNotifications(featureStatusesProvider: featureStatusesProviderMock!)) + } + + context("when calling statusMap") { + beforeEach { + _ = sut!.statusMap + } + + it("requests the status map from the statuses module") { + expect(testStatuses!.didCallStatusMap).to(beTrue()) + } + } + + context("when calling isHandicapEnabled") { + beforeEach { + _ = sut!.isHandicapEnabled(handicapName: "TestHandicap") + } + + it("returns false") { + expect(testStatuses!.didCallIsHandicapEnabled).to(beTrue()) + } + } + } + + context("when setting the logType") { + var testLogType: OSLogType? + + beforeEach { + Logger.minLogType = .debug + testLogType = .error + Capable.minLogType = testLogType! + } + + it("sets the logType on the Logger") { + expect(Logger.minLogType).to(equal(testLogType!)) + } + + context("when requesting the logType") { + it("returns the correct value") { + expect(Capable.minLogType).to(equal(testLogType!)) + } + } + } + + context("when setting the onLog closure") { + var testOnLog: ((String, OSLogType) -> Void)? + var testDidCall: Bool = false + + beforeEach { + Logger.onLog = Logger.defaultOnLog + testDidCall = false + testOnLog = { _, _ in + testDidCall = true + } + Capable.onLog = testOnLog! + } + + it("sets the onLog closure on the Logger") { + Logger.onLog("test", .debug) + + expect(testDidCall).to(beTrue()) + } + + context("when requesting the onLog closure") { + it("returns the correct value") { + Capable.onLog("test", .debug) + + expect(testDidCall).to(beTrue()) + } + } + } + } + } + } + } + +#endif diff --git a/Example/Tests/Features/FeatureNotificationsTests.swift b/Example/Tests/Features/FeatureNotificationsTests.swift new file mode 100644 index 0000000..d3a1c9f --- /dev/null +++ b/Example/Tests/Features/FeatureNotificationsTests.swift @@ -0,0 +1,413 @@ +// +// FeatureNotificationsTests.swift +// CapableTests +// +// Created by Christoph Wendt on 24.08.18. +// + +#if os(iOS) || os(tvOS) || os(OSX) + + @testable import Capable + import Nimble + import Quick + + class FeatureNotificationsTests: QuickSpec { + override func spec() { + describe("The FeatureNotifications class") { + let featureDidChangeNotification = Notification.Name.CapableFeatureStatusDidChange + var targetNotificationCenterMock: NotificationCenterMock? + var systemNotificationCenterMock: NotificationCenterMock? + var featureStatusesProviderMock: FeatureStatusesProviderMock? + + beforeEach { + targetNotificationCenterMock = NotificationCenterMock() + systemNotificationCenterMock = NotificationCenterMock() + featureStatusesProviderMock = FeatureStatusesProviderMock() + } + + context("after initialization") { + var sut: FeatureNotifications? + var testFeatures: [CapableFeature]? + + beforeEach { + testFeatures = [] + sut = FeatureNotifications(featureStatusesProvider: featureStatusesProviderMock!, features: testFeatures!, targetNotificationCenter: targetNotificationCenterMock!, systemNotificationCenter: systemNotificationCenterMock!) + } + + it("creates a FeatureNotifications intsance") { + expect(sut!).to(beAnInstanceOf(FeatureNotifications.self)) + } + + it("sets properties correctly") { + // swiftlint:disable force_cast + expect(sut!.featureStatusesProvider as! FeatureStatusesProviderMock).to(be(featureStatusesProviderMock!)) + // swiftlint:enable force_cast + expect(sut!.targetNotificationCenter).to(equal(targetNotificationCenterMock!)) + expect(sut!.systemNotificationCenter).to(equal(systemNotificationCenterMock!)) + } + } + + context("after initialization with required initializer") { + var sut: FeatureNotifications? + + beforeEach { + sut = FeatureNotifications(featureStatusesProvider: featureStatusesProviderMock!, targetNotificationCenter: targetNotificationCenterMock!, systemNotificationCenter: systemNotificationCenterMock!) + } + + it("creates a FeatureNotifications intsance") { + expect(sut!).to(beAnInstanceOf(FeatureNotifications.self)) + } + + it("sets statuses property correctly") { + // swiftlint:disable force_cast + expect(sut!.featureStatusesProvider as! FeatureStatusesProviderMock).to(be(featureStatusesProviderMock!)) + // swiftlint:enable force_cast + expect(sut!.targetNotificationCenter).to(equal(targetNotificationCenterMock!)) + expect(sut!.systemNotificationCenter).to(equal(systemNotificationCenterMock!)) + } + } + + #if os(iOS) || os(tvOS) || os(OSX) + + context("after initialization with all features available") { + var sut: FeatureNotifications? + var testFeatures: [CapableFeature]? + + beforeEach { + testFeatures = CapableFeature.allCases + sut = FeatureNotifications(featureStatusesProvider: featureStatusesProviderMock!, features: testFeatures!, targetNotificationCenter: targetNotificationCenterMock!, systemNotificationCenter: systemNotificationCenterMock!) + } + + #if os(iOS) || os(tvOS) + + it("registers itself as observer for feature related notifications") { + expect(systemNotificationCenterMock!.observedNotifications).to(haveCount(testFeatures!.count)) + for feature in testFeatures! { + expect(systemNotificationCenterMock!.hasRegisteredNotification(forFeature: feature)).to(beTrue()) + } + } + + #endif + + #if os(OSX) + + it("registers itself as observer for the display options notification only once") { + expect(systemNotificationCenterMock!.observedNotifications).to(haveCount(1)) + expect(systemNotificationCenterMock!.hasRegisteredNotification(forName: NSWorkspace.accessibilityDisplayOptionsDidChangeNotification)).to(beTrue()) + } + + it("observs key path changes for features not related to display options") { + expect(sut!.keyValueObservations).to(haveCount(2)) + } + + #endif + + #if os(iOS) + + context("when AssistiveTouch was activated by the user") { + beforeEach { + featureStatusesProviderMock!.assistiveTouchEnabled = true + sut!.assistiveTouchStatusChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .assistiveTouch, statusString: "enabled") + } + } + + context("when DarkerSystemColors was activated by the user") { + beforeEach { + featureStatusesProviderMock!.darkerSystemColorsEnabled = true + sut!.darkerSystemColorsStatusChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .darkerSystemColors, statusString: "enabled") + } + } + + context("when DifferentiateWithoutColor was activated by the user") { + beforeEach { + featureStatusesProviderMock!.differentiateWithoutColor = true + sut!.differentiateWithoutColorStatusChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .differentiateWithoutColor, statusString: "enabled") + } + } + + context("when GuidedAccess was activated by the user") { + beforeEach { + featureStatusesProviderMock!.guidedAccessEnabled = true + sut!.guidedAccessStatusChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .guidedAccess, statusString: "enabled") + } + } + + context("when HearingDevice was activated by the user") { + beforeEach { + featureStatusesProviderMock!.hearingDeviceEar = .both + sut!.hearingDeviceStatusChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .hearingDevice, statusString: "both") + } + } + + context("when LargerText was activated by the user") { + var testContentSizeCategory: UIContentSizeCategory? + + beforeEach { + testContentSizeCategory = .accessibilityExtraExtraExtraLarge + featureStatusesProviderMock!.textCatagory = testContentSizeCategory! + sut!.largerTextStatusChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .largerText, statusString: testContentSizeCategory!.stringValue) + } + } + + context("when OnOffSwitchLabels was activated by the user") { + beforeEach { + featureStatusesProviderMock!.onOffSwitchLabelsEnabled = true + sut!.onOffSwitchLabelsStatusChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .onOffSwitchLabels, statusString: "enabled") + } + } + + context("when ShakeToUndo was activated by the user") { + beforeEach { + featureStatusesProviderMock!.shakeToUndoEnabled = true + sut!.shakeToUndoStatusChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .shakeToUndo, statusString: "enabled") + } + } + + context("when SpeakScreen was activated by the user") { + beforeEach { + featureStatusesProviderMock!.speakScreenEnabled = true + sut!.speakScreenStatusChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .speakScreen, statusString: "enabled") + } + } + + context("when SpeackSelection was activated by the user") { + beforeEach { + featureStatusesProviderMock!.speakSelectionEnabled = true + sut!.speakSelectionStatusChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .speakSelection, statusString: "enabled") + } + } + + #endif + + #if os(OSX) + + context("when DifferentiateWithoutColor was activated by the user") { + beforeEach { + featureStatusesProviderMock!.differentiateWithoutColor = true + sut!.displayOptionsChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .differentiateWithoutColor, statusString: "enabled") + } + } + + context("when IncreaseContrast was activated by the user") { + beforeEach { + featureStatusesProviderMock!.increaseContrast = true + sut!.displayOptionsChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .increaseContrast, statusString: "enabled") + } + } + + context("when InvertColors was activated by the user") { + beforeEach { + featureStatusesProviderMock!.invertColorsEnabled = true + sut!.displayOptionsChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .invertColors, statusString: "enabled") + } + } + + context("when ReduceMotion was activated by the user") { + beforeEach { + featureStatusesProviderMock!.reduceMotionEnabled = true + sut!.displayOptionsChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .reduceMotion, statusString: "enabled") + } + } + + context("when ReduceTransparency was activated by the user") { + beforeEach { + featureStatusesProviderMock!.reduceTransparencyEnabled = true + sut!.displayOptionsChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .reduceTransparency, statusString: "enabled") + } + } + + #endif + + #if os(iOS) || os(tvOS) + + context("when BoldText was activated by the user") { + beforeEach { + featureStatusesProviderMock!.boldTextEnabled = true + sut!.boldTextStatusChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .boldText, statusString: "enabled") + } + } + + context("when ClosedCaptioning was activated by the user") { + beforeEach { + featureStatusesProviderMock!.closedCaptioningEnabled = true + sut!.closedCaptioningStatusChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .closedCaptioning, statusString: "enabled") + } + } + + context("when Grayscale was activated by the user") { + beforeEach { + featureStatusesProviderMock!.grayscaleEnabled = true + sut!.grayscaleStatusChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .grayscale, statusString: "enabled") + } + } + + context("when InvertColors was activated by the user") { + beforeEach { + featureStatusesProviderMock!.invertColorsEnabled = true + sut!.invertColorsStatusChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .invertColors, statusString: "enabled") + } + } + + context("when MonoAudio was activated by the user") { + beforeEach { + featureStatusesProviderMock!.monoAudioEnabled = true + sut!.monoAudioStatusChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .monoAudio, statusString: "enabled") + } + } + + context("when ReduceMotion was activated by the user") { + beforeEach { + featureStatusesProviderMock!.reduceMotionEnabled = true + sut!.reduceMotionStatusChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .reduceMotion, statusString: "enabled") + } + } + + context("when ReduceTransparency was activated by the user") { + beforeEach { + featureStatusesProviderMock!.reduceTransparencyEnabled = true + sut!.reduceTransparencyStatusChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .reduceTransparency, statusString: "enabled") + } + } + + context("when VideoAutoplay was activated by the user") { + beforeEach { + featureStatusesProviderMock!.videoAutoplayEnabled = true + sut!.videoAutoplayStatusChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .videoAutoplay, statusString: "enabled") + } + } + + #endif + + context("when SwitchControl was activated by the user") { + beforeEach { + featureStatusesProviderMock!.switchControlEnabled = true + sut!.switchControlStatusChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .switchControl, statusString: "enabled") + } + } + + context("when VoiceOver was activated by the user") { + beforeEach { + featureStatusesProviderMock!.voiceOverEnabled = true + sut!.voiceOverStatusChanged() + } + + it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { + verifyFeatureDidChangeNotificationWasPosted(withFeature: .voiceOver, statusString: "enabled") + } + } + } + + func verifyFeatureDidChangeNotificationWasPosted(withFeature feature: CapableFeature, statusString: String) { + expect(targetNotificationCenterMock!.postedNotifications).to(haveCount(1)) + + let notificationObject = targetNotificationCenterMock!.postedNotifications[featureDidChangeNotification] + guard let featureStatus = notificationObject as? FeatureStatus else { + fail("Notification does not contain a FeatureStatus object.") + return + } + expect(featureStatus.feature).to(equal(feature)) + expect(featureStatus.statusString).to(equal(statusString)) + } + + #endif + } + } + } + +#endif diff --git a/Example/Tests/Features/FeatureStatusesProviderTests.swift b/Example/Tests/Features/FeatureStatusesProviderTests.swift new file mode 100644 index 0000000..1a3e9c0 --- /dev/null +++ b/Example/Tests/Features/FeatureStatusesProviderTests.swift @@ -0,0 +1,264 @@ +// +// FeatureStatusesProviderTests.swift +// CapableTests +// +// Created by Wendt, Christoph on 06.10.18. +// + +#if os(iOS) || os(tvOS) || os(OSX) + + @testable import Capable + import Nimble + import Quick + + class FeatureStatusesProviderTests: QuickSpec { + override func spec() { + describe("The FeatureStatusesProvider class") { + var sut: FeatureStatusesProviderMock? + + beforeEach { + sut = FeatureStatusesProviderMock() + } + + context("when calling isFeatureEnabled") { + #if os(iOS) + + context("for AssistiveTouch") { + beforeEach { + sut!.assistiveTouchEnabled = true + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .assistiveTouch)).to(beTrue()) + } + } + + context("for DarkerSystemColors") { + beforeEach { + sut!.darkerSystemColorsEnabled = true + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .darkerSystemColors)).to(beTrue()) + } + } + + context("for GuidedAccess") { + beforeEach { + sut!.guidedAccessEnabled = true + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .guidedAccess)).to(beTrue()) + } + } + + context("for HearingDevice") { + beforeEach { + sut!.hearingDeviceEar = .both + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .hearingDevice)).to(beTrue()) + } + } + + context("for InvertColors") { + beforeEach { + sut!.invertColorsEnabled = true + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .invertColors)).to(beTrue()) + } + } + + context("for LargerText") { + beforeEach { + sut!.textCatagory = .accessibilityLarge + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .largerText)).to(beTrue()) + } + } + + context("for OnOffSwitchLabels") { + beforeEach { + sut!.onOffSwitchLabelsEnabled = true + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .onOffSwitchLabels)).to(beTrue()) + } + } + + context("for ShakeToUndo") { + beforeEach { + sut!.shakeToUndoEnabled = true + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .shakeToUndo)).to(beTrue()) + } + } + + context("for SpeakScreen") { + beforeEach { + sut!.speakScreenEnabled = true + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .speakScreen)).to(beTrue()) + } + } + + context("for SpeakSelection") { + beforeEach { + sut!.speakSelectionEnabled = true + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .speakSelection)).to(beTrue()) + } + } + + #endif + + #if os(OSX) + + context("for FullKeyboardAccess") { + beforeEach { + sut!.fullKeyboardAccess = true + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .fullKeyboardAccess)).to(beTrue()) + } + } + + context("for IncreaseContrast") { + beforeEach { + sut!.increaseContrast = true + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .increaseContrast)).to(beTrue()) + } + } + + #endif + + #if os(iOS) || os(tvOS) + + context("for BoldText") { + beforeEach { + sut!.boldTextEnabled = true + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .boldText)).to(beTrue()) + } + } + + context("for ClosedCaptioning") { + beforeEach { + sut!.closedCaptioningEnabled = true + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .closedCaptioning)).to(beTrue()) + } + } + + context("for Grayscale") { + beforeEach { + sut!.grayscaleEnabled = true + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .grayscale)).to(beTrue()) + } + } + + context("for MonoAudio") { + beforeEach { + sut!.monoAudioEnabled = true + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .monoAudio)).to(beTrue()) + } + } + + context("for VideoAutoplay") { + beforeEach { + sut!.videoAutoplayEnabled = true + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .videoAutoplay)).to(beTrue()) + } + } + + #endif + + #if os(iOS) || os(OSX) + + context("for DifferentiateWithoutColor") { + beforeEach { + sut!.differentiateWithoutColor = true + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .differentiateWithoutColor)).to(beTrue()) + } + } + + #endif + + context("for ReduceMotion") { + beforeEach { + sut!.reduceMotionEnabled = true + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .reduceMotion)).to(beTrue()) + } + } + + context("for ReduceTransparency") { + beforeEach { + sut!.reduceTransparencyEnabled = true + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .reduceTransparency)).to(beTrue()) + } + } + + context("for SwitchControl") { + beforeEach { + sut!.switchControlEnabled = true + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .switchControl)).to(beTrue()) + } + } + + context("for VoiceOver") { + beforeEach { + sut!.voiceOverEnabled = true + } + + it("returns correct state") { + expect(sut!.isFeatureEnabled(feature: .voiceOver)).to(beTrue()) + } + } + } + } + } + } + +#endif diff --git a/Example/Tests/Features/FeatureStatusesTests.swift b/Example/Tests/Features/FeatureStatusesTests.swift new file mode 100644 index 0000000..f7b70db --- /dev/null +++ b/Example/Tests/Features/FeatureStatusesTests.swift @@ -0,0 +1,114 @@ +// +// FeatureStatusesTest.swift +// CapableTests +// +// Created by Christoph Wendt on 05.10.18. +// + +#if os(iOS) || os(tvOS) || os(OSX) + + @testable import Capable + import Nimble + import Quick + + class FeatureStatusesTests: QuickSpec { + override func spec() { + describe("The FeatureStatuses class") { + var featureStatusesProviderMock: FeatureStatusesProviderMock? + + beforeEach { + featureStatusesProviderMock = FeatureStatusesProviderMock() + } + + context("after initialization with all features") { + var sut: FeatureStatuses? + var testFeatures: [CapableFeature]? + + beforeEach { + testFeatures = CapableFeature.allCases + sut = FeatureStatuses(withFeatures: testFeatures!, featureStatusesProvider: featureStatusesProviderMock!) + } + + it("creates a FeatureStatuses instance with all properties set ") { + expect(sut!).to(beAnInstanceOf(FeatureStatuses.self)) + expect(sut!.features).to(equal(testFeatures)) + expect(sut!.featureStatusesProvider).to(be(featureStatusesProviderMock!)) + } + + context("when calling statusMap") { + var statusMap: [String: String]? + + beforeEach { + featureStatusesProviderMock!.enableAllFeatures() + statusMap = sut!.statusMap + } + + it("returns a status map containing all features") { + expect(statusMap!.count).to(equal(testFeatures!.count)) + expect(Array(statusMap!.keys)).to(contain(CapableFeature.keys(forFeatures: testFeatures!))) + } + + it("returns a status map containing the correct statuses") { + for key in statusMap!.keys { + #if os(iOS) + + if key == CapableFeature.largerText.rawValue { + expect(statusMap![key]).to(equal("Accessibility XXXL")) + } else if key == CapableFeature.hearingDevice.rawValue { + expect(statusMap![key]).to(equal("both")) + } else { + expect(statusMap![key]).to(equal("enabled")) + } + + #else + + expect(statusMap![key]).to(equal("enabled")) + + #endif + } + } + } + } + + context("when checking equality of two instances") { + var featureStatuses1: FeatureStatuses? + var featureStatuses2: FeatureStatuses? + + context("when they are holding different features") { + beforeEach { + featureStatuses1 = FeatureStatuses(withFeatures: [.voiceOver], featureStatusesProvider: FeatureStatusesProvider()) + featureStatuses2 = FeatureStatuses(withFeatures: [.reduceMotion], featureStatusesProvider: FeatureStatusesProvider()) + } + + it("returns false") { + expect(featureStatuses1 == featureStatuses2).to(beFalse()) + } + } + + context("when they use different feature status provider implementations") { + beforeEach { + featureStatuses1 = FeatureStatuses(withFeatures: [.voiceOver], featureStatusesProvider: featureStatusesProviderMock!) + featureStatuses2 = FeatureStatuses(withFeatures: [.voiceOver], featureStatusesProvider: FeatureStatusesProvider()) + } + + it("returns false") { + expect(featureStatuses1 == featureStatuses2).to(beFalse()) + } + } + + context("when they are holding the same features and using the same feature status provider implementation") { + beforeEach { + featureStatuses1 = FeatureStatuses(withFeatures: [.voiceOver], featureStatusesProvider: FeatureStatusesProvider()) + featureStatuses2 = FeatureStatuses(withFeatures: [.voiceOver], featureStatusesProvider: FeatureStatusesProvider()) + } + + it("returns true") { + expect(featureStatuses1 == featureStatuses2).to(beTrue()) + } + } + } + } + } + } + +#endif diff --git a/Example/Tests/Features/HandicapNotificationsTests.swift b/Example/Tests/Features/HandicapNotificationsTests.swift new file mode 100644 index 0000000..3e0f8e5 --- /dev/null +++ b/Example/Tests/Features/HandicapNotificationsTests.swift @@ -0,0 +1,239 @@ +// +// HandicapNotificationsTests.swift +// CapableTests +// +// Created by Christoph Wendt on 25.08.18. +// + +#if os(iOS) || os(tvOS) || os(OSX) + + @testable import Capable + import Nimble + import Quick + + class HandicapNotificationsTests: QuickSpec { + override func spec() { + describe("The HandicapNotifications class") { + let handicapDidChangeNotification = Notification.Name.CapableHandicapStatusDidChange + var targetNotificationCenterMock: NotificationCenterMock? + var systemNotificationCenterMock: NotificationCenterMock? + var featureStatusesProviderMock: FeatureStatusesProviderMock? + + beforeEach { + targetNotificationCenterMock = NotificationCenterMock() + systemNotificationCenterMock = NotificationCenterMock() + featureStatusesProviderMock = FeatureStatusesProviderMock() + } + + context("after initialization") { + var sut: HandicapNotifications? + var testStatuses: HandicapStatuses? + var testHandicaps: [Handicap]? + + beforeEach { + let handicap = Handicap(features: [], name: "test", enabledIf: .allFeaturesEnabled) + testHandicaps = [handicap] + testStatuses = HandicapStatuses(withHandicaps: [], featureStatusesProvider: featureStatusesProviderMock!) + sut = HandicapNotifications(statusesModule: testStatuses!, handicaps: testHandicaps!, featureStatusesProvider: featureStatusesProviderMock!, targetNotificationCenter: targetNotificationCenterMock!, systemNotificationCenter: systemNotificationCenterMock!) + } + + it("creates a HandicapNotifications intsance") { + expect(sut!).to(beAnInstanceOf(HandicapNotifications.self)) + } + + it("sets properties correctly") { + // swiftlint:disable force_cast + expect(sut!.statusesModule as! HandicapStatuses).to(equal(testStatuses!)) + expect(sut!.featureStatusesProvider as! FeatureStatusesProviderMock).to(be(featureStatusesProviderMock!)) + // swiftlint:enable force_cast + expect(sut!.targetNotificationCenter).to(equal(targetNotificationCenterMock!)) + expect(sut!.systemNotificationCenter).to(equal(systemNotificationCenterMock!)) + } + } + + context("after initialization with required initializer") { + var sut: HandicapNotifications? + var testStatuses: HandicapStatuses? + + beforeEach { + testStatuses = HandicapStatuses(withHandicaps: [], featureStatusesProvider: featureStatusesProviderMock!) + sut = HandicapNotifications(statusesModule: testStatuses!, handicaps: [], featureStatusesProvider: featureStatusesProviderMock!, targetNotificationCenter: targetNotificationCenterMock!, systemNotificationCenter: systemNotificationCenterMock!) + } + + it("creates a HandicapNotifications intsance") { + expect(sut!).to(beAnInstanceOf(HandicapNotifications.self)) + } + + it("sets statuses property correctly") { + // swiftlint:disable force_cast + expect(sut!.statusesModule as! HandicapStatuses).to(equal(testStatuses!)) + expect(sut!.featureStatusesProvider as! FeatureStatusesProviderMock).to(be(featureStatusesProviderMock!)) + // swiftlint:enable force_cast + expect(sut!.targetNotificationCenter).to(equal(targetNotificationCenterMock!)) + expect(sut!.systemNotificationCenter).to(equal(systemNotificationCenterMock!)) + } + } + + context("after initialization with two Handicaps containing the same feature") { + var sut: HandicapNotifications? + var testStatuses: HandicapStatuses? + var testHandicap1: Handicap? + var testHandicap2: Handicap? + var testFeature: CapableFeature? + + beforeEach { + testFeature = .voiceOver + testHandicap1 = Handicap(features: [testFeature!], name: "testHandicap1", enabledIf: .oneFeatureEnabled) + testHandicap2 = Handicap(features: [testFeature!], name: "testHandicap2", enabledIf: .oneFeatureEnabled) + testStatuses = HandicapStatuses(withHandicaps: [testHandicap1!, testHandicap2!], featureStatusesProvider: featureStatusesProviderMock!) + sut = HandicapNotifications(statusesModule: testStatuses!, handicaps: [testHandicap1!, testHandicap2!], featureStatusesProvider: featureStatusesProviderMock!, targetNotificationCenter: targetNotificationCenterMock!, systemNotificationCenter: systemNotificationCenterMock!) + } + + #if os(iOS) || os(tvOS) + + it("registers itself as observer for the feature notification only once") { + expect(systemNotificationCenterMock!.observedNotifications).to(haveCount(1)) + expect(systemNotificationCenterMock!.hasRegisteredNotification(forFeature: testFeature!)).to(beTrue()) + } + + #endif + + #if os(OSX) + + it("registers itself as observer for the display options notification only once") { + expect(systemNotificationCenterMock!.observedNotifications).to(haveCount(1)) + expect(systemNotificationCenterMock!.hasRegisteredNotification(forName: NSWorkspace.accessibilityDisplayOptionsDidChangeNotification)).to(beTrue()) + } + + it("observs key path changes for this feature only once") { + expect(sut!.keyValueObservations).to(haveCount(1)) + } + + #endif + } + + context("after initialization with a Handicap containing two features") { + var sut: HandicapNotifications? + var testStatuses: HandicapStatuses? + var testHandicap: Handicap? + var testFeature1: CapableFeature? + var testFeature2: CapableFeature? + + beforeEach { + testFeature1 = .voiceOver + testFeature2 = .reduceMotion + } + + context("when .enabledIf is set to .oneFeatureEnabled and both features are currently disabled") { + beforeEach { + testHandicap = Handicap(features: [testFeature1!, testFeature2!], name: "testHandicap", enabledIf: .oneFeatureEnabled) + testStatuses = HandicapStatuses(withHandicaps: [testHandicap!], featureStatusesProvider: featureStatusesProviderMock!) + featureStatusesProviderMock!.voiceOverEnabled = false + featureStatusesProviderMock!.reduceMotionEnabled = false + sut = HandicapNotifications(statusesModule: testStatuses!, handicaps: [testHandicap!], featureStatusesProvider: featureStatusesProviderMock!, targetNotificationCenter: targetNotificationCenterMock!, systemNotificationCenter: systemNotificationCenterMock!) + } + + afterEach { + featureStatusesProviderMock!.voiceOverEnabled = false + featureStatusesProviderMock!.reduceMotionEnabled = false + } + + #if os(iOS) || os(tvOS) + + it("registers itself as observer for both notifications") { + expect(systemNotificationCenterMock!.observedNotifications).to(haveCount(2)) + expect(systemNotificationCenterMock!.hasRegisteredNotification(forFeature: testFeature1!)).to(beTrue()) + expect(systemNotificationCenterMock!.hasRegisteredNotification(forFeature: testFeature2!)).to(beTrue()) + } + + #endif + + #if os(OSX) + + it("registers itself as observer for the display options notification (ReduceMotion)") { + expect(systemNotificationCenterMock!.observedNotifications).to(haveCount(1)) + expect(systemNotificationCenterMock!.hasRegisteredNotification(forName: NSWorkspace.accessibilityDisplayOptionsDidChangeNotification)).to(beTrue()) + } + + it("observs key path changes (VoiceOver) feature") { + expect(sut!.keyValueObservations).to(haveCount(1)) + } + + #endif + + context("when features get enabled one by one") { + it("posts a CapableHandicapStatusDidChange notification with the correct HandicapStatus only if needed") { + // Enable feature 1 => a notification is posted with status "enabled" + featureStatusesProviderMock!.voiceOverEnabled = true + sut!.voiceOverStatusChanged() + verifyHandicapDidChangeNotificationWasPosted(withHandicap: testHandicap!, statusString: "enabled") + + // Enable feature 2 => no notification is posted + featureStatusesProviderMock!.reduceMotionEnabled = true + sut!.reduceMotionStatusChanged() + expect(targetNotificationCenterMock!.postedNotifications).to(haveCount(1)) + + // Disable feature 2 => no notification is posted + featureStatusesProviderMock!.reduceMotionEnabled = false + sut!.reduceMotionStatusChanged() + expect(targetNotificationCenterMock!.postedNotifications).to(haveCount(1)) + + // Disable feature 2 => a notification is posted with status "disabled" + featureStatusesProviderMock!.voiceOverEnabled = false + sut!.voiceOverStatusChanged() + verifyHandicapDidChangeNotificationWasPosted(withHandicap: testHandicap!, statusString: "disabled") + } + } + } + + context("when .enabledIf is set to .allFeaturesEnabled and both features are currently disabled") { + beforeEach { + testHandicap = Handicap(features: [testFeature1!, testFeature2!], name: "testHandicap", enabledIf: .allFeaturesEnabled) + testStatuses = HandicapStatuses(withHandicaps: [testHandicap!], featureStatusesProvider: featureStatusesProviderMock!) + featureStatusesProviderMock!.voiceOverEnabled = false + featureStatusesProviderMock!.reduceMotionEnabled = false + sut = HandicapNotifications(statusesModule: testStatuses!, handicaps: [testHandicap!], featureStatusesProvider: featureStatusesProviderMock!, targetNotificationCenter: targetNotificationCenterMock!, systemNotificationCenter: systemNotificationCenterMock!) + } + + afterEach { + featureStatusesProviderMock!.voiceOverEnabled = false + featureStatusesProviderMock!.reduceMotionEnabled = false + } + + context("when features get enabled one by one") { + it("posts a CapableHandicapStatusDidChange notification with the correct HandicapStatus only if needed") { + // Enable feature 1 => no notification is posted + featureStatusesProviderMock!.voiceOverEnabled = true + sut!.voiceOverStatusChanged() + expect(targetNotificationCenterMock!.postedNotifications).to(haveCount(0)) + + // Enable feature 2 => a notification is posted with status "enabled" + featureStatusesProviderMock!.reduceMotionEnabled = true + sut!.reduceMotionStatusChanged() + verifyHandicapDidChangeNotificationWasPosted(withHandicap: testHandicap!, statusString: "enabled") + + // Disable feature 1 => a notification is posted with status "disabled" + featureStatusesProviderMock!.voiceOverEnabled = false + sut!.voiceOverStatusChanged() + verifyHandicapDidChangeNotificationWasPosted(withHandicap: testHandicap!, statusString: "disabled") + } + } + } + } + + func verifyHandicapDidChangeNotificationWasPosted(withHandicap handicap: Handicap, statusString: String) { + expect(targetNotificationCenterMock!.postedNotifications).to(haveCount(1)) + + let notificationObject = targetNotificationCenterMock!.postedNotifications[handicapDidChangeNotification] + guard let handicapStatus = notificationObject as? HandicapStatus else { + fail("Notification does not contain a HandicapStatus object.") + return + } + expect(handicapStatus.handicap).to(equal(handicap)) + expect(handicapStatus.statusString).to(equal(statusString)) + } + } + } + } + +#endif diff --git a/Example/Tests/Features/HandicapStatusesTests.swift b/Example/Tests/Features/HandicapStatusesTests.swift new file mode 100644 index 0000000..bad4882 --- /dev/null +++ b/Example/Tests/Features/HandicapStatusesTests.swift @@ -0,0 +1,178 @@ +// +// HandicapStatusesTests.swift +// CapableTests +// +// Created by Christoph Wendt on 05.10.18. +// + +#if os(iOS) || os(tvOS) || os(OSX) + + @testable import Capable + import Nimble + import Quick + + class HandicapStatusesTests: QuickSpec { + override func spec() { + describe("The HandicapStatuses class") { + var sut: HandicapStatuses? + var featureStatusesProviderMock: FeatureStatusesProviderMock? + + beforeEach { + featureStatusesProviderMock = FeatureStatusesProviderMock() + } + + context("after initialization with multiple handicaps") { + var testHandicap1: Handicap? + var testHandicap2: Handicap? + + beforeEach { + let testFeatures: [CapableFeature] = [.reduceMotion, .voiceOver] + testHandicap1 = Handicap(features: testFeatures, name: "TestHandicap1", enabledIf: .oneFeatureEnabled) + testHandicap2 = Handicap(features: testFeatures, name: "TestHandicap2", enabledIf: .allFeaturesEnabled) + sut = HandicapStatuses(withHandicaps: [testHandicap1!, testHandicap2!], featureStatusesProvider: featureStatusesProviderMock!) + } + + it("creates a HandicapStatuses instance with all properties set ") { + expect(sut!).to(beAnInstanceOf(HandicapStatuses.self)) + expect(sut!.handicapMap.count).to(equal(2)) + expect(Array(sut!.handicapMap.keys)).to(contain([testHandicap1!.name, testHandicap2!.name])) + expect(sut!.handicapMap[testHandicap1!.name]).to(equal(testHandicap1)) + expect(sut!.handicapMap[testHandicap2!.name]).to(equal(testHandicap2)) + expect(sut!.featureStatusesProvider).to(be(featureStatusesProviderMock!)) + } + + context("when calling statusMap") { + var statusMap: [String: String]? + + beforeEach { + featureStatusesProviderMock!.enableAllFeatures() + statusMap = sut!.statusMap + } + + it("returns a status map containing all features") { + expect(statusMap!.count).to(equal(2)) + expect(Array(statusMap!.keys)).to(contain([testHandicap1!.name, testHandicap2!.name])) + } + + it("returns a status map containing the correct statuses") { + for key in statusMap!.keys { + expect(statusMap![key]).to(equal("enabled")) + } + } + } + + context("when calling isHandicapEnabled") { + context("when requested Handicap has not been registered") { + beforeEach { + featureStatusesProviderMock!.enableAllFeatures() + } + + it("returns false") { + expect(sut!.isHandicapEnabled(handicapName: "notAvailable")).to(beFalse()) + } + } + + context("when enabledIf is set to .allFeaturesEnabled") { + var testHandicap: Handicap? + + beforeEach { + testHandicap = testHandicap2 + } + + context("when all features are enabled") { + beforeEach { + featureStatusesProviderMock!.reduceMotionEnabled = true + featureStatusesProviderMock!.voiceOverEnabled = true + } + + it("returns true") { + expect(sut!.isHandicapEnabled(handicapName: testHandicap!.name)).to(beTrue()) + } + } + + context("when one features is enabled") { + beforeEach { + featureStatusesProviderMock!.reduceMotionEnabled = true + featureStatusesProviderMock!.voiceOverEnabled = false + } + + it("returns false") { + expect(sut!.isHandicapEnabled(handicapName: testHandicap!.name)).to(beFalse()) + } + } + } + + context("when enabledIf is set to .oneFeatureEnabled") { + var testHandicap: Handicap? + + beforeEach { + testHandicap = testHandicap1 + } + + context("when one features are enabled") { + beforeEach { + featureStatusesProviderMock!.reduceMotionEnabled = true + featureStatusesProviderMock!.voiceOverEnabled = false + } + + it("returns true") { + expect(sut!.isHandicapEnabled(handicapName: testHandicap!.name)).to(beTrue()) + } + } + + context("when no features is enabled") { + beforeEach { + featureStatusesProviderMock!.reduceMotionEnabled = false + featureStatusesProviderMock!.voiceOverEnabled = false + } + + it("returns false") { + expect(sut!.isHandicapEnabled(handicapName: testHandicap!.name)).to(beFalse()) + } + } + } + } + } + + #if os(iOS) + + context("after initialization with a Handicap holding the .largerText feature") { + var testHandicapName: String? + + beforeEach { + testHandicapName = "TestHandicap" + let testHandicap = Handicap(features: [.largerText], name: testHandicapName!, enabledIf: .allFeaturesEnabled) + let testTextCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge + featureStatusesProviderMock!.textCatagory = testTextCategory + sut = HandicapStatuses(withHandicaps: [testHandicap], featureStatusesProvider: featureStatusesProviderMock!) + } + + it("returns a status map containing enabled/disabled rather than the actual text category for the Handicap") { + let statusMap = sut!.statusMap + expect(statusMap[testHandicapName!]).to(equal("enabled")) + } + } + + context("after initialization with a Handicap holding the .hearingDevice feature") { + var testHandicapName: String? + + beforeEach { + testHandicapName = "TestHandicap" + let testHandicap = Handicap(features: [.hearingDevice], name: testHandicapName!, enabledIf: .allFeaturesEnabled) + let testHearingDeviceEar: UIAccessibility.HearingDeviceEar = .both + featureStatusesProviderMock!.hearingDeviceEar = testHearingDeviceEar + sut = HandicapStatuses(withHandicaps: [testHandicap], featureStatusesProvider: featureStatusesProviderMock!) + } + + it("returns a status map containing enabled/disabled rather than the actual text category for the Handicap") { + let statusMap = sut!.statusMap + expect(statusMap[testHandicapName!]).to(equal("enabled")) + } + } + + #endif + } + } + } + +#endif diff --git a/Example/Tests/Features/HandicapTests.swift b/Example/Tests/Features/HandicapTests.swift new file mode 100644 index 0000000..7f7788a --- /dev/null +++ b/Example/Tests/Features/HandicapTests.swift @@ -0,0 +1,44 @@ +// +// HandicapTests.swift +// CapableTests +// +// Created by Christoph Wendt on 29.10.18. +// + +#if os(iOS) || os(tvOS) || os(OSX) + + @testable import Capable + import Nimble + import Quick + + class HandicapTests: QuickSpec { + override func spec() { + describe("The Handicap class") { + context("after initialization with features") { + var sut: Handicap? + var testFeatures: [CapableFeature]? + var testName: String? + var testMode: HandicapEnabledMode? + + beforeEach { + testName = "TestHandicap" + testFeatures = [.reduceMotion, .voiceOver] + testMode = .allFeaturesEnabled + sut = Handicap(features: testFeatures!, name: testName!, enabledIf: testMode!) + } + + it("returns a Handicap instance") { + expect(sut!).to(beAnInstanceOf(Handicap.self)) + } + + it("sets all properties correctly") { + expect(sut!.features).to(equal(testFeatures)) + expect(sut!.name).to(equal(testName)) + expect(sut!.enabledIf).to(equal(testMode)) + } + } + } + } + } + +#endif diff --git a/Example/Tests/Features/Mocks/FeatureStatusesMock.swift b/Example/Tests/Features/Mocks/FeatureStatusesMock.swift new file mode 100644 index 0000000..7e7e408 --- /dev/null +++ b/Example/Tests/Features/Mocks/FeatureStatusesMock.swift @@ -0,0 +1,29 @@ +// +// FeatureStatusesMock.swift +// CapableTests +// +// Created by Christoph Wendt on 05.10.18. +// + +#if os(iOS) || os(tvOS) || os(OSX) + + @testable import Capable + + class FeatureStatusesMock: FeatureStatusesProtocol { + var statusMapMock: [String: String] = [:] + var featureEnabled: Bool = false + var didCallStatusMap: Bool = false + var didCallIsFeatureEnabled: Bool = false + + func isFeatureEnabled(feature _: CapableFeature) -> Bool { + didCallIsFeatureEnabled = true + return featureEnabled + } + + var statusMap: [String: String] { + didCallStatusMap = true + return statusMapMock + } + } + +#endif diff --git a/Example/Tests/Features/Mocks/FeatureStatusesProviderMock.swift b/Example/Tests/Features/Mocks/FeatureStatusesProviderMock.swift new file mode 100644 index 0000000..4990ddb --- /dev/null +++ b/Example/Tests/Features/Mocks/FeatureStatusesProviderMock.swift @@ -0,0 +1,209 @@ +// +// FeatureStatusesProviderMock.swift +// CapableTests +// +// Created by Wendt, Christoph on 16.08.18. +// + +#if os(iOS) || os(tvOS) || os(OSX) + + @testable import Capable + + #if os(iOS) + import UIKit + #endif + + class FeatureStatusesProviderMock: FeatureStatusesProvider { + var didCallIsFeatureEnabled = false + + #if os(iOS) + var assistiveTouchEnabled = false + var darkerSystemColorsEnabled = false + var guidedAccessEnabled = false + var hearingDeviceEar: UIAccessibility.HearingDeviceEar = UIAccessibility.HearingDeviceEar(rawValue: 0) + var onOffSwitchLabelsEnabled = false + var shakeToUndoEnabled = false + var speakScreenEnabled = false + var speakSelectionEnabled = false + var textCatagory: UIContentSizeCategory = .unspecified + #endif + + #if os(OSX) + var fullKeyboardAccess = false + var increaseContrast = false + #endif + + #if os(iOS) || os(tvOS) + var boldTextEnabled = false + var closedCaptioningEnabled = false + var grayscaleEnabled = false + var monoAudioEnabled = false + var videoAutoplayEnabled = false + #endif + + #if os(iOS) || os(OSX) + var differentiateWithoutColor = false + #endif + + var invertColorsEnabled = false + var reduceMotionEnabled = false + var reduceTransparencyEnabled = false + var switchControlEnabled = false + var voiceOverEnabled = false + + #if os(iOS) + + override var isAssistiveTouchEnabled: Bool { + return self.assistiveTouchEnabled + } + + override var isDarkerSystemColorsEnabled: Bool { + return self.darkerSystemColorsEnabled + } + + override var isGuidedAccessEnabled: Bool { + return self.guidedAccessEnabled + } + + override var hearingDevicePairedEar: UIAccessibility.HearingDeviceEar { + return self.hearingDeviceEar + } + + override var largerTextCatagory: UIContentSizeCategory { + return self.textCatagory + } + + override var isOnOffSwitchLabelsEnabled: Bool { + return self.onOffSwitchLabelsEnabled + } + + override var isShakeToUndoEnabled: Bool { + return self.shakeToUndoEnabled + } + + override var isSpeakScreenEnabled: Bool { + return self.speakScreenEnabled + } + + override var isSpeakSelectionEnabled: Bool { + return speakSelectionEnabled + } + + #endif + + #if os(OSX) + + override var isFullKeyboardAccessEnabled: Bool { + return self.fullKeyboardAccess + } + + override var isIncreaseContrastEnabled: Bool { + return increaseContrast + } + + #endif + + #if os(iOS) || os(tvOS) + + override var isBoldTextEnabled: Bool { + return self.boldTextEnabled + } + + override var isClosedCaptioningEnabled: Bool { + return self.closedCaptioningEnabled + } + + override var isGrayscaleEnabled: Bool { + return self.grayscaleEnabled + } + + override var isMonoAudioEnabled: Bool { + return self.monoAudioEnabled + } + + override var isVideoAutoplayEnabled: Bool { + return videoAutoplayEnabled + } + + #endif + + #if os(iOS) || os(OSX) + + override var isDifferentiateWithoutColorEnabled: Bool { + return differentiateWithoutColor + } + + #endif + + override var isInvertColorsEnabled: Bool { + return self.invertColorsEnabled + } + + override var isReduceMotionEnabled: Bool { + return self.reduceMotionEnabled + } + + override var isReduceTransparencyEnabled: Bool { + return self.reduceTransparencyEnabled + } + + override var isSwitchControlEnabled: Bool { + return self.switchControlEnabled + } + + override var isVoiceOverEnabled: Bool { + return voiceOverEnabled + } + + func enableAllFeatures() { + #if os(iOS) + + assistiveTouchEnabled = true + darkerSystemColorsEnabled = true + textCatagory = .accessibilityExtraExtraExtraLarge + guidedAccessEnabled = true + hearingDeviceEar = .both + onOffSwitchLabelsEnabled = true + shakeToUndoEnabled = true + speakScreenEnabled = true + speakSelectionEnabled = true + + #endif + + #if os(OSX) + + fullKeyboardAccess = true + increaseContrast = true + + #endif + + #if os(iOS) || os(tvOS) + + boldTextEnabled = true + closedCaptioningEnabled = true + grayscaleEnabled = true + monoAudioEnabled = true + videoAutoplayEnabled = true + + #endif + + #if os(iOS) || os(OSX) + + differentiateWithoutColor = true + + #endif + + invertColorsEnabled = true + reduceMotionEnabled = true + reduceTransparencyEnabled = true + switchControlEnabled = true + voiceOverEnabled = true + } + + override func isFeatureEnabled(feature: CapableFeature) -> Bool { + didCallIsFeatureEnabled = true + return super.isFeatureEnabled(feature: feature) + } + } + +#endif diff --git a/Example/Tests/Features/Mocks/HandicapStatusesMock.swift b/Example/Tests/Features/Mocks/HandicapStatusesMock.swift new file mode 100644 index 0000000..655a81c --- /dev/null +++ b/Example/Tests/Features/Mocks/HandicapStatusesMock.swift @@ -0,0 +1,29 @@ +// +// HandicapStatusesMock.swift +// CapableTests +// +// Created by Christoph Wendt on 05.10.18. +// + +#if os(iOS) || os(tvOS) || os(OSX) + + @testable import Capable + + class HandicapStatusesMock: HandicapStatusesProtocol { + var statusMapMock: [String: String] = [:] + var handicapEnabled: Bool = false + var didCallStatusMap: Bool = false + var didCallIsHandicapEnabled: Bool = false + + func isHandicapEnabled(handicapName _: String) -> Bool { + didCallIsHandicapEnabled = true + return handicapEnabled + } + + var statusMap: [String: String] { + didCallStatusMap = true + return statusMapMock + } + } + +#endif diff --git a/Example/Tests/Features/Mocks/NotificationCenterMock.swift b/Example/Tests/Features/Mocks/NotificationCenterMock.swift new file mode 100644 index 0000000..b23984f --- /dev/null +++ b/Example/Tests/Features/Mocks/NotificationCenterMock.swift @@ -0,0 +1,68 @@ +// +// NotificationCenterMock.swift +// CapableTests +// +// Created by Christoph Wendt on 23.08.18. +// + +#if os(iOS) || os(tvOS) || os(OSX) + + #if os(iOS) || os(tvOS) + import UIKit + #endif + + @testable import Capable + + class NotificationCenterMock: NotificationCenter { + var observedNotifications: [Notification.Name] = [] + var postedNotifications: [Notification.Name: Any?] = [:] + + override func addObserver(_ observer: Any, selector aSelector: Selector, name aName: NSNotification.Name?, object anObject: Any?) { + if let notificationName = aName { + observedNotifications.append(notificationName) + } + super.addObserver(observer, selector: aSelector, name: aName, object: anObject) + } + + override func post(name aName: NSNotification.Name, object anObject: Any?) { + postedNotifications[aName] = anObject + super.post(name: aName, object: anObject) + } + + func hasRegisteredNotification(forFeature feature: CapableFeature) -> Bool { + #if os(iOS) + if feature == .largerText { + return observedNotifications.contains(UIContentSizeCategory.didChangeNotification) + } + #endif + + return observedNotifications.contains(where: { + $0.rawValue.range(of: feature.rawValue, options: .caseInsensitive) != nil + }) + } + + func hasRegisteredNotification(forName name: Notification.Name) -> Bool { + return observedNotifications.contains(name) + } + + func hasPostedNotification(forFeature feature: CapableFeature) -> Bool { + let notificationNames = Array(postedNotifications.keys) + + #if os(iOS) + if feature == .largerText { + return notificationNames.contains(UIContentSizeCategory.didChangeNotification) + } + #endif + + return notificationNames.contains(where: { + $0.rawValue.range(of: feature.rawValue, options: .caseInsensitive) != nil + }) + } + + func hasPostedNotification(forName name: Notification.Name) -> Bool { + let notificationNames = Array(postedNotifications.keys) + return notificationNames.contains(name) + } + } + +#endif diff --git a/Example/Tests/Features/NotificationsTests.swift b/Example/Tests/Features/NotificationsTests.swift new file mode 100644 index 0000000..23bc939 --- /dev/null +++ b/Example/Tests/Features/NotificationsTests.swift @@ -0,0 +1,58 @@ +// +// NotificationsTests.swift +// CapableTests +// +// Created by Christoph Wendt on 12.09.18. +// + +#if os(iOS) || os(tvOS) || os(OSX) + + @testable import Capable + import Nimble + import Quick + + class NotificationsTests: QuickSpec { + override func spec() { + describe("The Notifications class") { + var targetNotificationCenterMock: NotificationCenterMock? + var systemNotificationCenterMock: NotificationCenterMock? + var featureStatusesProviderMock: FeatureStatusesProviderMock? + + beforeEach { + targetNotificationCenterMock = NotificationCenterMock() + systemNotificationCenterMock = NotificationCenterMock() + featureStatusesProviderMock = FeatureStatusesProviderMock() + } + + context("after initialization") { + var sut: Notifications? + + beforeEach { + sut = Notifications(featureStatusesProvider: featureStatusesProviderMock!, targetNotificationCenter: targetNotificationCenterMock!, systemNotificationCenter: systemNotificationCenterMock!) + } + + it("creates a Notifications intsance") { + expect(sut!).to(beAnInstanceOf(Notifications.self)) + } + + it("sets properties correctly") { + expect(sut!.featureStatusesProvider).to(be(featureStatusesProviderMock!)) + expect(sut!.targetNotificationCenter).to(equal(targetNotificationCenterMock!)) + expect(sut!.systemNotificationCenter).to(equal(systemNotificationCenterMock!)) + } + + #if os(iOS) || os(OSX) + + context("when calling postNotification") { + it("throws an error") { + expect(sut!.postNotification(withFeature: .voiceOver, statusString: "enabled")).to(throwAssertion()) + } + } + + #endif + } + } + } + } + +#endif diff --git a/Example/Tests/Fonts/FontMetricsProviderTests.swift b/Example/Tests/Fonts/FontMetricsProviderTests.swift new file mode 100644 index 0000000..2db9947 --- /dev/null +++ b/Example/Tests/Fonts/FontMetricsProviderTests.swift @@ -0,0 +1,48 @@ +// +// FontMetricsProviderTests.swift +// CapableTests +// +// Created by Wendt, Christoph on 03.08.18. +// + +#if os(iOS) || os(tvOS) + + @testable import Capable + import Nimble + import Quick + + class FontMetricsProviderTests: QuickSpec { + override func spec() { + describe("The FontMetricsProvider") { + var sut: FontMetricsProvider? + + if #available(iOS 11.0, tvOS 11.0, watchOS 4.0, *) { + context("when running on device with OS that comes with UIFontMetrics support") { + beforeEach { + let osVersionProviderMock = OsVersionProviderMock() + osVersionProviderMock.osVersionWithUIFontMetrics = true + sut = FontMetricsProvider(osVersionProvider: osVersionProviderMock) + } + + it("provides the default UIFontMetrics") { + expect(sut!.fontMetrics as? UIFontMetrics).to(beIdenticalTo(UIFontMetrics.default)) + } + } + } + + context("when running on device with OS without UIFontMetrics support") { + beforeEach { + let osVersionProviderMock = OsVersionProviderMock() + osVersionProviderMock.osVersionWithUIFontMetrics = false + sut = FontMetricsProvider(osVersionProvider: osVersionProviderMock) + } + + it("provides an instance of FontMetricsSupport") { + expect(sut!.fontMetrics).to(beAnInstanceOf(FontMetricsSupport.self)) + } + } + } + } + } + +#endif diff --git a/Example/Tests/Fonts/FontMetricsSupportTests.swift b/Example/Tests/Fonts/FontMetricsSupportTests.swift new file mode 100644 index 0000000..103a087 --- /dev/null +++ b/Example/Tests/Fonts/FontMetricsSupportTests.swift @@ -0,0 +1,41 @@ +// +// FontMetricsSupportTests.swift +// CapableTests +// +// Created by Wendt, Christoph on 03.08.18. +// + +#if os(iOS) || os(tvOS) + + @testable import Capable + import Nimble + import Quick + + class FontMetricsSupportTests: QuickSpec { + override func spec() { + describe("The FontMetricsSupport") { + var sut: FontMetricsSupport? + + context("after initialization") { + beforeEach { + sut = FontMetricsSupport() + } + + it("conforms to UIFontMetricsProtocol") { + expect(sut!).to(beAKindOf(FontMetricsProtocol.self)) + } + + context("scaling a font") { + it("returns a UIFont instance") { + let testFont = UIFont.boldSystemFont(ofSize: 99) + let scaledFont = sut!.scaledFont(for: testFont) + + expect(scaledFont).to(beAKindOf(UIFont.self)) + } + } + } + } + } + } + +#endif diff --git a/Example/Tests/Fonts/FontMetricsTests.swift b/Example/Tests/Fonts/FontMetricsTests.swift new file mode 100644 index 0000000..7bf30b0 --- /dev/null +++ b/Example/Tests/Fonts/FontMetricsTests.swift @@ -0,0 +1,50 @@ +// +// FontMetricsTests.swift +// CapableTests +// +// Created by Wendt, Christoph on 03.08.18. +// + +#if os(iOS) || os(tvOS) + + @testable import Capable + import Nimble + import Quick + + class FontMetricsTests: QuickSpec { + override func spec() { + describe("The FontMetrics") { + var testFont: UIFont? + var sut: FontMetrics? + var fontMetricsMock: FontMetricsMock? + + beforeEach { + fontMetricsMock = FontMetricsMock() + testFont = UIFont.boldSystemFont(ofSize: 99) + + let fontMetricsProviderMock = FontMetricsProviderMock(fontMetrics: fontMetricsMock!) + sut = FontMetrics(fontMetricsProvider: fontMetricsProviderMock) + } + + context("after initialization") { + it("has the fontMetrics instance from the provider") { + expect(sut!.fontMetrics as? FontMetricsMock).to(beIdenticalTo(fontMetricsMock!)) + } + + context("calling scaledFont:for") { + it("calls scaledFont:for on its fontMetrics object") { + _ = sut!.scaledFont(for: testFont!) + expect(fontMetricsMock!.didCallScaledFont).to(beTrue()) + } + + it("calls scaledFont:for with the passed font") { + _ = sut!.scaledFont(for: testFont!) + expect(fontMetricsMock!.scaledFont!).to(equal(testFont!)) + } + } + } + } + } + } + +#endif diff --git a/Example/Tests/Fonts/Mocks/FontMetricsMock.swift b/Example/Tests/Fonts/Mocks/FontMetricsMock.swift new file mode 100644 index 0000000..603cf35 --- /dev/null +++ b/Example/Tests/Fonts/Mocks/FontMetricsMock.swift @@ -0,0 +1,25 @@ +// +// FontMetricsMock.swift +// CapableTests +// +// Created by Wendt, Christoph on 03.08.18. +// + +#if os(iOS) || os(tvOS) + + import UIKit + + @testable import Capable + + class FontMetricsMock: FontMetricsProtocol { + var didCallScaledFont: Bool = false + var scaledFont: UIFont? + + func scaledFont(for font: UIFont) -> UIFont { + didCallScaledFont = true + scaledFont = font + return font + } + } + +#endif diff --git a/Example/Tests/Fonts/Mocks/FontMetricsProviderMock.swift b/Example/Tests/Fonts/Mocks/FontMetricsProviderMock.swift new file mode 100644 index 0000000..b96cf8f --- /dev/null +++ b/Example/Tests/Fonts/Mocks/FontMetricsProviderMock.swift @@ -0,0 +1,20 @@ +// +// FontMetricsProviderMock.swift +// CapableTests +// +// Created by Wendt, Christoph on 03.08.18. +// + +#if os(iOS) || os(tvOS) + + @testable import Capable + + class FontMetricsProviderMock: FontMetricsProviderProtocol { + let fontMetrics: FontMetricsProtocol + + init(fontMetrics: FontMetricsProtocol) { + self.fontMetrics = fontMetrics + } + } + +#endif diff --git a/Example/Tests/Fonts/Mocks/OsVersionProviderMock.swift b/Example/Tests/Fonts/Mocks/OsVersionProviderMock.swift new file mode 100644 index 0000000..f8d72da --- /dev/null +++ b/Example/Tests/Fonts/Mocks/OsVersionProviderMock.swift @@ -0,0 +1,20 @@ +// +// OsVersionProviderMock.swift +// Capable +// +// Created by Christoph Wendt on 30.04.18. +// + +#if os(iOS) || os(tvOS) + + @testable import Capable + + class OsVersionProviderMock: OsVersionProviderProtocol { + var osVersionWithUIFontMetrics = false + + func isOsVersionWithUIFontMetrics() -> Bool { + return osVersionWithUIFontMetrics + } + } + +#endif diff --git a/Tests/Info.plist b/Example/Tests/Tests-iOS/Info.plist similarity index 93% rename from Tests/Info.plist rename to Example/Tests/Tests-iOS/Info.plist index 6c40a6c..64d65ca 100644 --- a/Tests/Info.plist +++ b/Example/Tests/Tests-iOS/Info.plist @@ -13,7 +13,7 @@ CFBundleName $(PRODUCT_NAME) CFBundlePackageType - BNDL + $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString 1.0 CFBundleVersion diff --git a/Example/Tests/Tests-macOS/Info.plist b/Example/Tests/Tests-macOS/Info.plist new file mode 100644 index 0000000..64d65ca --- /dev/null +++ b/Example/Tests/Tests-macOS/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/Example/Tests/Tests-tvOS/Info.plist b/Example/Tests/Tests-tvOS/Info.plist new file mode 100644 index 0000000..64d65ca --- /dev/null +++ b/Example/Tests/Tests-tvOS/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/Images/features_example_app.png b/Images/features_example_app.png new file mode 100644 index 0000000..e6c0b96 Binary files /dev/null and b/Images/features_example_app.png differ diff --git a/Package.resolved b/Package.resolved index cf3647a..0f1b75d 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,13 +1,76 @@ { "object": { "pins": [ + { + "package": "Commandant", + "repositoryURL": "https://github.com/Carthage/Commandant.git", + "state": { + "branch": null, + "revision": "2cd0210f897fe46c6ce42f52ccfa72b3bbb621a0", + "version": "0.16.0" + } + }, + { + "package": "Curry", + "repositoryURL": "https://github.com/thoughtbot/Curry.git", + "state": { + "branch": null, + "revision": "4331dd50bc1db007db664a23f32e6f3df93d4e1a", + "version": "4.0.2" + } + }, + { + "package": "CwlCatchException", + "repositoryURL": "https://github.com/mattgallagher/CwlCatchException.git", + "state": { + "branch": null, + "revision": "7cd2f8cacc4d22f21bc0b2309c3b18acf7957b66", + "version": "1.2.0" + } + }, + { + "package": "CwlPreconditionTesting", + "repositoryURL": "https://github.com/mattgallagher/CwlPreconditionTesting.git", + "state": { + "branch": null, + "revision": "c228db5d2ad1b01ebc84435e823e6cca4e3db98b", + "version": "1.2.0" + } + }, + { + "package": "Komondor", + "repositoryURL": "https://github.com/orta/Komondor", + "state": { + "branch": null, + "revision": "3cd6d76887816ead5931ddbfb249c2935f518e17", + "version": "1.0.4" + } + }, + { + "package": "MarkdownGenerator", + "repositoryURL": "https://github.com/eneko/MarkdownGenerator.git", + "state": { + "branch": null, + "revision": "1fc31be6b66245187c3f87f35d86b6aeac6dfe7f", + "version": "0.5.0" + } + }, { "package": "Nimble", "repositoryURL": "https://github.com/Quick/Nimble.git", "state": { "branch": null, - "revision": "9c1379fdcd58c4f2278aea5e029394ba9a2b8f07", - "version": "7.1.3" + "revision": "6abeb3f5c03beba2b9e4dbe20886e773b5b629b6", + "version": "8.0.4" + } + }, + { + "package": "PackageConfig", + "repositoryURL": "https://github.com/shibapm/PackageConfig", + "state": { + "branch": null, + "revision": "fd0829aac9851434b3d2db0890e27bc489fc973a", + "version": "0.12.2" } }, { @@ -15,8 +78,98 @@ "repositoryURL": "https://github.com/Quick/Quick.git", "state": { "branch": null, - "revision": "b060679e70d13c3c7dcd124201b5b1b34ce6f340", - "version": "1.3.1" + "revision": "33682c2f6230c60614861dfc61df267e11a1602f", + "version": "2.2.0" + } + }, + { + "package": "Rainbow", + "repositoryURL": "https://github.com/onevcat/Rainbow", + "state": { + "branch": null, + "revision": "9c52c1952e9b2305d4507cf473392ac2d7c9b155", + "version": "3.1.5" + } + }, + { + "package": "Result", + "repositoryURL": "https://github.com/antitypical/Result.git", + "state": { + "branch": null, + "revision": "2ca499ba456795616fbc471561ff1d963e6ae160", + "version": "4.1.0" + } + }, + { + "package": "ShellOut", + "repositoryURL": "https://github.com/JohnSundell/ShellOut.git", + "state": { + "branch": null, + "revision": "d3d54ce662dfee7fef619330b71d251b8d4869f9", + "version": "2.2.0" + } + }, + { + "package": "SourceDocs", + "repositoryURL": "https://github.com/eneko/SourceDocs.git", + "state": { + "branch": null, + "revision": "951606c945f4a9d3b0b8c2a37fa28ac2c99d25bb", + "version": "0.5.1" + } + }, + { + "package": "SourceKitten", + "repositoryURL": "https://github.com/jpsim/SourceKitten.git", + "state": { + "branch": null, + "revision": "cc1f16acc70630d27498e81078789f5fa55d7463", + "version": "0.26.0" + } + }, + { + "package": "SwiftFormat", + "repositoryURL": "https://github.com/nicklockwood/SwiftFormat", + "state": { + "branch": null, + "revision": "1f0d26082bee42490f286bee98133ae710be0032", + "version": "0.40.13" + } + }, + { + "package": "SwiftLint", + "repositoryURL": "https://github.com/Realm/SwiftLint", + "state": { + "branch": null, + "revision": "8dc8421a49f2b74f79da3ef514a26249027309b9", + "version": "0.35.0" + } + }, + { + "package": "SwiftyTextTable", + "repositoryURL": "https://github.com/scottrhoyt/SwiftyTextTable.git", + "state": { + "branch": null, + "revision": "c6df6cf533d120716bff38f8ff9885e1ce2a4ac3", + "version": "0.9.0" + } + }, + { + "package": "SWXMLHash", + "repositoryURL": "https://github.com/drmohundro/SWXMLHash.git", + "state": { + "branch": null, + "revision": "a4931e5c3bafbedeb1601d3bb76bbe835c6d475a", + "version": "5.0.1" + } + }, + { + "package": "Yams", + "repositoryURL": "https://github.com/jpsim/Yams.git", + "state": { + "branch": null, + "revision": "c947a306d2e80ecb2c0859047b35c73b8e1ca27f", + "version": "2.0.0" } } ] diff --git a/Package.swift b/Package.swift index f87ff13..6cc7011 100644 --- a/Package.swift +++ b/Package.swift @@ -1,26 +1,52 @@ -// swift-tools-version:4.0 +// swift-tools-version:5.0 import PackageDescription let package = Package( name: "Capable", + platforms: [ + .macOS(.v10_12), .iOS(.v10), .tvOS(.v10), .watchOS(.v4), + ], products: [ .library( name: "Capable", - targets: ["Capable"]) + targets: ["Capable"] + ), ], dependencies: [ .package(url: "https://github.com/Quick/Quick.git", from: "2.1.0"), - .package(url: "https://github.com/Quick/Nimble.git", from: "8.0.2") + .package(url: "https://github.com/Quick/Nimble.git", from: "8.0.4"), + .package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.40.13"), + .package(url: "https://github.com/Realm/SwiftLint", from: "0.35.0"), + .package(url: "https://github.com/orta/Komondor", from: "1.0.4"), + .package(url: "https://github.com/eneko/SourceDocs.git", from: "0.5.1"), ], targets: [ .target( name: "Capable", dependencies: [], - path: "Source"), + path: "Source" + ), .testTarget( name: "CapableTests", dependencies: ["Capable", "Quick", "Nimble"], - path: "Tests"), + path: "Example/Tests" + ), ], - swiftLanguageVersions: [4] + swiftLanguageVersions: [ + .v5, + ] ) + +#if canImport(PackageConfig) + import PackageConfig + + let config = PackageConfiguration([ + "komondor": [ + "pre-commit": [ + // "swift run swiftlint", + "swift run swiftformat .", + "swift run sourcedocs generate --spm-module Capable", + ], + ], + ]).write() +#endif diff --git a/README.md b/README.md index 734c8d0..f3c18b1 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,9 @@ [![Build Status](https://app.bitrise.io/app/7596a076a75ab2ab/status.svg?token=3kpsJB-PR0sBLRF8NYrwhg&branch=develop)](https://app.bitrise.io/app/7596a076a75ab2ab) ![Swift](https://img.shields.io/badge/swift-5.0-red.svg) ![Platforms](https://img.shields.io/cocoapods/p/Capable.svg) -[![Carthage compatible](https://img.shields.io/badge/carthage-compatible-4BC51D.svg)](https://github.com/Carthage/Carthage) [![Cocoapods compatible](https://img.shields.io/cocoapods/v/Capable.svg)](https://cocoapods.org/pods/Capable) -![SPM](https://img.shields.io/badge/swift%20package%20manager-macOS-blue.svg) -![Documentation](Documentation/badge.svg) +![SPM](https://img.shields.io/badge/SPM-compatible-ff59b4) +[![Carthage compatible](https://img.shields.io/badge/carthage-compatible-4BC51D.svg)](https://github.com/Carthage/Carthage) [![codecov](https://codecov.io/gh/chrs1885/Capable/branch/develop/graph/badge.svg)](https://codecov.io/gh/chrs1885/Capable) [![Twitter](https://img.shields.io/badge/twitter-%40chr__wendt-58a1f2.svg)](https://twitter.com/chr_wendt) @@ -49,7 +48,7 @@ Each Capable feature is backed by the built-in logging system, which will keep y ## Documentation -Capable offers a whole lot of features along with a bunch of configurations. To find more about how to use them inside the [documentation](https://htmlpreview.github.io/?https://github.com/chrs1885/Capable/blob/1.1.0/Documentation/index.html) section. +Capable offers a whole lot of features along with a bunch of configurations. To find more about how to use them inside the [documentation](Documentation/Reference/README.md) section. ## Installation @@ -86,7 +85,7 @@ github "chrs1885/Capable" ```ruby dependencies: [ - .package(url: "https://github.com/chrs1885/Capable.git", from: "1.1.0") + .package(url: "https://github.com/chrs1885/Capable.git", from: "1.1.1") ] ``` @@ -291,7 +290,7 @@ let textColor = UIColor.getTextColor( )! ``` -You can find an overview of all image areas available in the [documentation](https://htmlpreview.github.io/?https://raw.githubusercontent.com/chrs1885/Capable/1.1.0/Documentation/Enums/ImageArea.html). +You can find an overview of all image areas available in the [documentation](Documentation/Reference/enums/ImageArea.md). #### Calculating contrast ratios & WCAG conformance levels diff --git a/Scripts/release.sh b/Scripts/release.sh deleted file mode 100755 index 250f0af..0000000 --- a/Scripts/release.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -# Run this script from the root directory just before releasing a new Capable version. - -#============================= Documentation ============================= -echo "Updating framework documentation" - -jazzy - -#========================== Example dependencies ========================= -echo "Updating Capable dependency in example project" - -cd Example -pod install -cd .. \ No newline at end of file diff --git a/Scripts/setup.sh b/Scripts/setup.sh index 74be543..f7b57e3 100755 --- a/Scripts/setup.sh +++ b/Scripts/setup.sh @@ -1,13 +1,9 @@ #!/bin/sh +# Run this script from the root directory just before starting to contribute code. -# Run this script before contributing code. +#================================= Tooling ================================= +echo "Installing tools (SwiftLint, SwiftFormat, and SourceDocs" +swift build -#================================= Jazzy ================================= -echo "Installing Jazzy for generating code documentation (https://github.com/realm/jazzy)" - -gem install jazzy - -#=============================== SwiftLint =============================== -echo "Installing SwiftLint to enforce the Capable coding style & conventions" - -brew install swiftlint +echo "Installing pre-commit hook" +swift run komondor install diff --git a/Source/Colors/Extensions/CIImage+initWithImage.swift b/Source/Colors/Extensions/CIImage+initWithImage.swift index 21120d3..f63eb2e 100644 --- a/Source/Colors/Extensions/CIImage+initWithImage.swift +++ b/Source/Colors/Extensions/CIImage+initWithImage.swift @@ -7,16 +7,16 @@ #if os(OSX) -import AppKit + import AppKit -extension CIImage { - convenience init?(image: NSImage) { - guard let cgImage = image.cgImage(forProposedRect: nil, context: nil, hints: nil) else { - return nil - } + extension CIImage { + convenience init?(image: NSImage) { + guard let cgImage = image.cgImage(forProposedRect: nil, context: nil, hints: nil) else { + return nil + } - self.init(cgImage: cgImage) + self.init(cgImage: cgImage) + } } -} #endif diff --git a/Source/Colors/Extensions/Color+wcag.swift b/Source/Colors/Extensions/Color+wcag.swift index 711dd79..c506b92 100644 --- a/Source/Colors/Extensions/Color+wcag.swift +++ b/Source/Colors/Extensions/Color+wcag.swift @@ -7,29 +7,28 @@ #if os(iOS) || os(tvOS) || os(watchOS) -import UIKit + import UIKit -/// Typealias used for colors. It maps to UIColor. -public typealias Color = UIColor + /// Typealias used for colors. It maps to UIColor. + public typealias Color = UIColor -/// Typealias used for fonts. It maps to UIFont. -public typealias Font = UIFont + /// Typealias used for fonts. It maps to UIFont. + public typealias Font = UIFont #elseif os(OSX) -import AppKit + import AppKit -/// Typealias used for colors. It maps to NSColor. -public typealias Color = NSColor + /// Typealias used for colors. It maps to NSColor. + public typealias Color = NSColor -/// Typealias used for fonts. It maps to NSFont. -public typealias Font = NSFont + /// Typealias used for fonts. It maps to NSFont. + public typealias Font = NSFont #endif /// Extension that adds functionality for calculating WCAG compliant high contrast colors. extension Color { - /** Calculates the color ratio for a text color on a background color. @@ -102,46 +101,46 @@ extension Color { #if os(iOS) || os(tvOS) || os(OSX) - /** - Returns the text color with the highest contrast (black or white) for a specific area of given background image. + /** + Returns the text color with the highest contrast (black or white) for a specific area of given background image. - - Parameters: - - backgroundImage: The background image. - - imageArea: The area of the image that is used as the text background. Defaults to .full. + - Parameters: + - backgroundImage: The background image. + - imageArea: The area of the image that is used as the text background. Defaults to .full. - - Returns: A color that has the highest contrast with the given background image. + - Returns: A color that has the highest contrast with the given background image. - - Note: For the background image, the alpha component is ignored. + - Note: For the background image, the alpha component is ignored. - - Warning: This function will also return `nil` if the image is corrupted. - */ - public class func getTextColor(onBackgroundImage image: Image, imageArea: ImageArea = .full) -> Color? { - guard let averageImageColor = image.averageColor(imageArea: imageArea) else { return nil } + - Warning: This function will also return `nil` if the image is corrupted. + */ + public class func getTextColor(onBackgroundImage image: Image, imageArea: ImageArea = .full) -> Color? { + guard let averageImageColor = image.averageColor(imageArea: imageArea) else { return nil } - return Color.getTextColor(onBackgroundColor: averageImageColor) - } + return Color.getTextColor(onBackgroundColor: averageImageColor) + } - /** - Calculates the contrast ratio of a given list of text colors and a specific area of given background image. The first color that conforms to the conformance level defined gets returned. The default conformance level is .AA. + /** + Calculates the contrast ratio of a given list of text colors and a specific area of given background image. The first color that conforms to the conformance level defined gets returned. The default conformance level is .AA. - - Parameters: - - colors: A list of possible text colors. - - font: The font used for the text. - - backgroundImage: The background image that the text should be displayed on. - - imageArea: The area of the image that is used as the text background. Defaults to .full. - - conformanceLevel: The conformance level that needs to be passed when calculating the contrast ratio. The default conformance level is .AA. + - Parameters: + - colors: A list of possible text colors. + - font: The font used for the text. + - backgroundImage: The background image that the text should be displayed on. + - imageArea: The area of the image that is used as the text background. Defaults to .full. + - conformanceLevel: The conformance level that needs to be passed when calculating the contrast ratio. The default conformance level is .AA. - - Returns: The first color that conforms to the conformance level defined or `nil` if non of the colors provided passed. + - Returns: The first color that conforms to the conformance level defined or `nil` if non of the colors provided passed. - - Note: Semi-transparent text colors will be blended with the background color. However, for the background image, the alpha component is ignored. + - Note: Semi-transparent text colors will be blended with the background color. However, for the background image, the alpha component is ignored. - - Warning: This function will also return `nil` if any input color is not convertable to the sRGB color space. - */ - public class func getTextColor(fromColors colors: [Color], withFont font: Font, onBackgroundImage image: Image, imageArea: ImageArea = .full, conformanceLevel: ConformanceLevel = .AA) -> Color? { - guard let averageImageColor = image.averageColor(imageArea: imageArea) else { return nil } + - Warning: This function will also return `nil` if any input color is not convertable to the sRGB color space. + */ + public class func getTextColor(fromColors colors: [Color], withFont font: Font, onBackgroundImage image: Image, imageArea: ImageArea = .full, conformanceLevel: ConformanceLevel = .AA) -> Color? { + guard let averageImageColor = image.averageColor(imageArea: imageArea) else { return nil } - return Color.getTextColor(fromColors: colors, withFont: font, onBackgroundColor: averageImageColor, conformanceLevel: conformanceLevel) - } + return Color.getTextColor(fromColors: colors, withFont: font, onBackgroundColor: averageImageColor, conformanceLevel: conformanceLevel) + } #endif diff --git a/Source/Colors/Extensions/Image+averageColor.swift b/Source/Colors/Extensions/Image+averageColor.swift index 3e17dde..27c881a 100644 --- a/Source/Colors/Extensions/Image+averageColor.swift +++ b/Source/Colors/Extensions/Image+averageColor.swift @@ -9,62 +9,62 @@ import CoreGraphics #if os(iOS) || os(tvOS) -import UIKit + import UIKit -/// Typealias used for images. It maps to UIImage. -public typealias Image = UIImage + /// Typealias used for images. It maps to UIImage. + public typealias Image = UIImage #elseif os(OSX) -import AppKit + import AppKit -/// Typealias used for image. It maps to NSImage. -public typealias Image = NSImage + /// Typealias used for image. It maps to NSImage. + public typealias Image = NSImage #endif #if os(iOS) || os(tvOS) || os(OSX) -extension Image { - func averageColor(imageArea: ImageArea = .full) -> Color? { - let imageAreaRect = imageArea.rect(forImage: self) - var transform = CGAffineTransform(scaleX: 1, y: -1) - transform = transform.translatedBy(x: 0, y: -self.size.height) - let transformedRect = imageAreaRect.applying(transform) + extension Image { + func averageColor(imageArea: ImageArea = .full) -> Color? { + let imageAreaRect = imageArea.rect(forImage: self) + var transform = CGAffineTransform(scaleX: 1, y: -1) + transform = transform.translatedBy(x: 0, y: -size.height) + let transformedRect = imageAreaRect.applying(transform) - guard - let inputImage = CIImage(image: self), - let averageColor = inputImage.averageColor(in: transformedRect) else { + guard + let inputImage = CIImage(image: self), + let averageColor = inputImage.averageColor(in: transformedRect) else { return nil - } + } - return averageColor + return averageColor + } } -} -private extension CIImage { - func averageColor(in rect: CGRect) -> Color? { - let extentVector = CIVector(x: rect.origin.x, y: rect.origin.y, z: rect.size.width, w: rect.size.height) + private extension CIImage { + func averageColor(in rect: CGRect) -> Color? { + let extentVector = CIVector(x: rect.origin.x, y: rect.origin.y, z: rect.size.width, w: rect.size.height) - guard - let filter = CIFilter(name: "CIAreaAverage", parameters: [kCIInputImageKey: self, kCIInputExtentKey: extentVector]), - let imageSection = filter.outputImage else { + guard + let filter = CIFilter(name: "CIAreaAverage", parameters: [kCIInputImageKey: self, kCIInputExtentKey: extentVector]), + let imageSection = filter.outputImage else { Logger.warning("Unable to create image section.") return nil + } + + var bitmap = [UInt8](repeating: 0, count: 4) + let context = CIContext(options: [.workingColorSpace: kCFNull as Any]) + context.render(imageSection, toBitmap: &bitmap, rowBytes: 4, bounds: CGRect(x: 0, y: 0, width: 1, height: 1), format: .RGBA8, colorSpace: nil) + let averageColor = Color( + red: CGFloat(bitmap[0]) / 255, + green: CGFloat(bitmap[1]) / 255, + blue: CGFloat(bitmap[2]) / 255, + alpha: CGFloat(bitmap[3]) / 255 + ) + + return averageColor } - - var bitmap = [UInt8](repeating: 0, count: 4) - let context = CIContext(options: [.workingColorSpace: kCFNull as Any]) - context.render(imageSection, toBitmap: &bitmap, rowBytes: 4, bounds: CGRect(x: 0, y: 0, width: 1, height: 1), format: .RGBA8, colorSpace: nil) - let averageColor = Color( - red: CGFloat(bitmap[0]) / 255, - green: CGFloat(bitmap[1]) / 255, - blue: CGFloat(bitmap[2]) / 255, - alpha: CGFloat(bitmap[3]) / 255 - ) - - return averageColor } -} #endif diff --git a/Source/Colors/Extensions/NSColor+rgbaColor.swift b/Source/Colors/Extensions/NSColor+rgbaColor.swift index b3eb5c9..0edd032 100644 --- a/Source/Colors/Extensions/NSColor+rgbaColor.swift +++ b/Source/Colors/Extensions/NSColor+rgbaColor.swift @@ -7,20 +7,20 @@ #if os(OSX) -import AppKit + import AppKit -extension NSColor { - var rgbaColor: RGBAColor? { - guard let rgbColor = self.usingColorSpace(.sRGB) else { - Logger.warning("Input color not compatible with sRGB color space.") - return nil - } + extension NSColor { + var rgbaColor: RGBAColor? { + guard let rgbColor = self.usingColorSpace(.sRGB) else { + Logger.warning("Input color not compatible with sRGB color space.") + return nil + } - var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0, alpha: CGFloat = 0 - rgbColor.getRed(&red, green: &green, blue: &blue, alpha: &alpha) + var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0, alpha: CGFloat = 0 + rgbColor.getRed(&red, green: &green, blue: &blue, alpha: &alpha) - return RGBAColor(red: (red * 255.0), green: (green * 255.0), blue: (blue * 255.0), alpha: alpha) + return RGBAColor(red: red * 255.0, green: green * 255.0, blue: blue * 255.0, alpha: alpha) + } } -} #endif diff --git a/Source/Colors/Extensions/NSFont+fontProps.swift b/Source/Colors/Extensions/NSFont+fontProps.swift index 7f2b532..22bfb02 100644 --- a/Source/Colors/Extensions/NSFont+fontProps.swift +++ b/Source/Colors/Extensions/NSFont+fontProps.swift @@ -7,16 +7,16 @@ #if os(OSX) -import AppKit + import AppKit -extension NSFont { - var fontProps: FontProps { - return FontProps(fontSize: self.pointSize, isBoldFont: self.isBold) - } + extension NSFont { + var fontProps: FontProps { + return FontProps(fontSize: pointSize, isBoldFont: isBold) + } - var isBold: Bool { - return (self.fontDescriptor.symbolicTraits.rawValue & NSFontSymbolicTraits(NSFontBoldTrait)) != 0 + var isBold: Bool { + return (fontDescriptor.symbolicTraits.rawValue & NSFontSymbolicTraits(NSFontBoldTrait)) != 0 + } } -} #endif diff --git a/Source/Colors/Extensions/UIColor+rgbaColor.swift b/Source/Colors/Extensions/UIColor+rgbaColor.swift index 0708e0d..cea96dc 100644 --- a/Source/Colors/Extensions/UIColor+rgbaColor.swift +++ b/Source/Colors/Extensions/UIColor+rgbaColor.swift @@ -7,30 +7,30 @@ #if os(iOS) || os(tvOS) || os(watchOS) -import UIKit + import UIKit -extension UIColor { - var rgbaColor: RGBAColor? { - func normalize(_ component: CGFloat) -> CGFloat { - let nomralizedValue = component * 255.0 + extension UIColor { + var rgbaColor: RGBAColor? { + func normalize(_ component: CGFloat) -> CGFloat { + let nomralizedValue = component * 255.0 - if nomralizedValue > 255.0 { return 255.0 } - if nomralizedValue < 0.0 { return 0.0 } - return nomralizedValue - } + if nomralizedValue > 255.0 { return 255.0 } + if nomralizedValue < 0.0 { return 0.0 } + return nomralizedValue + } - var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0, white: CGFloat = 0, alpha: CGFloat = 0 + var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0, white: CGFloat = 0, alpha: CGFloat = 0 - if self.getRed(&red, green: &green, blue: &blue, alpha: &alpha) { - return RGBAColor(red: normalize(red), green: normalize(green), blue: normalize(blue), alpha: alpha) - } else if self.getWhite(&white, alpha: &alpha) { - let white = normalize(white) - return RGBAColor(red: white, green: white, blue: white, alpha: alpha) - } else { - Logger.warning("Input color not compatible with sRGB color space.") - return nil + if getRed(&red, green: &green, blue: &blue, alpha: &alpha) { + return RGBAColor(red: normalize(red), green: normalize(green), blue: normalize(blue), alpha: alpha) + } else if getWhite(&white, alpha: &alpha) { + let white = normalize(white) + return RGBAColor(red: white, green: white, blue: white, alpha: alpha) + } else { + Logger.warning("Input color not compatible with sRGB color space.") + return nil + } } } -} #endif diff --git a/Source/Colors/Extensions/UIFont+fontProps.swift b/Source/Colors/Extensions/UIFont+fontProps.swift index 8efa1fc..b5d0618 100644 --- a/Source/Colors/Extensions/UIFont+fontProps.swift +++ b/Source/Colors/Extensions/UIFont+fontProps.swift @@ -7,16 +7,16 @@ #if os(iOS) || os(tvOS) || os(watchOS) -import UIKit + import UIKit -extension UIFont { - var fontProps: FontProps { - return FontProps(fontSize: self.pointSize, isBoldFont: self.isBold) - } + extension UIFont { + var fontProps: FontProps { + return FontProps(fontSize: pointSize, isBoldFont: isBold) + } - var isBold: Bool { - return (self.fontDescriptor.symbolicTraits.rawValue & UIFontDescriptor.SymbolicTraits.traitBold.rawValue) != 0 + var isBold: Bool { + return (fontDescriptor.symbolicTraits.rawValue & UIFontDescriptor.SymbolicTraits.traitBold.rawValue) != 0 + } } -} #endif diff --git a/Source/Colors/Models/ConformanceLevel.swift b/Source/Colors/Models/ConformanceLevel.swift index fc8a65c..e9399cc 100644 --- a/Source/Colors/Models/ConformanceLevel.swift +++ b/Source/Colors/Models/ConformanceLevel.swift @@ -11,7 +11,6 @@ infix operator >=: ComparisonPrecedence /// An enum specifying all WCAG conformance levels. public enum ConformanceLevel: Int { - /// The minimum level of conformance. case A = 1 diff --git a/Source/Colors/Models/FontProps.swift b/Source/Colors/Models/FontProps.swift index 6465908..292734f 100644 --- a/Source/Colors/Models/FontProps.swift +++ b/Source/Colors/Models/FontProps.swift @@ -12,6 +12,6 @@ struct FontProps: Equatable { var isBoldFont: Bool var isLargeText: Bool { - return self.fontSize >= 18.0 || (self.fontSize >= 14.0 && self.isBoldFont) + return fontSize >= 18.0 || (fontSize >= 14.0 && isBoldFont) } } diff --git a/Source/Colors/Models/ImageArea.swift b/Source/Colors/Models/ImageArea.swift index d6ea7a6..9a54036 100644 --- a/Source/Colors/Models/ImageArea.swift +++ b/Source/Colors/Models/ImageArea.swift @@ -7,104 +7,103 @@ #if os(iOS) || os(tvOS) || os(OSX) -import CoreGraphics - -public enum ImageArea { - - /// The full image size. - case full - - /// The last vertical third. - case bottom - - /// The second horizontal third of the last vertical third. - case bottomCenter - - /// The first horizontal third of the last vertical third. - case bottomLeft - - /// The last horizontal third of the last vertical third. - case bottomRight - - /// The second horizontal third of the second vertical third. - case center - - /// The first horizontal third of the second vertical third. - case centerLeft - - /// The last horizontal third of the second vertical third. - case centerRight - - /// A custom area of the image defined by a CGRect. - case custom(rect: CGRect) - - /// The second vertical third. - case horizontalCenter - - /// The first horizontal third. - case left - - /// The last horizontal third. - case right - - /// The first vertical third. - case top - - /// The second horizontal third of the first vertical third. - case topCenter - - /// The first horizontal third of the first vertical third. - case topLeft - - /// The last horizontal third of the first vertical third. - case topRight - - /// The second horizontal third. - case verticalCenter - - func rect(forImage image: Image) -> CGRect { - let imageWidth = image.size.width - let imageHeight = image.size.height - let widthThird = imageWidth / 3.0 - let heightThird = imageHeight / 3.0 - - switch self { - case .bottom: - return CGRect(x: 0, y: heightThird * 2, width: imageWidth, height: heightThird) - case .bottomCenter: - return CGRect(x: widthThird, y: heightThird * 2, width: widthThird, height: heightThird) - case .bottomLeft: - return CGRect(x: 0, y: heightThird * 2, width: widthThird, height: heightThird) - case .bottomRight: - return CGRect(x: widthThird * 2, y: heightThird * 2, width: widthThird, height: heightThird) - case .center: - return CGRect(x: widthThird, y: heightThird, width: widthThird, height: heightThird) - case .centerLeft: - return CGRect(x: 0, y: heightThird, width: widthThird, height: heightThird) - case .centerRight: - return CGRect(x: widthThird * 2, y: heightThird, width: widthThird, height: heightThird) - case .custom(let rect): - return rect - case .full: - return CGRect(x: 0, y: 0, width: imageWidth, height: imageHeight) - case .horizontalCenter: - return CGRect(x: 0, y: heightThird, width: imageWidth, height: heightThird) - case .left: - return CGRect(x: 0, y: 0, width: widthThird, height: imageHeight) - case .right: - return CGRect(x: widthThird * 2, y: 0, width: widthThird, height: imageHeight) - case .top: - return CGRect(x: 0, y: 0, width: imageWidth, height: heightThird) - case .topCenter: - return CGRect(x: widthThird, y: 0, width: widthThird, height: heightThird) - case .topLeft: - return CGRect(x: 0, y: 0, width: widthThird, height: heightThird) - case .topRight: - return CGRect(x: widthThird * 2, y: 0, width: widthThird, height: heightThird) - case .verticalCenter: - return CGRect(x: widthThird, y: 0, width: widthThird, height: imageHeight) + import CoreGraphics + + public enum ImageArea { + /// The full image size. + case full + + /// The last vertical third. + case bottom + + /// The second horizontal third of the last vertical third. + case bottomCenter + + /// The first horizontal third of the last vertical third. + case bottomLeft + + /// The last horizontal third of the last vertical third. + case bottomRight + + /// The second horizontal third of the second vertical third. + case center + + /// The first horizontal third of the second vertical third. + case centerLeft + + /// The last horizontal third of the second vertical third. + case centerRight + + /// A custom area of the image defined by a CGRect. + case custom(rect: CGRect) + + /// The second vertical third. + case horizontalCenter + + /// The first horizontal third. + case left + + /// The last horizontal third. + case right + + /// The first vertical third. + case top + + /// The second horizontal third of the first vertical third. + case topCenter + + /// The first horizontal third of the first vertical third. + case topLeft + + /// The last horizontal third of the first vertical third. + case topRight + + /// The second horizontal third. + case verticalCenter + + func rect(forImage image: Image) -> CGRect { + let imageWidth = image.size.width + let imageHeight = image.size.height + let widthThird = imageWidth / 3.0 + let heightThird = imageHeight / 3.0 + + switch self { + case .bottom: + return CGRect(x: 0, y: heightThird * 2, width: imageWidth, height: heightThird) + case .bottomCenter: + return CGRect(x: widthThird, y: heightThird * 2, width: widthThird, height: heightThird) + case .bottomLeft: + return CGRect(x: 0, y: heightThird * 2, width: widthThird, height: heightThird) + case .bottomRight: + return CGRect(x: widthThird * 2, y: heightThird * 2, width: widthThird, height: heightThird) + case .center: + return CGRect(x: widthThird, y: heightThird, width: widthThird, height: heightThird) + case .centerLeft: + return CGRect(x: 0, y: heightThird, width: widthThird, height: heightThird) + case .centerRight: + return CGRect(x: widthThird * 2, y: heightThird, width: widthThird, height: heightThird) + case let .custom(rect): + return rect + case .full: + return CGRect(x: 0, y: 0, width: imageWidth, height: imageHeight) + case .horizontalCenter: + return CGRect(x: 0, y: heightThird, width: imageWidth, height: heightThird) + case .left: + return CGRect(x: 0, y: 0, width: widthThird, height: imageHeight) + case .right: + return CGRect(x: widthThird * 2, y: 0, width: widthThird, height: imageHeight) + case .top: + return CGRect(x: 0, y: 0, width: imageWidth, height: heightThird) + case .topCenter: + return CGRect(x: widthThird, y: 0, width: widthThird, height: heightThird) + case .topLeft: + return CGRect(x: 0, y: 0, width: widthThird, height: heightThird) + case .topRight: + return CGRect(x: widthThird * 2, y: 0, width: widthThird, height: heightThird) + case .verticalCenter: + return CGRect(x: widthThird, y: 0, width: widthThird, height: imageHeight) + } } } -} #endif diff --git a/Source/Colors/Models/RGBAColor.swift b/Source/Colors/Models/RGBAColor.swift index bff9917..698a73c 100644 --- a/Source/Colors/Models/RGBAColor.swift +++ b/Source/Colors/Models/RGBAColor.swift @@ -25,15 +25,16 @@ struct RGBAColor: Equatable { } } - let adjustedRed = getAdjustedColorComponent(self.red / 255.0) - let adjustedGreen = getAdjustedColorComponent(self.green / 255.0) - let adjustedBlue = getAdjustedColorComponent(self.blue / 255.0) + let adjustedRed = getAdjustedColorComponent(red / 255.0) + let adjustedGreen = getAdjustedColorComponent(green / 255.0) + let adjustedBlue = getAdjustedColorComponent(blue / 255.0) return (0.2126 * adjustedRed) + (0.7152 * adjustedGreen) + (0.0722 * adjustedBlue) } } // MARK: - Calculating color properties + extension RGBAColor { static func getContrastRatio(forTextColor textColor: RGBAColor, onBackgroundColor backgroundColor: RGBAColor) -> CGFloat { let blendedColor = textColor.alpha < 1.0 ? textColor.blended(withFraction: textColor.alpha, ofColor: backgroundColor) : textColor @@ -53,6 +54,7 @@ extension RGBAColor { } // MARK: - Text colors + extension RGBAColor { static func getTextColor(onBackgroundColor backgroundColor: RGBAColor) -> RGBAColor { let luminance = backgroundColor.relativeLuminance @@ -62,11 +64,12 @@ extension RGBAColor { } // MARK: - Background colors + extension RGBAColor { static func getBackgroundColor(forTextColor textColor: RGBAColor) -> RGBAColor { if textColor.alpha < 1.0 { - let whiteContrastRatio = self.getContrastRatio(forTextColor: textColor, onBackgroundColor: Colors.white) - let blackContrastRatio = self.getContrastRatio(forTextColor: textColor, onBackgroundColor: Colors.black) + let whiteContrastRatio = getContrastRatio(forTextColor: textColor, onBackgroundColor: Colors.white) + let blackContrastRatio = getContrastRatio(forTextColor: textColor, onBackgroundColor: Colors.black) return whiteContrastRatio > blackContrastRatio ? Colors.white : Colors.black } else { @@ -76,6 +79,7 @@ extension RGBAColor { } // MARK: - Color operations + extension RGBAColor { func blended(withFraction fraction: CGFloat, ofColor color: RGBAColor) -> RGBAColor { func getBlendedColorComponent(aColorComponent: CGFloat, fraction: CGFloat, otherColorComponent: CGFloat) -> CGFloat { @@ -83,9 +87,9 @@ extension RGBAColor { return blendedComponent } - let red = getBlendedColorComponent(aColorComponent: self.red, fraction: self.alpha, otherColorComponent: color.red) - let green = getBlendedColorComponent(aColorComponent: self.green, fraction: self.alpha, otherColorComponent: color.green) - let blue = getBlendedColorComponent(aColorComponent: self.blue, fraction: self.alpha, otherColorComponent: color.blue) + let red = getBlendedColorComponent(aColorComponent: self.red, fraction: alpha, otherColorComponent: color.red) + let green = getBlendedColorComponent(aColorComponent: self.green, fraction: alpha, otherColorComponent: color.green) + let blue = getBlendedColorComponent(aColorComponent: self.blue, fraction: alpha, otherColorComponent: color.blue) return RGBAColor(red: red, green: green, blue: blue, alpha: 1.0) } diff --git a/Source/Common/Logger/Logger.swift b/Source/Common/Logger/Logger.swift index 116f2f3..b11eff3 100644 --- a/Source/Common/Logger/Logger.swift +++ b/Source/Common/Logger/Logger.swift @@ -17,7 +17,7 @@ struct Logger { ) private static func logIfNeeded(message: String, logType: OSLogType) { - if logType >= self.minLogType { + if logType >= minLogType { onLog(message, logType) } } @@ -28,6 +28,7 @@ struct Logger { } // MARK: - Logging API + extension Logger { static func verbose(_ message: String) { logIfNeeded(message: message, logType: .debug) diff --git a/Source/Features/Capable.swift b/Source/Features/Capable.swift index e5e87fe..ccc2cc7 100644 --- a/Source/Features/Capable.swift +++ b/Source/Features/Capable.swift @@ -20,7 +20,7 @@ public struct Capable { - Parameters: - features: An optional array containing the features of interest. This will default to all features available on the current platform. - */ + */ public init(withFeatures features: [CapableFeature] = CapableFeature.allCases) { let featureStatusesProvider = FeatureStatusesProvider() let statusesModule = FeatureStatuses(withFeatures: features, featureStatusesProvider: featureStatusesProvider) @@ -44,31 +44,31 @@ public struct Capable { init(withFeatures features: [CapableFeature], featureStatusesProvider: FeatureStatusesProviderProtocol, statusesModule: StatusesProtocol, notificationModule: NotificationsProtocol) { self.features = features self.statusesModule = statusesModule - self.notificationsModule = notificationModule + notificationsModule = notificationModule self.featureStatusesProvider = featureStatusesProvider - Logger.info("Capable started with handicaps: \(features.map({ $0.rawValue }).joined(separator: ", "))") + Logger.info("Capable started with handicaps: \(features.map { $0.rawValue }.joined(separator: ", "))") } init(withHandicaps handicaps: [Handicap], featureStatusesProvider: FeatureStatusesProviderProtocol, statusesModule: StatusesProtocol, notificationModule: NotificationsProtocol) { self.handicaps = handicaps self.statusesModule = statusesModule - self.notificationsModule = notificationModule + notificationsModule = notificationModule self.featureStatusesProvider = featureStatusesProvider - Logger.info("Capable started with handicaps: \(handicaps.map({ $0.name }).joined(separator: ", "))") + Logger.info("Capable started with handicaps: \(handicaps.map { $0.name }.joined(separator: ", "))") } } // MARK: - Accessibility Statuses -extension Capable { +extension Capable { /** The `statusMap` property returns a dictionary of all `CapableFeature`s or `Handicap`s , that the Capable instance has been initialized with along with their current statuses. This object is compatible with most analytic SDKs such as **Fabric Answers**, **Firebase Analytics**, **AppCenter Analytics**, or **HockeyApp**. While most entries can only have a status set to **enabled** or **disabled**, the `.largerText` feature offers the font scale set by the user. */ public var statusMap: [String: String] { - return self.statusesModule.statusMap + return statusesModule.statusMap } /** @@ -80,7 +80,7 @@ extension Capable { - Returns: `true` if the given feature has been enabled, otherwise `false`. */ public func isFeatureEnabled(feature: CapableFeature) -> Bool { - return self.featureStatusesProvider.isFeatureEnabled(feature: feature) + return featureStatusesProvider.isFeatureEnabled(feature: feature) } /** @@ -95,12 +95,11 @@ extension Capable { guard let handicapStatuses = self.statusesModule as? HandicapStatusesProtocol else { return false } return handicapStatuses.isHandicapEnabled(handicapName: handicapName) } - } // MARK: - Debug Logging -extension Capable { +extension Capable { /** The minimum log level that should be considered when logging messages. Note that the custom 'onLog' closure will only be called for messages of this log type or higher. This value defaults to `OSLogType.debug`. */ @@ -120,7 +119,7 @@ extension Capable { - message: The message string that is about to be logged. - logType: The 'OSLogType' of the message. */ - public static var onLog: (_ message: String, _ logType: OSLogType) -> Void { + public static var onLog: (_ message: String, _ logType: OSLogType) -> Void { get { return Logger.onLog } diff --git a/Source/Features/Extensions/CGFloat+contentSizeString.swift b/Source/Features/Extensions/CGFloat+contentSizeString.swift index 6adaea8..687f11a 100644 --- a/Source/Features/Extensions/CGFloat+contentSizeString.swift +++ b/Source/Features/Extensions/CGFloat+contentSizeString.swift @@ -7,27 +7,27 @@ #if os(watchOS) -import UIKit + import UIKit -extension CGFloat { - var contentSizeString: String { - switch self { - case 14.0: - return "XS" - case 15.0: - return "S" - case 16.0: - return "L" - case 17.0: - return "XL" - case 18.0: - return "XXL" - case 19.0: - return "XXXL" - default: - return "Unknown" + extension CGFloat { + var contentSizeString: String { + switch self { + case 14.0: + return "XS" + case 15.0: + return "S" + case 16.0: + return "L" + case 17.0: + return "XL" + case 18.0: + return "XXL" + case 19.0: + return "XXXL" + default: + return "Unknown" + } } } -} #endif diff --git a/Source/Features/Extensions/HearingDeviceEar+stringValue.swift b/Source/Features/Extensions/HearingDeviceEar+stringValue.swift index 86cca68..3ad779f 100644 --- a/Source/Features/Extensions/HearingDeviceEar+stringValue.swift +++ b/Source/Features/Extensions/HearingDeviceEar+stringValue.swift @@ -7,21 +7,21 @@ #if os(iOS) -import UIKit + import UIKit -extension UIAccessibility.HearingDeviceEar { - var statusString: String { - switch self { - case .both: - return "both" - case .left: - return "left" - case .right: - return "right" - default: - return "disabled" + extension UIAccessibility.HearingDeviceEar { + var statusString: String { + switch self { + case .both: + return "both" + case .left: + return "left" + case .right: + return "right" + default: + return "disabled" + } } } -} #endif diff --git a/Source/Features/Extensions/Notification+Name.swift b/Source/Features/Extensions/Notification+Name.swift index 5261cbc..7661df5 100644 --- a/Source/Features/Extensions/Notification+Name.swift +++ b/Source/Features/Extensions/Notification+Name.swift @@ -9,7 +9,6 @@ import Foundation /// Extension that defines notification names provided by the Capable framework. extension Notification.Name { - /// Name of the notification that gets fired whenever an observed accessibility feature status changes. public static let CapableFeatureStatusDidChange = Notification.Name("capable-feature-status-did-change") diff --git a/Source/Features/Extensions/String+isDefaultContentSize.swift b/Source/Features/Extensions/String+isDefaultContentSize.swift index d3aded6..998c0bc 100644 --- a/Source/Features/Extensions/String+isDefaultContentSize.swift +++ b/Source/Features/Extensions/String+isDefaultContentSize.swift @@ -7,26 +7,26 @@ #if os(watchOS) -import WatchKit + import WatchKit -extension String { - struct DefaultContentSize { - // 38mm - static let small = "UICTContentSizeCategoryS" - // 42mm - static let large = "UICTContentSizeCategoryL" - } + extension String { + struct DefaultContentSize { + // 38mm + static let small = "UICTContentSizeCategoryS" + // 42mm + static let large = "UICTContentSizeCategoryL" + } - var isDefaultContentSizeString: Bool { - let watchSize = WKInterfaceDevice.current().preferredContentSizeCategory - if watchSize == DefaultContentSize.small { - return self == "S" - } else if watchSize == DefaultContentSize.large { - return self == "L" - } else { - return false + var isDefaultContentSizeString: Bool { + let watchSize = WKInterfaceDevice.current().preferredContentSizeCategory + if watchSize == DefaultContentSize.small { + return self == "S" + } else if watchSize == DefaultContentSize.large { + return self == "L" + } else { + return false + } } } -} #endif diff --git a/Source/Features/Extensions/UIContentSizeCategory+values.swift b/Source/Features/Extensions/UIContentSizeCategory+values.swift index 1c1365d..d66579b 100644 --- a/Source/Features/Extensions/UIContentSizeCategory+values.swift +++ b/Source/Features/Extensions/UIContentSizeCategory+values.swift @@ -7,43 +7,43 @@ #if os(iOS) -import UIKit + import UIKit -extension UIContentSizeCategory { - var stringValue: String { - switch self { - case .extraSmall: - return "XS" - case .small: - return "S" - case .medium: - return "M" - case .large: - return "L" - case .extraLarge: - return "XL" - case .extraExtraLarge: - return "XXL" - case .extraExtraExtraLarge: - return "XXXL" - case .accessibilityMedium: - return "Accessibility M" - case .accessibilityLarge: - return "Accessibility L" - case .accessibilityExtraLarge: - return "Accessibility XL" - case .accessibilityExtraExtraLarge: - return "Accessibility XXL" - case .accessibilityExtraExtraExtraLarge: - return "Accessibility XXXL" - default: - return "Unknown" + extension UIContentSizeCategory { + var stringValue: String { + switch self { + case .extraSmall: + return "XS" + case .small: + return "S" + case .medium: + return "M" + case .large: + return "L" + case .extraLarge: + return "XL" + case .extraExtraLarge: + return "XXL" + case .extraExtraExtraLarge: + return "XXXL" + case .accessibilityMedium: + return "Accessibility M" + case .accessibilityLarge: + return "Accessibility L" + case .accessibilityExtraLarge: + return "Accessibility XL" + case .accessibilityExtraExtraLarge: + return "Accessibility XXL" + case .accessibilityExtraExtraExtraLarge: + return "Accessibility XXXL" + default: + return "Unknown" + } } - } - var isDefault: Bool { - return self == .medium + var isDefault: Bool { + return self == .medium + } } -} #endif diff --git a/Source/Features/Models/CapableFeature.swift b/Source/Features/Models/CapableFeature.swift index 52f87b7..b5b513d 100644 --- a/Source/Features/Models/CapableFeature.swift +++ b/Source/Features/Models/CapableFeature.swift @@ -7,92 +7,91 @@ /// An enum specifying all features available on the current platform. public enum CapableFeature: String, CaseIterable { - #if os(iOS) - /// Menu that helps people with motor skill impairments to do certain actions or gestures by using a single tap. - case assistiveTouch + /// Menu that helps people with motor skill impairments to do certain actions or gestures by using a single tap. + case assistiveTouch - /// Enhances text contrast. - case darkerSystemColors + /// Enhances text contrast. + case darkerSystemColors - /// Restricts access to certain features of a single app to keep the user focused. - case guidedAccess + /// Restricts access to certain features of a single app to keep the user focused. + case guidedAccess - /// Pairing status of a hearing aid. - case hearingDevice + /// Pairing status of a hearing aid. + case hearingDevice - /// Displays on/off labels for UISwitch controls. - case onOffSwitchLabels + /// Displays on/off labels for UISwitch controls. + case onOffSwitchLabels - /// Deletes the last command by shaking the phone. - case shakeToUndo + /// Deletes the last command by shaking the phone. + case shakeToUndo - /// Reads out the content of the current screen. - case speakScreen + /// Reads out the content of the current screen. + case speakScreen - /// Reads out the selected content. - case speakSelection + /// Reads out the selected content. + case speakSelection #endif #if os(OSX) - /// Enables users to navigate through items of the screen without having to use a mouse. - case fullKeyboardAccess + /// Enables users to navigate through items of the screen without having to use a mouse. + case fullKeyboardAccess - /// Increases contrast to make out text and interface elements. - case increaseContrast + /// Increases contrast to make out text and interface elements. + case increaseContrast #endif #if os(iOS) || os(tvOS) - /// Displays subtitles when playing videos. - case closedCaptioning + /// Displays subtitles when playing videos. + case closedCaptioning - /// Makes the display more readable for color blind people by using gray tones instead of colors. - case grayscale + /// Makes the display more readable for color blind people by using gray tones instead of colors. + case grayscale - /// Merges stereo audio channels to help users that are hard of hearing or deaf in one ear. - case monoAudio + /// Merges stereo audio channels to help users that are hard of hearing or deaf in one ear. + case monoAudio - /// Allows users who are sensitive to motion to disable automatic video playback. - case videoAutoplay + /// Allows users who are sensitive to motion to disable automatic video playback. + case videoAutoplay #endif #if os(iOS) || os(watchOS) - /// Increases legibility by making fonts bigger. - case largerText + /// Increases legibility by making fonts bigger. + case largerText #endif #if os(iOS) || os(OSX) - /// Helps color blind users to differentiate settings differently, e.g. by using shapes rather than colors. - case differentiateWithoutColor + /// Helps color blind users to differentiate settings differently, e.g. by using shapes rather than colors. + case differentiateWithoutColor #endif #if os(iOS) || os(tvOS) || os(OSX) - /// Helps people with low vision, color blindness, or sensitivity to brightness to read the display content. - case invertColors + /// Helps people with low vision, color blindness, or sensitivity to brightness to read the display content. + case invertColors - /// Removes transparency from layers to make them readable for users with visual impairment. - case reduceTransparency + /// Removes transparency from layers to make them readable for users with visual impairment. + case reduceTransparency - /// Allows users with limited mobility to control their device with the help of ability switches and other adaptive devices. - case switchControl + /// Allows users with limited mobility to control their device with the help of ability switches and other adaptive devices. + case switchControl #endif #if os(iOS) || os(tvOS) || os(watchOS) - /// Increases legibility by making fonts heavier. - case boldText + /// Increases legibility by making fonts heavier. + case boldText #endif @@ -111,6 +110,6 @@ public enum CapableFeature: String, CaseIterable { - Returns: An array containing the feature names as strings */ public static func keys(forFeatures features: [CapableFeature]) -> [String] { - return features.map {$0.rawValue} + return features.map { $0.rawValue } } } diff --git a/Source/Features/Models/FeatureStatus.swift b/Source/Features/Models/FeatureStatus.swift index 429132b..0c96e98 100644 --- a/Source/Features/Models/FeatureStatus.swift +++ b/Source/Features/Models/FeatureStatus.swift @@ -7,7 +7,6 @@ /// Model class that describes the content of a Capable notification (see `Notification.Name.CapableFeatureStatusDidChange`) public struct FeatureStatus { - /// The feature type. public private(set) var feature: CapableFeature diff --git a/Source/Features/Models/Handicap.swift b/Source/Features/Models/Handicap.swift index 7d1650c..1430b15 100644 --- a/Source/Features/Models/Handicap.swift +++ b/Source/Features/Models/Handicap.swift @@ -9,7 +9,6 @@ Model class that groups a number of `CapableFeature`s to represent a user's handicap. */ public struct Handicap: Equatable { - /// A list of `CapableFeature`s that are expected to be enabled if a user has this handicap. public private(set) var features: [CapableFeature] diff --git a/Source/Features/Models/HandicapEnabledMode.swift b/Source/Features/Models/HandicapEnabledMode.swift index 1b8de35..f19472c 100644 --- a/Source/Features/Models/HandicapEnabledMode.swift +++ b/Source/Features/Models/HandicapEnabledMode.swift @@ -7,7 +7,6 @@ /// This enum defines several modes which describe whether all features need to be enabled to set the `Handicap`'s status to enabled or only one of them. public enum HandicapEnabledMode: String { - /// The `Handicap`'s status is enabled if one of its features is currently set to **enabled**. case oneFeatureEnabled diff --git a/Source/Features/Models/HandicapStatus.swift b/Source/Features/Models/HandicapStatus.swift index c14a7b1..e67d64e 100644 --- a/Source/Features/Models/HandicapStatus.swift +++ b/Source/Features/Models/HandicapStatus.swift @@ -7,7 +7,6 @@ /// Model class that describes the content of a Capable notification (see `Notification.Name.CapableHandicapStatusDidChange`) public struct HandicapStatus { - /// The `Handicap` that has changed. public private(set) var handicap: Handicap diff --git a/Source/Features/Notifications/FeatureNotifications.swift b/Source/Features/Notifications/FeatureNotifications.swift index 5a02b15..bdff6e9 100644 --- a/Source/Features/Notifications/FeatureNotifications.swift +++ b/Source/Features/Notifications/FeatureNotifications.swift @@ -10,7 +10,7 @@ import Foundation class FeatureNotifications: Notifications { convenience init(featureStatusesProvider: FeatureStatusesProviderProtocol, features: [CapableFeature], targetNotificationCenter: NotificationCenter = NotificationCenter.default, systemNotificationCenter: NotificationCenter = Notifications.systemNotificationCenter) { self.init(featureStatusesProvider: featureStatusesProvider, targetNotificationCenter: targetNotificationCenter, systemNotificationCenter: systemNotificationCenter) - self.enableNotifications(forFeatures: features) + enableNotifications(forFeatures: features) } required init(featureStatusesProvider: FeatureStatusesProviderProtocol, targetNotificationCenter: NotificationCenter = NotificationCenter.default, systemNotificationCenter: NotificationCenter = Notifications.systemNotificationCenter) { @@ -19,7 +19,7 @@ class FeatureNotifications: Notifications { override func postNotification(withFeature feature: CapableFeature, statusString: String) { let featureStatus = FeatureStatus(feature: feature, statusString: statusString) - self.targetNotificationCenter.post(name: .CapableFeatureStatusDidChange, object: featureStatus) + targetNotificationCenter.post(name: .CapableFeatureStatusDidChange, object: featureStatus) Logger.info("Posted notification for feature \(feature) set to \(statusString)") } diff --git a/Source/Features/Notifications/HandicapNotifications.swift b/Source/Features/Notifications/HandicapNotifications.swift index 57f5ad6..7f7da9b 100644 --- a/Source/Features/Notifications/HandicapNotifications.swift +++ b/Source/Features/Notifications/HandicapNotifications.swift @@ -16,8 +16,8 @@ class HandicapNotifications: Notifications { self.init(featureStatusesProvider: featureStatusesProvider, targetNotificationCenter: targetNotificationCenter, systemNotificationCenter: systemNotificationCenter) self.statusesModule = statusesModule self.handicaps = handicaps - self.lastValues = Dictionary(uniqueKeysWithValues: self.handicaps.map { ($0.name, statusesModule.isHandicapEnabled(handicapName: $0.name).statusString) }) - self.enableNotifications(forHandicaps: handicaps) + lastValues = Dictionary(uniqueKeysWithValues: self.handicaps.map { ($0.name, statusesModule.isHandicapEnabled(handicapName: $0.name).statusString) }) + enableNotifications(forHandicaps: handicaps) } required init(featureStatusesProvider: FeatureStatusesProviderProtocol, targetNotificationCenter: NotificationCenter = NotificationCenter.default, systemNotificationCenter: NotificationCenter = Notifications.systemNotificationCenter) { @@ -25,11 +25,11 @@ class HandicapNotifications: Notifications { } override func postNotification(withFeature feature: CapableFeature, statusString: String) { - for handicap in self.handicaps { - if handicap.features.contains(feature), self.hasStatusChanged(handicap: handicap) { - self.lastValues[handicap.name] = statusString + for handicap in handicaps { + if handicap.features.contains(feature), hasStatusChanged(handicap: handicap) { + lastValues[handicap.name] = statusString let handicapStatus = HandicapStatus(handicap: handicap, statusString: statusString) - self.targetNotificationCenter.post(name: .CapableHandicapStatusDidChange, object: handicapStatus) + targetNotificationCenter.post(name: .CapableHandicapStatusDidChange, object: handicapStatus) Logger.info("Posted notification for handicap \(handicap.name) set to \(statusString)") } @@ -43,13 +43,14 @@ class HandicapNotifications: Notifications { fatalError(errorMessage) } let currentStatus = handicapStatuses.isHandicapEnabled(handicapName: handicap.name).statusString - let lastStatus = self.lastValues[handicap.name] + let lastStatus = lastValues[handicap.name] return currentStatus != lastStatus } } // MARK: - Register Observers + extension Notifications { func enableNotifications(forHandicaps handicaps: [Handicap]) { var observedFeatures = [CapableFeature]() diff --git a/Source/Features/Notifications/NotificationCenterProtocol.swift b/Source/Features/Notifications/NotificationCenterProtocol.swift index 056336e..32f6c40 100644 --- a/Source/Features/Notifications/NotificationCenterProtocol.swift +++ b/Source/Features/Notifications/NotificationCenterProtocol.swift @@ -5,6 +5,8 @@ // Created by Christoph Wendt on 23.08.18. // +import Foundation + protocol NotificationCenterProtocol { func addObserver(_ observer: Any, selector aSelector: Selector, name aName: NSNotification.Name?, object anObject: Any?) func post(name aName: NSNotification.Name, object anObject: Any?) diff --git a/Source/Features/Notifications/Notifications.swift b/Source/Features/Notifications/Notifications.swift index 3f1624b..273d1a5 100644 --- a/Source/Features/Notifications/Notifications.swift +++ b/Source/Features/Notifications/Notifications.swift @@ -8,15 +8,15 @@ import Foundation #if os(iOS) || os(tvOS) -import UIKit + import UIKit #endif #if os(OSX) -import AppKit + import AppKit #endif #if os(watchOS) -import WatchKit + import WatchKit #endif class Notifications: NSObject, NotificationsProtocol { @@ -25,8 +25,8 @@ class Notifications: NSObject, NotificationsProtocol { var systemNotificationCenter: NotificationCenter #if os(OSX) - var displayOptionStatuses: [CapableFeature: Bool] - var keyValueObservations: [NSKeyValueObservation] + var displayOptionStatuses: [CapableFeature: Bool] + var keyValueObservations: [NSKeyValueObservation] #endif required init(featureStatusesProvider: FeatureStatusesProviderProtocol, targetNotificationCenter: NotificationCenter = NotificationCenter.default, systemNotificationCenter: NotificationCenter = Notifications.systemNotificationCenter) { @@ -35,20 +35,20 @@ class Notifications: NSObject, NotificationsProtocol { self.systemNotificationCenter = systemNotificationCenter #if os(OSX) - self.displayOptionStatuses = [CapableFeature: Bool]() - self.keyValueObservations = [NSKeyValueObservation]() + displayOptionStatuses = [CapableFeature: Bool]() + keyValueObservations = [NSKeyValueObservation]() #endif } static var systemNotificationCenter: NotificationCenter { #if os(OSX) - return NSWorkspace.shared.notificationCenter + return NSWorkspace.shared.notificationCenter #else - return NotificationCenter.default + return NotificationCenter.default #endif } - func postNotification(withFeature feature: CapableFeature, statusString: String) { + func postNotification(withFeature _: CapableFeature, statusString _: String) { let errorMessage = "Capable.Notifications.postNotification: Function needs to be implemented by its subclass." Logger.error(errorMessage) fatalError(errorMessage) @@ -56,257 +56,259 @@ class Notifications: NSObject, NotificationsProtocol { } // MARK: - Register Observers -extension Notifications { +extension Notifications { // swiftlint:disable cyclomatic_complexity func enableNotifications(forFeatures features: [CapableFeature]) { - #if os(iOS) - if features.contains(.assistiveTouch) { - addObserver(forNotification: UIAccessibility.assistiveTouchStatusDidChangeNotification, selector: #selector(self.assistiveTouchStatusChanged)) - } - if features.contains(.darkerSystemColors) { - addObserver(forNotification: UIAccessibility.darkerSystemColorsStatusDidChangeNotification, selector: #selector(self.darkerSystemColorsStatusChanged)) - } - if features.contains(.differentiateWithoutColor) { - if #available(iOS 13.0, *) { - addObserver(forNotification: NSNotification.Name(rawValue: UIAccessibility.differentiateWithoutColorDidChangeNotification), selector: #selector(self.differentiateWithoutColorStatusChanged)) + if features.contains(.assistiveTouch) { + addObserver(forNotification: UIAccessibility.assistiveTouchStatusDidChangeNotification, selector: #selector(assistiveTouchStatusChanged)) } - } - if features.contains(.guidedAccess) { - addObserver(forNotification: UIAccessibility.guidedAccessStatusDidChangeNotification, selector: #selector(self.guidedAccessStatusChanged)) - } - if features.contains(.hearingDevice) { - addObserver(forNotification: UIAccessibility.hearingDevicePairedEarDidChangeNotification, selector: #selector(self.guidedAccessStatusChanged)) - } - if features.contains(.largerText) { - addObserver(forNotification: UIContentSizeCategory.didChangeNotification, selector: #selector(self.largerTextStatusChanged)) - } - if features.contains(.onOffSwitchLabels) { - if #available(iOS 13.0, *) { - addObserver(forNotification: UIAccessibility.onOffSwitchLabelsDidChangeNotification, selector: #selector(self.onOffSwitchLabelsStatusChanged)) + if features.contains(.darkerSystemColors) { + addObserver(forNotification: UIAccessibility.darkerSystemColorsStatusDidChangeNotification, selector: #selector(darkerSystemColorsStatusChanged)) + } + if features.contains(.differentiateWithoutColor) { + if #available(iOS 13.0, *) { + addObserver(forNotification: NSNotification.Name(rawValue: UIAccessibility.differentiateWithoutColorDidChangeNotification), selector: #selector(self.differentiateWithoutColorStatusChanged)) + } + } + if features.contains(.guidedAccess) { + addObserver(forNotification: UIAccessibility.guidedAccessStatusDidChangeNotification, selector: #selector(guidedAccessStatusChanged)) + } + if features.contains(.hearingDevice) { + addObserver(forNotification: UIAccessibility.hearingDevicePairedEarDidChangeNotification, selector: #selector(guidedAccessStatusChanged)) + } + if features.contains(.largerText) { + addObserver(forNotification: UIContentSizeCategory.didChangeNotification, selector: #selector(largerTextStatusChanged)) + } + if features.contains(.onOffSwitchLabels) { + if #available(iOS 13.0, *) { + addObserver(forNotification: UIAccessibility.onOffSwitchLabelsDidChangeNotification, selector: #selector(self.onOffSwitchLabelsStatusChanged)) + } + } + if features.contains(.shakeToUndo) { + addObserver(forNotification: UIAccessibility.shakeToUndoDidChangeNotification, selector: #selector(shakeToUndoStatusChanged)) + } + if features.contains(.speakScreen) { + addObserver(forNotification: UIAccessibility.speakScreenStatusDidChangeNotification, selector: #selector(speakScreenStatusChanged)) + } + if features.contains(.speakSelection) { + addObserver(forNotification: UIAccessibility.speakSelectionStatusDidChangeNotification, selector: #selector(speakSelectionStatusChanged)) } - } - if features.contains(.shakeToUndo) { - addObserver(forNotification: UIAccessibility.shakeToUndoDidChangeNotification, selector: #selector(self.shakeToUndoStatusChanged)) - } - if features.contains(.speakScreen) { - addObserver(forNotification: UIAccessibility.speakScreenStatusDidChangeNotification, selector: #selector(self.speakScreenStatusChanged)) - } - if features.contains(.speakSelection) { - addObserver(forNotification: UIAccessibility.speakSelectionStatusDidChangeNotification, selector: #selector(self.speakSelectionStatusChanged)) - } #endif #if os(iOS) || os(tvOS) - if features.contains(.boldText) { - addObserver(forNotification: UIAccessibility.boldTextStatusDidChangeNotification, selector: #selector(self.boldTextStatusChanged)) - } - if features.contains(.closedCaptioning) { - addObserver(forNotification: UIAccessibility.closedCaptioningStatusDidChangeNotification, selector: #selector(self.closedCaptioningStatusChanged)) - } - if features.contains(.grayscale) { - addObserver(forNotification: UIAccessibility.grayscaleStatusDidChangeNotification, selector: #selector(self.grayscaleStatusChanged)) - } - if features.contains(.invertColors) { - addObserver(forNotification: UIAccessibility.invertColorsStatusDidChangeNotification, selector: #selector(self.invertColorsStatusChanged)) - } - if features.contains(.monoAudio) { - addObserver(forNotification: UIAccessibility.monoAudioStatusDidChangeNotification, selector: #selector(self.monoAudioStatusChanged)) - } - if features.contains(.switchControl) { - addObserver(forNotification: UIAccessibility.switchControlStatusDidChangeNotification, selector: #selector(self.switchControlStatusChanged)) - } - if features.contains(.reduceMotion) { - addObserver(forNotification: UIAccessibility.reduceMotionStatusDidChangeNotification, selector: #selector(self.reduceMotionStatusChanged)) - } - if features.contains(.reduceTransparency) { - addObserver(forNotification: UIAccessibility.reduceTransparencyStatusDidChangeNotification, selector: #selector(self.reduceTransparencyStatusChanged)) - } - if features.contains(.videoAutoplay) { - if #available(iOS 13.0, tvOS 13.0, *) { - addObserver(forNotification: UIAccessibility.videoAutoplayStatusDidChangeNotification, selector: #selector(self.videoAutoplayStatusChanged)) + if features.contains(.boldText) { + addObserver(forNotification: UIAccessibility.boldTextStatusDidChangeNotification, selector: #selector(boldTextStatusChanged)) } - } - if features.contains(.voiceOver) { - if #available(iOS 11.0, tvOS 11.0, *) { - addObserver(forNotification: UIAccessibility.voiceOverStatusDidChangeNotification, selector: #selector(self.voiceOverStatusChanged)) - } else { - addObserver(forNotification: Notification.Name(UIAccessibilityVoiceOverStatusChanged), selector: #selector(self.voiceOverStatusChanged)) + if features.contains(.closedCaptioning) { + addObserver(forNotification: UIAccessibility.closedCaptioningStatusDidChangeNotification, selector: #selector(closedCaptioningStatusChanged)) + } + if features.contains(.grayscale) { + addObserver(forNotification: UIAccessibility.grayscaleStatusDidChangeNotification, selector: #selector(grayscaleStatusChanged)) + } + if features.contains(.invertColors) { + addObserver(forNotification: UIAccessibility.invertColorsStatusDidChangeNotification, selector: #selector(invertColorsStatusChanged)) + } + if features.contains(.monoAudio) { + addObserver(forNotification: UIAccessibility.monoAudioStatusDidChangeNotification, selector: #selector(monoAudioStatusChanged)) + } + if features.contains(.switchControl) { + addObserver(forNotification: UIAccessibility.switchControlStatusDidChangeNotification, selector: #selector(switchControlStatusChanged)) + } + if features.contains(.reduceMotion) { + addObserver(forNotification: UIAccessibility.reduceMotionStatusDidChangeNotification, selector: #selector(reduceMotionStatusChanged)) + } + if features.contains(.reduceTransparency) { + addObserver(forNotification: UIAccessibility.reduceTransparencyStatusDidChangeNotification, selector: #selector(reduceTransparencyStatusChanged)) + } + if features.contains(.videoAutoplay) { + if #available(iOS 13.0, tvOS 13.0, *) { + addObserver(forNotification: UIAccessibility.videoAutoplayStatusDidChangeNotification, selector: #selector(self.videoAutoplayStatusChanged)) + } + } + if features.contains(.voiceOver) { + if #available(iOS 11.0, tvOS 11.0, *) { + addObserver(forNotification: UIAccessibility.voiceOverStatusDidChangeNotification, selector: #selector(self.voiceOverStatusChanged)) + } else { + addObserver(forNotification: Notification.Name(UIAccessibilityVoiceOverStatusChanged), selector: #selector(voiceOverStatusChanged)) + } } - } #endif #if os(watchOS) - if #available(watchOS 4.0, *), features.contains(.reduceMotion) { - addObserver(forNotification: .WKAccessibilityReduceMotionStatusDidChange, selector: #selector(self.reduceMotionStatusChanged)) - } - if features.contains(.voiceOver) { - addObserver(forNotification: NSNotification.Name(rawValue: WKAccessibilityVoiceOverStatusChanged), selector: #selector(self.voiceOverStatusChanged)) - } + if #available(watchOS 4.0, *), features.contains(.reduceMotion) { + addObserver(forNotification: .WKAccessibilityReduceMotionStatusDidChange, selector: #selector(self.reduceMotionStatusChanged)) + } + if features.contains(.voiceOver) { + addObserver(forNotification: NSNotification.Name(rawValue: WKAccessibilityVoiceOverStatusChanged), selector: #selector(voiceOverStatusChanged)) + } #endif #if os(OSX) - if features.contains(.differentiateWithoutColor) { - self.displayOptionStatuses[.differentiateWithoutColor] = self.featureStatusesProvider.isDifferentiateWithoutColorEnabled - } - if features.contains(.increaseContrast) { - self.displayOptionStatuses[.increaseContrast] = self.featureStatusesProvider.isIncreaseContrastEnabled - } - if features.contains(.invertColors) { - self.displayOptionStatuses[.invertColors] = self.featureStatusesProvider.isInvertColorsEnabled - } - if features.contains(.reduceMotion) { - self.displayOptionStatuses[.reduceMotion] = self.featureStatusesProvider.isReduceMotionEnabled - } - if features.contains(.reduceTransparency) { - self.displayOptionStatuses[.reduceTransparency] = self.featureStatusesProvider.isReduceTransparencyEnabled - } + if features.contains(.differentiateWithoutColor) { + displayOptionStatuses[.differentiateWithoutColor] = featureStatusesProvider.isDifferentiateWithoutColorEnabled + } + if features.contains(.increaseContrast) { + displayOptionStatuses[.increaseContrast] = featureStatusesProvider.isIncreaseContrastEnabled + } + if features.contains(.invertColors) { + displayOptionStatuses[.invertColors] = featureStatusesProvider.isInvertColorsEnabled + } + if features.contains(.reduceMotion) { + displayOptionStatuses[.reduceMotion] = featureStatusesProvider.isReduceMotionEnabled + } + if features.contains(.reduceTransparency) { + displayOptionStatuses[.reduceTransparency] = featureStatusesProvider.isReduceTransparencyEnabled + } - addObserver(forNotification: NSWorkspace.accessibilityDisplayOptionsDidChangeNotification, selector: #selector(self.displayOptionsChanged), object: NSWorkspace.shared) + addObserver(forNotification: NSWorkspace.accessibilityDisplayOptionsDidChangeNotification, selector: #selector(displayOptionsChanged), object: NSWorkspace.shared) - if features.contains(.switchControl), #available(OSX 10.13, *) { - let switchControlObservation = NSWorkspace.shared.observe(\NSWorkspace.isSwitchControlEnabled) { _, _ in - self.switchControlStatusChanged() + if features.contains(.switchControl), #available(OSX 10.13, *) { + let switchControlObservation = NSWorkspace.shared.observe(\NSWorkspace.isSwitchControlEnabled) { _, _ in + self.switchControlStatusChanged() + } + self.keyValueObservations.append(switchControlObservation) } - self.keyValueObservations.append(switchControlObservation) - } - if features.contains(.voiceOver), #available(OSX 10.13, *) { - let voiceOverObservation = NSWorkspace.shared.observe(\NSWorkspace.isVoiceOverEnabled) { _, _ in - self.voiceOverStatusChanged() + if features.contains(.voiceOver), #available(OSX 10.13, *) { + let voiceOverObservation = NSWorkspace.shared.observe(\NSWorkspace.isVoiceOverEnabled) { _, _ in + self.voiceOverStatusChanged() + } + self.keyValueObservations.append(voiceOverObservation) } - self.keyValueObservations.append(voiceOverObservation) - } #endif - Logger.info("Registered notification for features \(features.map({ $0.rawValue }).joined(separator: ", "))") + Logger.info("Registered notification for features \(features.map { $0.rawValue }.joined(separator: ", "))") } + // swiftlint:enable cyclomatic_complexity } // MARK: - Handle notifications + extension Notifications { func addObserver(forNotification notificationName: NSNotification.Name, selector: Selector, object: Any? = nil) { - self.systemNotificationCenter.addObserver( + systemNotificationCenter.addObserver( self, selector: selector, name: notificationName, - object: object) + object: object + ) } #if os(iOS) - @objc func assistiveTouchStatusChanged() { - postNotification(withFeature: .assistiveTouch, statusString: self.featureStatusesProvider.isAssistiveTouchEnabled.statusString) - } + @objc func assistiveTouchStatusChanged() { + postNotification(withFeature: .assistiveTouch, statusString: featureStatusesProvider.isAssistiveTouchEnabled.statusString) + } - @objc func darkerSystemColorsStatusChanged() { - self.postNotification(withFeature: .darkerSystemColors, statusString: self.featureStatusesProvider.isDarkerSystemColorsEnabled.statusString) - } + @objc func darkerSystemColorsStatusChanged() { + postNotification(withFeature: .darkerSystemColors, statusString: featureStatusesProvider.isDarkerSystemColorsEnabled.statusString) + } - @objc func differentiateWithoutColorStatusChanged() { - self.postNotification(withFeature: .differentiateWithoutColor, statusString: self.featureStatusesProvider.isDifferentiateWithoutColorEnabled.statusString) - } + @objc func differentiateWithoutColorStatusChanged() { + postNotification(withFeature: .differentiateWithoutColor, statusString: featureStatusesProvider.isDifferentiateWithoutColorEnabled.statusString) + } - @objc func guidedAccessStatusChanged() { - self.postNotification(withFeature: .guidedAccess, statusString: self.featureStatusesProvider.isGuidedAccessEnabled.statusString) - } + @objc func guidedAccessStatusChanged() { + postNotification(withFeature: .guidedAccess, statusString: featureStatusesProvider.isGuidedAccessEnabled.statusString) + } - @objc func hearingDeviceStatusChanged() { - self.postNotification(withFeature: .hearingDevice, statusString: self.featureStatusesProvider.hearingDevicePairedEar.statusString) - } + @objc func hearingDeviceStatusChanged() { + postNotification(withFeature: .hearingDevice, statusString: featureStatusesProvider.hearingDevicePairedEar.statusString) + } - @objc func largerTextStatusChanged() { - self.postNotification(withFeature: .largerText, statusString: self.featureStatusesProvider.largerTextCatagory.stringValue) - } + @objc func largerTextStatusChanged() { + postNotification(withFeature: .largerText, statusString: featureStatusesProvider.largerTextCatagory.stringValue) + } - @objc func onOffSwitchLabelsStatusChanged() { - self.postNotification(withFeature: .onOffSwitchLabels, statusString: self.featureStatusesProvider.isOnOffSwitchLabelsEnabled.statusString) - } + @objc func onOffSwitchLabelsStatusChanged() { + postNotification(withFeature: .onOffSwitchLabels, statusString: featureStatusesProvider.isOnOffSwitchLabelsEnabled.statusString) + } - @objc func shakeToUndoStatusChanged() { - self.postNotification(withFeature: .shakeToUndo, statusString: self.featureStatusesProvider.isShakeToUndoEnabled.statusString) - } + @objc func shakeToUndoStatusChanged() { + postNotification(withFeature: .shakeToUndo, statusString: featureStatusesProvider.isShakeToUndoEnabled.statusString) + } - @objc func speakScreenStatusChanged() { - self.postNotification(withFeature: .speakScreen, statusString: self.featureStatusesProvider.isSpeakScreenEnabled.statusString) - } + @objc func speakScreenStatusChanged() { + postNotification(withFeature: .speakScreen, statusString: featureStatusesProvider.isSpeakScreenEnabled.statusString) + } - @objc func speakSelectionStatusChanged() { - self.postNotification(withFeature: .speakSelection, statusString: self.featureStatusesProvider.isSpeakSelectionEnabled.statusString) - } + @objc func speakSelectionStatusChanged() { + postNotification(withFeature: .speakSelection, statusString: featureStatusesProvider.isSpeakSelectionEnabled.statusString) + } #endif #if os(iOS) || os(tvOS) - @objc func boldTextStatusChanged() { - self.postNotification(withFeature: .boldText, statusString: self.featureStatusesProvider.isBoldTextEnabled.statusString) - } + @objc func boldTextStatusChanged() { + postNotification(withFeature: .boldText, statusString: featureStatusesProvider.isBoldTextEnabled.statusString) + } - @objc func closedCaptioningStatusChanged() { - self.postNotification(withFeature: .closedCaptioning, statusString: self.featureStatusesProvider.isClosedCaptioningEnabled.statusString) - } + @objc func closedCaptioningStatusChanged() { + postNotification(withFeature: .closedCaptioning, statusString: featureStatusesProvider.isClosedCaptioningEnabled.statusString) + } - @objc func grayscaleStatusChanged() { - self.postNotification(withFeature: .grayscale, statusString: self.featureStatusesProvider.isGrayscaleEnabled.statusString) - } + @objc func grayscaleStatusChanged() { + postNotification(withFeature: .grayscale, statusString: featureStatusesProvider.isGrayscaleEnabled.statusString) + } - @objc func invertColorsStatusChanged() { - self.postNotification(withFeature: .invertColors, statusString: self.featureStatusesProvider.isInvertColorsEnabled.statusString) - } + @objc func invertColorsStatusChanged() { + postNotification(withFeature: .invertColors, statusString: featureStatusesProvider.isInvertColorsEnabled.statusString) + } - @objc func monoAudioStatusChanged() { - self.postNotification(withFeature: .monoAudio, statusString: self.featureStatusesProvider.isMonoAudioEnabled.statusString) - } + @objc func monoAudioStatusChanged() { + postNotification(withFeature: .monoAudio, statusString: featureStatusesProvider.isMonoAudioEnabled.statusString) + } - @objc func reduceTransparencyStatusChanged() { - self.postNotification(withFeature: .reduceTransparency, statusString: self.featureStatusesProvider.isReduceTransparencyEnabled.statusString) - } + @objc func reduceTransparencyStatusChanged() { + postNotification(withFeature: .reduceTransparency, statusString: featureStatusesProvider.isReduceTransparencyEnabled.statusString) + } - @objc func videoAutoplayStatusChanged() { - self.postNotification(withFeature: .videoAutoplay, statusString: self.featureStatusesProvider.isVideoAutoplayEnabled.statusString) - } + @objc func videoAutoplayStatusChanged() { + postNotification(withFeature: .videoAutoplay, statusString: featureStatusesProvider.isVideoAutoplayEnabled.statusString) + } #endif #if os(iOS) || os(tvOS) || os(OSX) - @objc func switchControlStatusChanged() { - self.postNotification(withFeature: .switchControl, statusString: self.featureStatusesProvider.isSwitchControlEnabled.statusString) - } + @objc func switchControlStatusChanged() { + postNotification(withFeature: .switchControl, statusString: featureStatusesProvider.isSwitchControlEnabled.statusString) + } #endif #if os(OSX) - @objc func displayOptionsChanged() { - for feature in self.displayOptionStatuses.keys { - let newValue = self.featureStatusesProvider.isFeatureEnabled(feature: feature) - let oldValue = self.displayOptionStatuses[feature] + @objc func displayOptionsChanged() { + for feature in displayOptionStatuses.keys { + let newValue = featureStatusesProvider.isFeatureEnabled(feature: feature) + let oldValue = displayOptionStatuses[feature] - if newValue != oldValue { - self.displayOptionStatuses[feature] = newValue - self.postNotification(withFeature: feature, statusString: newValue.statusString) + if newValue != oldValue { + displayOptionStatuses[feature] = newValue + postNotification(withFeature: feature, statusString: newValue.statusString) + } } } - } #endif @objc func reduceMotionStatusChanged() { - self.postNotification(withFeature: .reduceMotion, statusString: self.featureStatusesProvider.isReduceMotionEnabled.statusString) + postNotification(withFeature: .reduceMotion, statusString: featureStatusesProvider.isReduceMotionEnabled.statusString) } @objc func voiceOverStatusChanged() { - self.postNotification(withFeature: .voiceOver, statusString: self.featureStatusesProvider.isVoiceOverEnabled.statusString) + postNotification(withFeature: .voiceOver, statusString: featureStatusesProvider.isVoiceOverEnabled.statusString) } } diff --git a/Source/Features/Notifications/NotificationsProtocol.swift b/Source/Features/Notifications/NotificationsProtocol.swift index 04284b6..f7bba93 100644 --- a/Source/Features/Notifications/NotificationsProtocol.swift +++ b/Source/Features/Notifications/NotificationsProtocol.swift @@ -5,7 +5,10 @@ // Created by Christoph Wendt on 30.03.18. // +import Foundation + protocol NotificationsProtocol { init(featureStatusesProvider: FeatureStatusesProviderProtocol, targetNotificationCenter: NotificationCenter, systemNotificationCenter: NotificationCenter) + func postNotification(withFeature feature: CapableFeature, statusString: String) } diff --git a/Source/Features/Statuses/FeatureStatuses.swift b/Source/Features/Statuses/FeatureStatuses.swift index 66f3a4b..0d1ca39 100644 --- a/Source/Features/Statuses/FeatureStatuses.swift +++ b/Source/Features/Statuses/FeatureStatuses.swift @@ -6,11 +6,11 @@ // #if os(iOS) -import UIKit + import UIKit #endif #if os(watchOS) -import WatchKit + import WatchKit #endif class FeatureStatuses: StatusesProtocol { @@ -25,29 +25,28 @@ class FeatureStatuses: StatusesProtocol { var statusMap: [String: String] { var statusMap = [String: String]() - for feature in self.features { - + for feature in features { #if os(iOS) - if feature == .hearingDevice { - statusMap[feature.rawValue] = self.featureStatusesProvider.hearingDevicePairedEar.statusString - continue - } - if feature == .largerText { - statusMap[feature.rawValue] = self.featureStatusesProvider.largerTextCatagory.stringValue - continue - } + if feature == .hearingDevice { + statusMap[feature.rawValue] = featureStatusesProvider.hearingDevicePairedEar.statusString + continue + } + if feature == .largerText { + statusMap[feature.rawValue] = featureStatusesProvider.largerTextCatagory.stringValue + continue + } #elseif os(watchOS) - if feature == .largerText { - statusMap[feature.rawValue] = self.featureStatusesProvider.largerTextCatagory - continue - } + if feature == .largerText { + statusMap[feature.rawValue] = featureStatusesProvider.largerTextCatagory + continue + } #endif - statusMap[feature.rawValue] = self.featureStatusesProvider.isFeatureEnabled(feature: feature).statusString + statusMap[feature.rawValue] = featureStatusesProvider.isFeatureEnabled(feature: feature).statusString } return statusMap @@ -55,6 +54,7 @@ class FeatureStatuses: StatusesProtocol { } // MARK: - Equatable + extension FeatureStatuses: Equatable { static func == (lhs: FeatureStatuses, rhs: FeatureStatuses) -> Bool { return diff --git a/Source/Features/Statuses/FeatureStatusesProvider.swift b/Source/Features/Statuses/FeatureStatusesProvider.swift index 13c25c8..5ab4718 100644 --- a/Source/Features/Statuses/FeatureStatusesProvider.swift +++ b/Source/Features/Statuses/FeatureStatusesProvider.swift @@ -6,306 +6,305 @@ // #if os(iOS) || os(tvOS) -import UIKit + import UIKit #endif #if os(OSX) -import AppKit + import AppKit #endif #if os(watchOS) -import WatchKit + import WatchKit #endif class FeatureStatusesProvider: FeatureStatusesProviderProtocol { - #if os(iOS) - var isAssistiveTouchEnabled: Bool { - return UIAccessibility.isAssistiveTouchRunning - } + var isAssistiveTouchEnabled: Bool { + return UIAccessibility.isAssistiveTouchRunning + } - var isDarkerSystemColorsEnabled: Bool { - return UIAccessibility.isDarkerSystemColorsEnabled - } + var isDarkerSystemColorsEnabled: Bool { + return UIAccessibility.isDarkerSystemColorsEnabled + } - var isDifferentiateWithoutColorEnabled: Bool { - if #available(iOS 13.0, *) { - return UIAccessibility.shouldDifferentiateWithoutColor - } else { - Logger.warning("Unable to determine status for isDifferentiateWithoutColorEnabled since it is only available on iOS 13 or later.") - return false + var isDifferentiateWithoutColorEnabled: Bool { + if #available(iOS 13.0, *) { + return UIAccessibility.shouldDifferentiateWithoutColor + } else { + Logger.warning("Unable to determine status for isDifferentiateWithoutColorEnabled since it is only available on iOS 13 or later.") + return false + } } - } - var isGuidedAccessEnabled: Bool { - return UIAccessibility.isGuidedAccessEnabled - } + var isGuidedAccessEnabled: Bool { + return UIAccessibility.isGuidedAccessEnabled + } - var hearingDevicePairedEar: UIAccessibility.HearingDeviceEar { - return UIAccessibility.hearingDevicePairedEar - } + var hearingDevicePairedEar: UIAccessibility.HearingDeviceEar { + return UIAccessibility.hearingDevicePairedEar + } - var largerTextCatagory: UIContentSizeCategory { - return UIScreen.main.traitCollection.preferredContentSizeCategory - } + var largerTextCatagory: UIContentSizeCategory { + return UIScreen.main.traitCollection.preferredContentSizeCategory + } - var isOnOffSwitchLabelsEnabled: Bool { - if #available(iOS 13.0, *) { - return UIAccessibility.isOnOffSwitchLabelsEnabled - } else { - Logger.warning("Unable to determine status for isOnOffSwitchLabelsEnabled since it is only available on iOS 13 or later.") - return false + var isOnOffSwitchLabelsEnabled: Bool { + if #available(iOS 13.0, *) { + return UIAccessibility.isOnOffSwitchLabelsEnabled + } else { + Logger.warning("Unable to determine status for isOnOffSwitchLabelsEnabled since it is only available on iOS 13 or later.") + return false + } } - } - var isShakeToUndoEnabled: Bool { - return UIAccessibility.isShakeToUndoEnabled - } + var isShakeToUndoEnabled: Bool { + return UIAccessibility.isShakeToUndoEnabled + } - var isSpeakScreenEnabled: Bool { - return UIAccessibility.isSpeakScreenEnabled - } + var isSpeakScreenEnabled: Bool { + return UIAccessibility.isSpeakScreenEnabled + } - var isSpeakSelectionEnabled: Bool { - return UIAccessibility.isSpeakSelectionEnabled - } + var isSpeakSelectionEnabled: Bool { + return UIAccessibility.isSpeakSelectionEnabled + } #endif #if os(iOS) || os(tvOS) - var isBoldTextEnabled: Bool { - return UIAccessibility.isBoldTextEnabled - } + var isBoldTextEnabled: Bool { + return UIAccessibility.isBoldTextEnabled + } - var isClosedCaptioningEnabled: Bool { - return UIAccessibility.isClosedCaptioningEnabled - } + var isClosedCaptioningEnabled: Bool { + return UIAccessibility.isClosedCaptioningEnabled + } - var isGrayscaleEnabled: Bool { - return UIAccessibility.isGrayscaleEnabled - } + var isGrayscaleEnabled: Bool { + return UIAccessibility.isGrayscaleEnabled + } - var isInvertColorsEnabled: Bool { - return UIAccessibility.isInvertColorsEnabled - } + var isInvertColorsEnabled: Bool { + return UIAccessibility.isInvertColorsEnabled + } - var isMonoAudioEnabled: Bool { - return UIAccessibility.isMonoAudioEnabled - } + var isMonoAudioEnabled: Bool { + return UIAccessibility.isMonoAudioEnabled + } - var isReduceMotionEnabled: Bool { - return UIAccessibility.isReduceMotionEnabled - } + var isReduceMotionEnabled: Bool { + return UIAccessibility.isReduceMotionEnabled + } - var isReduceTransparencyEnabled: Bool { - return UIAccessibility.isReduceTransparencyEnabled - } + var isReduceTransparencyEnabled: Bool { + return UIAccessibility.isReduceTransparencyEnabled + } - var isSwitchControlEnabled: Bool { - return UIAccessibility.isSwitchControlRunning - } + var isSwitchControlEnabled: Bool { + return UIAccessibility.isSwitchControlRunning + } - var isVideoAutoplayEnabled: Bool { - if #available(iOS 13.0, tvOS 13.0, *) { - return UIAccessibility.isVideoAutoplayEnabled - } else { - Logger.warning("Unable to determine status for isVideoAutoplayEnabled since it is only available on iOS 13 / tvOS 13 or later.") - return false + var isVideoAutoplayEnabled: Bool { + if #available(iOS 13.0, tvOS 13.0, *) { + return UIAccessibility.isVideoAutoplayEnabled + } else { + Logger.warning("Unable to determine status for isVideoAutoplayEnabled since it is only available on iOS 13 / tvOS 13 or later.") + return false + } } - } - var isVoiceOverEnabled: Bool { - return UIAccessibility.isVoiceOverRunning - } + var isVoiceOverEnabled: Bool { + return UIAccessibility.isVoiceOverRunning + } #endif #if os(watchOS) - var isBoldTextEnabled: Bool { - let referenceFont = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.body) - let isBoldText = referenceFont.fontName.localizedCaseInsensitiveContains("bold") - return isBoldText - } + var isBoldTextEnabled: Bool { + let referenceFont = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.body) + let isBoldText = referenceFont.fontName.localizedCaseInsensitiveContains("bold") + return isBoldText + } - var largerTextCatagory: String { - let referenceFontSize = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.body).pointSize - return referenceFontSize.contentSizeString - } + var largerTextCatagory: String { + let referenceFontSize = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.body).pointSize + return referenceFontSize.contentSizeString + } - var isReduceMotionEnabled: Bool { - if #available(watchOS 4.0, *) { - return WKAccessibilityIsReduceMotionEnabled() - } else { - Logger.warning("Unable to determine status for isReduceMotion since it is only available on watchOS 4 or later.") - return false + var isReduceMotionEnabled: Bool { + if #available(watchOS 4.0, *) { + return WKAccessibilityIsReduceMotionEnabled() + } else { + Logger.warning("Unable to determine status for isReduceMotion since it is only available on watchOS 4 or later.") + return false + } } - } - var isVoiceOverEnabled: Bool { - return WKAccessibilityIsVoiceOverRunning() - } + var isVoiceOverEnabled: Bool { + return WKAccessibilityIsVoiceOverRunning() + } #endif #if os(OSX) - var isDifferentiateWithoutColorEnabled: Bool { - return NSWorkspace.shared.accessibilityDisplayShouldDifferentiateWithoutColor - } + var isDifferentiateWithoutColorEnabled: Bool { + return NSWorkspace.shared.accessibilityDisplayShouldDifferentiateWithoutColor + } - var isFullKeyboardAccessEnabled: Bool { - return NSApplication.shared.isFullKeyboardAccessEnabled - } + var isFullKeyboardAccessEnabled: Bool { + return NSApplication.shared.isFullKeyboardAccessEnabled + } - var isIncreaseContrastEnabled: Bool { - return NSWorkspace.shared.accessibilityDisplayShouldIncreaseContrast - } + var isIncreaseContrastEnabled: Bool { + return NSWorkspace.shared.accessibilityDisplayShouldIncreaseContrast + } - var isInvertColorsEnabled: Bool { - return NSWorkspace.shared.accessibilityDisplayShouldInvertColors - } + var isInvertColorsEnabled: Bool { + return NSWorkspace.shared.accessibilityDisplayShouldInvertColors + } - var isReduceMotionEnabled: Bool { - return NSWorkspace.shared.accessibilityDisplayShouldReduceMotion - } + var isReduceMotionEnabled: Bool { + return NSWorkspace.shared.accessibilityDisplayShouldReduceMotion + } - var isReduceTransparencyEnabled: Bool { - return NSWorkspace.shared.accessibilityDisplayShouldReduceTransparency - } + var isReduceTransparencyEnabled: Bool { + return NSWorkspace.shared.accessibilityDisplayShouldReduceTransparency + } - var isSwitchControlEnabled: Bool { - if #available(OSX 10.13, *) { - return NSWorkspace.shared.isSwitchControlEnabled - } else { - Logger.warning("Unable to determine status for switchControl since it is only available on macOS 10.13 or later.") - return false + var isSwitchControlEnabled: Bool { + if #available(OSX 10.13, *) { + return NSWorkspace.shared.isSwitchControlEnabled + } else { + Logger.warning("Unable to determine status for switchControl since it is only available on macOS 10.13 or later.") + return false + } } - } - var isVoiceOverEnabled: Bool { - if #available(OSX 10.13, *) { - return NSWorkspace.shared.isVoiceOverEnabled - } else { - Logger.warning("Unable to determine status for voiceOver since it is only available on macOS 10.13 or later.") - return false + var isVoiceOverEnabled: Bool { + if #available(OSX 10.13, *) { + return NSWorkspace.shared.isVoiceOverEnabled + } else { + Logger.warning("Unable to determine status for voiceOver since it is only available on macOS 10.13 or later.") + return false + } } - } #endif // swiftlint:disable cyclomatic_complexity func isFeatureEnabled(feature: CapableFeature) -> Bool { - #if os(iOS) - if feature == .assistiveTouch { - return self.isAssistiveTouchEnabled - } - if feature == .darkerSystemColors { - return self.isDarkerSystemColorsEnabled - } - if feature == .guidedAccess { - return self.isGuidedAccessEnabled - } - if feature == .hearingDevice { - return self.hearingDevicePairedEar.rawValue != 0 - } - if feature == .largerText { - return !self.largerTextCatagory.isDefault - } - if feature == .onOffSwitchLabels { - return self.isOnOffSwitchLabelsEnabled - } - if feature == .shakeToUndo { - return self.isShakeToUndoEnabled - } - if feature == .speakScreen { - return self.isSpeakScreenEnabled - } - if feature == .speakSelection { - return self.isSpeakSelectionEnabled - } + if feature == .assistiveTouch { + return isAssistiveTouchEnabled + } + if feature == .darkerSystemColors { + return isDarkerSystemColorsEnabled + } + if feature == .guidedAccess { + return isGuidedAccessEnabled + } + if feature == .hearingDevice { + return hearingDevicePairedEar.rawValue != 0 + } + if feature == .largerText { + return !largerTextCatagory.isDefault + } + if feature == .onOffSwitchLabels { + return isOnOffSwitchLabelsEnabled + } + if feature == .shakeToUndo { + return isShakeToUndoEnabled + } + if feature == .speakScreen { + return isSpeakScreenEnabled + } + if feature == .speakSelection { + return isSpeakSelectionEnabled + } #endif #if os(watchOS) - if feature == .largerText { - return !self.largerTextCatagory.isDefaultContentSizeString - } + if feature == .largerText { + return !largerTextCatagory.isDefaultContentSizeString + } #endif #if os(OSX) - if feature == .fullKeyboardAccess { - return self.isFullKeyboardAccessEnabled - } - if feature == .increaseContrast { - return self.isIncreaseContrastEnabled - } + if feature == .fullKeyboardAccess { + return isFullKeyboardAccessEnabled + } + if feature == .increaseContrast { + return isIncreaseContrastEnabled + } #endif #if os(iOS) || os(tvOS) - if feature == .closedCaptioning { - return self.isClosedCaptioningEnabled - } - if feature == .grayscale { - return self.isGrayscaleEnabled - } - if feature == .monoAudio { - return self.isMonoAudioEnabled - } - if feature == .videoAutoplay { - return self.isVideoAutoplayEnabled - } + if feature == .closedCaptioning { + return isClosedCaptioningEnabled + } + if feature == .grayscale { + return isGrayscaleEnabled + } + if feature == .monoAudio { + return isMonoAudioEnabled + } + if feature == .videoAutoplay { + return isVideoAutoplayEnabled + } #endif #if os(iOS) || os(OSX) - if feature == .differentiateWithoutColor { - return self.isDifferentiateWithoutColorEnabled - } + if feature == .differentiateWithoutColor { + return isDifferentiateWithoutColorEnabled + } #endif #if os(iOS) || os(tvOS) || os(OSX) - if feature == .invertColors { - return self.isInvertColorsEnabled - } - if feature == .reduceTransparency { - return self.isReduceTransparencyEnabled - } - if feature == .switchControl { - return self.isSwitchControlEnabled - } + if feature == .invertColors { + return isInvertColorsEnabled + } + if feature == .reduceTransparency { + return isReduceTransparencyEnabled + } + if feature == .switchControl { + return isSwitchControlEnabled + } #endif #if os(iOS) || os(tvOS) || os(watchOS) - if feature == .boldText { - return self.isBoldTextEnabled - } + if feature == .boldText { + return isBoldTextEnabled + } #endif if feature == .reduceMotion { - return self.isReduceMotionEnabled + return isReduceMotionEnabled } if feature == .voiceOver { - return self.isVoiceOverEnabled + return isVoiceOverEnabled } Logger.warning("Feature \(feature) was not handled in isFeatureEnabled. Returning false.") return false } + // swiftlint:enable cyclomatic_complexity } diff --git a/Source/Features/Statuses/FeatureStatusesProviderProtocol.swift b/Source/Features/Statuses/FeatureStatusesProviderProtocol.swift index e5cc1c2..c24bda7 100644 --- a/Source/Features/Statuses/FeatureStatusesProviderProtocol.swift +++ b/Source/Features/Statuses/FeatureStatusesProviderProtocol.swift @@ -6,51 +6,50 @@ // #if os(iOS) -import UIKit + import UIKit #endif protocol FeatureStatusesProviderProtocol { - #if os(iOS) - var isAssistiveTouchEnabled: Bool { get } - var isDarkerSystemColorsEnabled: Bool { get } - var isGuidedAccessEnabled: Bool { get } - var hearingDevicePairedEar: UIAccessibility.HearingDeviceEar { get } - var largerTextCatagory: UIContentSizeCategory { get } - var isOnOffSwitchLabelsEnabled: Bool { get } - var isShakeToUndoEnabled: Bool { get } - var isSpeakScreenEnabled: Bool { get } - var isSpeakSelectionEnabled: Bool { get } + var isAssistiveTouchEnabled: Bool { get } + var isDarkerSystemColorsEnabled: Bool { get } + var isGuidedAccessEnabled: Bool { get } + var hearingDevicePairedEar: UIAccessibility.HearingDeviceEar { get } + var largerTextCatagory: UIContentSizeCategory { get } + var isOnOffSwitchLabelsEnabled: Bool { get } + var isShakeToUndoEnabled: Bool { get } + var isSpeakScreenEnabled: Bool { get } + var isSpeakSelectionEnabled: Bool { get } #endif #if os(iOS) || os(tvOS) - var isClosedCaptioningEnabled: Bool { get } - var isGrayscaleEnabled: Bool { get } - var isMonoAudioEnabled: Bool { get } - var isVideoAutoplayEnabled: Bool { get } + var isClosedCaptioningEnabled: Bool { get } + var isGrayscaleEnabled: Bool { get } + var isMonoAudioEnabled: Bool { get } + var isVideoAutoplayEnabled: Bool { get } #endif #if os(iOS) || os(OSX) - var isDifferentiateWithoutColorEnabled: Bool { get } + var isDifferentiateWithoutColorEnabled: Bool { get } #endif #if os(iOS) || os(tvOS) || os(watchOS) - var isBoldTextEnabled: Bool { get } + var isBoldTextEnabled: Bool { get } #endif #if os(iOS) || os(tvOS) || os(OSX) - var isInvertColorsEnabled: Bool { get } - var isReduceTransparencyEnabled: Bool { get } - var isSwitchControlEnabled: Bool { get } + var isInvertColorsEnabled: Bool { get } + var isReduceTransparencyEnabled: Bool { get } + var isSwitchControlEnabled: Bool { get } #endif #if os(OSX) - var isFullKeyboardAccessEnabled: Bool { get } - var isIncreaseContrastEnabled: Bool { get } + var isFullKeyboardAccessEnabled: Bool { get } + var isIncreaseContrastEnabled: Bool { get } #endif #if os(watchOS) - var largerTextCatagory: String { get } + var largerTextCatagory: String { get } #endif var isReduceMotionEnabled: Bool { get } diff --git a/Source/Features/Statuses/HandicapStatuses.swift b/Source/Features/Statuses/HandicapStatuses.swift index 229c281..95bd698 100644 --- a/Source/Features/Statuses/HandicapStatuses.swift +++ b/Source/Features/Statuses/HandicapStatuses.swift @@ -10,14 +10,14 @@ class HandicapStatuses: HandicapStatusesProtocol { let featureStatusesProvider: FeatureStatusesProviderProtocol init(withHandicaps handicaps: [Handicap], featureStatusesProvider: FeatureStatusesProviderProtocol) { - self.handicapMap = Dictionary(uniqueKeysWithValues: handicaps.map { ($0.name, $0) }) + handicapMap = Dictionary(uniqueKeysWithValues: handicaps.map { ($0.name, $0) }) self.featureStatusesProvider = featureStatusesProvider } var statusMap: [String: String] { var statusMap = [String: String]() for handicapName in handicapMap.keys { - statusMap[handicapName] = self.isHandicapEnabled(handicapName: handicapName).statusString + statusMap[handicapName] = isHandicapEnabled(handicapName: handicapName).statusString } return statusMap @@ -29,7 +29,7 @@ class HandicapStatuses: HandicapStatusesProtocol { } for feature in handicap.features { - let isFeatureEnabled = self.featureStatusesProvider.isFeatureEnabled(feature: feature) + let isFeatureEnabled = featureStatusesProvider.isFeatureEnabled(feature: feature) if isFeatureEnabled, handicap.enabledIf == .oneFeatureEnabled { return true @@ -43,6 +43,7 @@ class HandicapStatuses: HandicapStatusesProtocol { } // MARK: - Equatable + extension HandicapStatuses: Equatable { static func == (lhs: HandicapStatuses, rhs: HandicapStatuses) -> Bool { return diff --git a/Source/Fonts/Extensions/UIFont+ScaledFont.swift b/Source/Fonts/Extensions/UIFont+ScaledFont.swift index a62b1ef..8f66126 100644 --- a/Source/Fonts/Extensions/UIFont+ScaledFont.swift +++ b/Source/Fonts/Extensions/UIFont+ScaledFont.swift @@ -7,79 +7,78 @@ #if os(iOS) || os(tvOS) || os(watchOS) -import UIKit + import UIKit -/// Extension that adds functionality for creating scalable UIFont objects. -extension UIFont { + /// Extension that adds functionality for creating scalable UIFont objects. + extension UIFont { + /** + Makes the given font scalable. - /** - Makes the given font scalable. + - Parameters: + - font: The font to make scalable. - - Parameters: - - font: The font to make scalable. - - - Returns: A scalable font object. - */ - public class func scaledFont(for font: UIFont) -> UIFont { - let fontMetrics = FontMetrics() - return fontMetrics.scaledFont(for: font) - } - - /** - Creates a scalable font with the given font name and reference font size. - - - Parameters: - - fontName: The name of the font that should be used. - - fontSize: The reference font size to use. - - - Returns: A scalable font object. - */ - public class func scaledFont(withName fontName: String, ofSize fontSize: CGFloat) -> UIFont? { - if let font = UIFont(name: fontName, size: fontSize) { + - Returns: A scalable font object. + */ + public class func scaledFont(for font: UIFont) -> UIFont { let fontMetrics = FontMetrics() return fontMetrics.scaledFont(for: font) } - return nil - } - /** - Creates a scalable system font with a given reference font size. + /** + Creates a scalable font with the given font name and reference font size. + + - Parameters: + - fontName: The name of the font that should be used. + - fontSize: The reference font size to use. + + - Returns: A scalable font object. + */ + public class func scaledFont(withName fontName: String, ofSize fontSize: CGFloat) -> UIFont? { + if let font = UIFont(name: fontName, size: fontSize) { + let fontMetrics = FontMetrics() + return fontMetrics.scaledFont(for: font) + } + return nil + } - - Parameters: - - fontSize: The reference font size to use. + /** + Creates a scalable system font with a given reference font size. - - Returns: A scalable font object. - */ - public class func scaledSystemFont(ofSize fontSize: CGFloat) -> UIFont { - let font = UIFont.systemFont(ofSize: fontSize) - return UIFont.scaledFont(for: font) - } + - Parameters: + - fontSize: The reference font size to use. - /** - Creates a scalable bold system font with a given reference font size. + - Returns: A scalable font object. + */ + public class func scaledSystemFont(ofSize fontSize: CGFloat) -> UIFont { + let font = UIFont.systemFont(ofSize: fontSize) + return UIFont.scaledFont(for: font) + } - - Parameters: - - fontSize: The reference font size to use. + /** + Creates a scalable bold system font with a given reference font size. - - Returns: A scalable font object. - */ - public class func scaledBoldSystemFont(ofSize fontSize: CGFloat) -> UIFont { - let font = UIFont.boldSystemFont(ofSize: fontSize) - return UIFont.scaledFont(for: font) - } + - Parameters: + - fontSize: The reference font size to use. - /** - Creates a scalable italic system font with a given reference font size. + - Returns: A scalable font object. + */ + public class func scaledBoldSystemFont(ofSize fontSize: CGFloat) -> UIFont { + let font = UIFont.boldSystemFont(ofSize: fontSize) + return UIFont.scaledFont(for: font) + } + + /** + Creates a scalable italic system font with a given reference font size. - - Parameters: - - fontSize: The reference font size to use. + - Parameters: + - fontSize: The reference font size to use. - - Returns: A scalable font object. - */ - public class func scaledItalicSystemFont(ofSize fontSize: CGFloat) -> UIFont { - let font = UIFont.italicSystemFont(ofSize: fontSize) - return UIFont.scaledFont(for: font) + - Returns: A scalable font object. + */ + public class func scaledItalicSystemFont(ofSize fontSize: CGFloat) -> UIFont { + let font = UIFont.italicSystemFont(ofSize: fontSize) + return UIFont.scaledFont(for: font) + } } -} #endif diff --git a/Source/Fonts/FontMetrics/FontMetrics.swift b/Source/Fonts/FontMetrics/FontMetrics.swift index 822d268..f9f8044 100644 --- a/Source/Fonts/FontMetrics/FontMetrics.swift +++ b/Source/Fonts/FontMetrics/FontMetrics.swift @@ -7,18 +7,18 @@ #if os(iOS) || os(tvOS) || os(watchOS) -import UIKit + import UIKit -class FontMetrics: FontMetricsProtocol { - var fontMetrics: FontMetricsProtocol + class FontMetrics: FontMetricsProtocol { + var fontMetrics: FontMetricsProtocol - init(fontMetricsProvider: FontMetricsProviderProtocol = FontMetricsProvider()) { - self.fontMetrics = fontMetricsProvider.fontMetrics - } + init(fontMetricsProvider: FontMetricsProviderProtocol = FontMetricsProvider()) { + fontMetrics = fontMetricsProvider.fontMetrics + } - func scaledFont(for font: UIFont) -> UIFont { - return self.fontMetrics.scaledFont(for: font) + func scaledFont(for font: UIFont) -> UIFont { + return fontMetrics.scaledFont(for: font) + } } -} #endif diff --git a/Source/Fonts/FontMetrics/FontMetricsProvider.swift b/Source/Fonts/FontMetrics/FontMetricsProvider.swift index fdb25e7..df9dd0e 100644 --- a/Source/Fonts/FontMetrics/FontMetricsProvider.swift +++ b/Source/Fonts/FontMetrics/FontMetricsProvider.swift @@ -7,22 +7,22 @@ #if os(iOS) || os(tvOS) || os(watchOS) -import UIKit + import UIKit -struct FontMetricsProvider: FontMetricsProviderProtocol { - var osVersionProvider: OsVersionProviderProtocol + struct FontMetricsProvider: FontMetricsProviderProtocol { + var osVersionProvider: OsVersionProviderProtocol - init(osVersionProvider: OsVersionProviderProtocol = OsVersionProvider()) { - self.osVersionProvider = osVersionProvider - } - - var fontMetrics: FontMetricsProtocol { - if self.osVersionProvider.isOsVersionWithUIFontMetrics(), #available(iOS 11.0, tvOS 11.0, watchOS 4.0, *) { - return UIFontMetrics.default + init(osVersionProvider: OsVersionProviderProtocol = OsVersionProvider()) { + self.osVersionProvider = osVersionProvider } - return FontMetricsSupport() + var fontMetrics: FontMetricsProtocol { + if osVersionProvider.isOsVersionWithUIFontMetrics(), #available(iOS 11.0, tvOS 11.0, watchOS 4.0, *) { + return UIFontMetrics.default + } + + return FontMetricsSupport() + } } -} #endif diff --git a/Source/Fonts/FontMetrics/FontMetricsSupport.swift b/Source/Fonts/FontMetrics/FontMetricsSupport.swift index b29784d..1d0043b 100644 --- a/Source/Fonts/FontMetrics/FontMetricsSupport.swift +++ b/Source/Fonts/FontMetrics/FontMetricsSupport.swift @@ -7,16 +7,16 @@ #if os(iOS) || os(tvOS) || os(watchOS) -import UIKit + import UIKit -class FontMetricsSupport: FontMetricsProtocol { - private var scaler: CGFloat { - return UIFont.preferredFont(forTextStyle: .body).pointSize / 17.0 - } + class FontMetricsSupport: FontMetricsProtocol { + private var scaler: CGFloat { + return UIFont.preferredFont(forTextStyle: .body).pointSize / 17.0 + } - func scaledFont(for font: UIFont) -> UIFont { - return font.withSize(scaler * font.pointSize) + func scaledFont(for font: UIFont) -> UIFont { + return font.withSize(scaler * font.pointSize) + } } -} #endif diff --git a/Source/Fonts/FontMetrics/Protocols/FontMetricsProtocol.swift b/Source/Fonts/FontMetrics/Protocols/FontMetricsProtocol.swift index 5e86c18..5b8e0a1 100644 --- a/Source/Fonts/FontMetrics/Protocols/FontMetricsProtocol.swift +++ b/Source/Fonts/FontMetrics/Protocols/FontMetricsProtocol.swift @@ -7,13 +7,13 @@ #if os(iOS) || os(tvOS) || os(watchOS) -import UIKit + import UIKit -protocol FontMetricsProtocol { - func scaledFont(for: UIFont) -> UIFont -} + protocol FontMetricsProtocol { + func scaledFont(for: UIFont) -> UIFont + } -@available(iOS 11.0, tvOS 11.0, watchOS 4.0, *) -extension UIFontMetrics: FontMetricsProtocol {} + @available(iOS 11.0, tvOS 11.0, watchOS 4.0, *) + extension UIFontMetrics: FontMetricsProtocol {} #endif diff --git a/Source/Fonts/FontMetrics/Protocols/FontMetricsProviderProtocol.swift b/Source/Fonts/FontMetrics/Protocols/FontMetricsProviderProtocol.swift index bc77bcc..4c70600 100644 --- a/Source/Fonts/FontMetrics/Protocols/FontMetricsProviderProtocol.swift +++ b/Source/Fonts/FontMetrics/Protocols/FontMetricsProviderProtocol.swift @@ -7,8 +7,8 @@ #if os(iOS) || os(tvOS) || os(watchOS) -protocol FontMetricsProviderProtocol { - var fontMetrics: FontMetricsProtocol { get } -} + protocol FontMetricsProviderProtocol { + var fontMetrics: FontMetricsProtocol { get } + } #endif diff --git a/Source/Fonts/FontMetrics/Protocols/OsVersionProviderProtocol.swift b/Source/Fonts/FontMetrics/Protocols/OsVersionProviderProtocol.swift index 9a438e3..a2a03e9 100644 --- a/Source/Fonts/FontMetrics/Protocols/OsVersionProviderProtocol.swift +++ b/Source/Fonts/FontMetrics/Protocols/OsVersionProviderProtocol.swift @@ -7,8 +7,8 @@ #if os(iOS) || os(tvOS) || os(watchOS) -protocol OsVersionProviderProtocol { - func isOsVersionWithUIFontMetrics() -> Bool -} + protocol OsVersionProviderProtocol { + func isOsVersionWithUIFontMetrics() -> Bool + } #endif diff --git a/Source/Fonts/FontMetrics/osVersionProvider.swift b/Source/Fonts/FontMetrics/osVersionProvider.swift index 876df86..6dc08fb 100644 --- a/Source/Fonts/FontMetrics/osVersionProvider.swift +++ b/Source/Fonts/FontMetrics/osVersionProvider.swift @@ -7,14 +7,14 @@ #if os(iOS) || os(tvOS) || os(watchOS) -class OsVersionProvider: OsVersionProviderProtocol { - func isOsVersionWithUIFontMetrics() -> Bool { - if #available(iOS 11.0, tvOS 11.0, watchOS 4.0, *) { - return true - } else { - return false + class OsVersionProvider: OsVersionProviderProtocol { + func isOsVersionWithUIFontMetrics() -> Bool { + if #available(iOS 11.0, tvOS 11.0, watchOS 4.0, *) { + return true + } else { + return false + } } } -} #endif diff --git a/Tests/Colors/Mocks/Image+mock.swift b/Tests/Colors/Mocks/Image+mock.swift deleted file mode 100644 index c2e33dc..0000000 --- a/Tests/Colors/Mocks/Image+mock.swift +++ /dev/null @@ -1,45 +0,0 @@ -// -// Image+mock.swift -// CapableTests -// -// Created by Wendt, Christoph on 29.09.19. -// - -@testable import Capable - -#if os(iOS) || os(tvOS) - -import UIKit - -#endif - -import CoreImage - -extension Image { - class func mock(withColor color: Color, rect: CGRect = CGRect(x: 0, y: 0, width: 1, height: 1)) -> Image { - - #if os(iOS) || os(tvOS) - - UIGraphicsBeginImageContext(rect.size) - let context = UIGraphicsGetCurrentContext() - context!.setFillColor(color.cgColor) - context!.fill(rect) - let image = UIGraphicsGetImageFromCurrentImageContext() - UIGraphicsEndImageContext() - return image! - - #elseif os(OSX) - - let rgbaColor = color.rgbaColor! - let ciColor = CIColor(red: rgbaColor.red, green: rgbaColor.green, blue: rgbaColor.blue, alpha: rgbaColor.alpha) - let ciImage = CIImage(color: ciColor) - let context = CIContext(options: nil) - guard let cgImage = context.createCGImage(ciImage, from: rect) else { - fatalError("Error creating the mock image.") - } - - return Image(cgImage: cgImage, size: rect.size) - - #endif - } -} diff --git a/Tests/Colors/NSFontFontPropsTests.swift b/Tests/Colors/NSFontFontPropsTests.swift deleted file mode 100644 index bcc7927..0000000 --- a/Tests/Colors/NSFontFontPropsTests.swift +++ /dev/null @@ -1,62 +0,0 @@ -// -// NSFontFontPropsTests.swift -// CapableTests -// -// Created by Christoph Wendt on 23.12.18. -// - -#if os(OSX) - -import Quick -import Nimble -@testable import Capable - -class NSFontFontPropsTests: QuickSpec { - override func spec() { - describe("The NSFont class") { - var sut: FontProps? - - context("when initialized with a regular font") { - var testFont: NSFont? - - beforeEach { - testFont = NSFont.systemFont(ofSize: 23.0) - } - - context("when calling fontProps") { - beforeEach { - sut = testFont!.fontProps - } - - it("returns a fontProps instance that holds the correct font size") { - expect(sut!.fontSize).to(equal(testFont?.pointSize)) - } - - it("returns a fontProps instance that has the isBoldFont property set to false") { - expect(sut!.isBoldFont).to(beFalse()) - } - } - } - - context("when initialized with a bold font") { - var testFont: NSFont? - - beforeEach { - testFont = NSFont.boldSystemFont(ofSize: 23.0) - } - - context("when calling fontProps") { - beforeEach { - sut = testFont!.fontProps - } - - it("returns a fontProps instance that has the isBoldFont property set to true") { - expect(sut!.isBoldFont).to(beTrue()) - } - } - } - } - } -} - -#endif diff --git a/Tests/Colors/UIFontFontPropsTests.swift b/Tests/Colors/UIFontFontPropsTests.swift deleted file mode 100644 index 212d12e..0000000 --- a/Tests/Colors/UIFontFontPropsTests.swift +++ /dev/null @@ -1,62 +0,0 @@ -// -// UIFontFontPropsTests.swift -// CapableTests -// -// Created by Christoph Wendt on 03.01.19. -// - -#if os(iOS) || os(tvOS) - -import Quick -import Nimble -@testable import Capable - -class UIFontFontPropsTests: QuickSpec { - override func spec() { - describe("The UIFont class") { - var sut: FontProps? - - context("when initialized with a regular font") { - var testFont: UIFont? - - beforeEach { - testFont = UIFont.systemFont(ofSize: 23.0) - } - - context("when calling fontProps") { - beforeEach { - sut = testFont!.fontProps - } - - it("returns a fontProps instance that holds the correct font size") { - expect(sut!.fontSize).to(equal(testFont?.pointSize)) - } - - it("returns a fontProps instance that has the isBoldFont property set to false") { - expect(sut!.isBoldFont).to(beFalse()) - } - } - } - - context("when initialized with a bold font") { - var testFont: UIFont? - - beforeEach { - testFont = UIFont.boldSystemFont(ofSize: 23.0) - } - - context("when calling fontProps") { - beforeEach { - sut = testFont!.fontProps - } - - it("returns a fontProps instance that has the isBoldFont property set to true") { - expect(sut!.isBoldFont).to(beTrue()) - } - } - } - } - } -} - -#endif diff --git a/Tests/Features/CapablePerfTests.swift b/Tests/Features/CapablePerfTests.swift deleted file mode 100644 index 76892e2..0000000 --- a/Tests/Features/CapablePerfTests.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// CapablePerfTests.swift -// CapableTests -// -// Created by Wendt, Christoph on 16.08.18. -// - -#if os(iOS) || os(tvOS) || os(OSX) - -import XCTest -import Capable - -class CapablePerfTests: XCTestCase { - var sut: Capable? - - override func setUp() { - super.setUp() - sut = Capable(withFeatures: CapableFeature.allCases) - } - - func testStatusMapPerformance() { - measure { - _ = sut!.statusMap - } - } -} - -#endif diff --git a/Tests/Features/CapableTests.swift b/Tests/Features/CapableTests.swift deleted file mode 100644 index 33ca69c..0000000 --- a/Tests/Features/CapableTests.swift +++ /dev/null @@ -1,243 +0,0 @@ -// -// CapableTests.swift -// CapableTests -// -// Created by Christoph Wendt on 23.03.18. -// - -#if os(iOS) || os(tvOS) || os(OSX) - -import Quick -import Nimble -import os.log -@testable import Capable - -class CapableTests: QuickSpec { - override func spec() { - describe("The Capable class") { - var featureStatusesProviderMock: FeatureStatusesProviderMock? - - beforeEach { - featureStatusesProviderMock = FeatureStatusesProviderMock() - } - - context("after initialization with features") { - context("when providing specific features") { - var sut: Capable? - var testedFeatures: [CapableFeature]? - - beforeEach { - testedFeatures = [.reduceMotion, .voiceOver] - sut = Capable(withFeatures: testedFeatures!) - } - - it("creates a Capable instance") { - expect(sut!).to(beAnInstanceOf(Capable.self)) - } - - it("initializes its feature statuses provider correctly") { - expect(sut!.featureStatusesProvider).to(beAnInstanceOf(FeatureStatusesProvider.self)) - } - - it("initializes its statuses module correctly") { - expect(sut!.statusesModule).to(beAnInstanceOf(FeatureStatuses.self)) - // swiftlint:disable force_cast - let featureStatuses = sut!.statusesModule as! FeatureStatuses - // swiftlint:enable force_cast - expect(featureStatuses.features).to(equal(sut!.features)) - expect(featureStatuses.featureStatusesProvider).to(be(sut!.featureStatusesProvider)) - } - - it("initializes its notifications module correctly") { - expect(sut!.notificationsModule).to(beAnInstanceOf(FeatureNotifications.self)) - // swiftlint:disable force_cast - let featureNotifications = sut!.notificationsModule as! FeatureNotifications - // swiftlint:enable force_cast - - expect(featureNotifications.featureStatusesProvider).to(be(sut!.featureStatusesProvider)) - expect(featureNotifications.targetNotificationCenter).to(equal(NotificationCenter.default)) - - #if os(OSX) - expect(featureNotifications.systemNotificationCenter).to(equal(NSWorkspace.shared.notificationCenter)) - #else - expect(featureNotifications.systemNotificationCenter).to(equal(NotificationCenter.default)) - #endif - } - - it("sets the features property correctly") { - expect(sut!.features).to(equal(testedFeatures)) - } - } - - context("when providing no parameters") { - var sut: Capable? - - beforeEach { - sut = Capable() - } - - it("registeres all features") { - expect(sut!.features).to(equal(CapableFeature.allCases)) - } - } - - context("after initialization") { - var sut: Capable? - var testStatuses: FeatureStatusesMock? - - beforeEach { - testStatuses = FeatureStatusesMock() - sut = Capable(withFeatures: [], featureStatusesProvider: featureStatusesProviderMock!, statusesModule: testStatuses!, notificationModule: FeatureNotifications(featureStatusesProvider: featureStatusesProviderMock!)) - } - - context("when calling statusMap") { - beforeEach { - _ = sut!.statusMap - } - - it("requests the status map from the statuses module") { - expect(testStatuses!.didCallStatusMap).to(beTrue()) - } - } - - context("when calling isFeatureEnabled") { - beforeEach { - _ = sut!.isFeatureEnabled(feature: .voiceOver) - } - - it("requests the status map from the statuses module") { - expect(featureStatusesProviderMock!.didCallIsFeatureEnabled).to(beTrue()) - } - } - } - } - - context("after initialization with Handicaps") { - context("when providing a Handicap ") { - var sut: Capable? - var testHandicap: Handicap? - - beforeEach { - testHandicap = Handicap(features: [.voiceOver], name: "TestHandicap", enabledIf: .allFeaturesEnabled) - sut = Capable(withHandicaps: [testHandicap!]) - } - - it("creates a Capable instance") { - expect(sut!).to(beAnInstanceOf(Capable.self)) - } - - it("initializes its feature statuses provider correctly") { - expect(sut!.featureStatusesProvider).to(beAnInstanceOf(FeatureStatusesProvider.self)) - } - - it("initializes its statuses module correctly") { - expect(sut!.statusesModule).to(beAnInstanceOf(HandicapStatuses.self)) - // swiftlint:disable force_cast - let handicapStatuses = sut!.statusesModule as! HandicapStatuses - // swiftlint:enable force_cast - expect(handicapStatuses.featureStatusesProvider).to(be(sut!.featureStatusesProvider)) - } - - it("initializes its notifications module correctly") { - expect(sut!.notificationsModule).to(beAnInstanceOf(HandicapNotifications.self)) - // swiftlint:disable force_cast - let handicapNotifications = sut!.notificationsModule as! HandicapNotifications - // swiftlint:enable force_cast - expect(handicapNotifications.featureStatusesProvider).to(be(sut!.featureStatusesProvider)) - expect(handicapNotifications.targetNotificationCenter).to(equal(NotificationCenter.default)) - - #if os(OSX) - expect(handicapNotifications.systemNotificationCenter).to(equal(NSWorkspace.shared.notificationCenter)) - #else - expect(handicapNotifications.systemNotificationCenter).to(equal(NotificationCenter.default)) - #endif - } - - it("sets the handicaps property correctly") { - expect(sut!.handicaps).to(equal([testHandicap])) - } - } - - context("after initialization") { - var sut: Capable? - var testStatuses: HandicapStatusesMock? - - beforeEach { - testStatuses = HandicapStatusesMock() - sut = Capable(withHandicaps: [], featureStatusesProvider: featureStatusesProviderMock!, statusesModule: testStatuses!, notificationModule: HandicapNotifications(featureStatusesProvider: featureStatusesProviderMock!)) - } - - context("when calling statusMap") { - beforeEach { - _ = sut!.statusMap - } - - it("requests the status map from the statuses module") { - expect(testStatuses!.didCallStatusMap).to(beTrue()) - } - } - - context("when calling isHandicapEnabled") { - beforeEach { - _ = sut!.isHandicapEnabled(handicapName: "TestHandicap") - } - - it("returns false") { - expect(testStatuses!.didCallIsHandicapEnabled).to(beTrue()) - } - } - } - - context("when setting the logType") { - var testLogType: OSLogType? - - beforeEach { - Logger.minLogType = .debug - testLogType = .error - Capable.minLogType = testLogType! - } - - it("sets the logType on the Logger") { - expect(Logger.minLogType).to(equal(testLogType!)) - } - - context("when requesting the logType") { - it("returns the correct value") { - expect(Capable.minLogType).to(equal(testLogType!)) - } - } - } - - context("when setting the onLog closure") { - var testOnLog: ((String, OSLogType) -> Void)? - var testDidCall: Bool = false - - beforeEach { - Logger.onLog = Logger.defaultOnLog - testDidCall = false - testOnLog = { message, logType in - testDidCall = true - } - Capable.onLog = testOnLog! - } - - it("sets the onLog closure on the Logger") { - Logger.onLog("test", .debug) - - expect(testDidCall).to(beTrue()) - } - - context("when requesting the onLog closure") { - it("returns the correct value") { - Capable.onLog("test", .debug) - - expect(testDidCall).to(beTrue()) - } - } - } - } - } - } -} - -#endif diff --git a/Tests/Features/FeatureNotificationsTests.swift b/Tests/Features/FeatureNotificationsTests.swift deleted file mode 100644 index 9163426..0000000 --- a/Tests/Features/FeatureNotificationsTests.swift +++ /dev/null @@ -1,414 +0,0 @@ -// -// FeatureNotificationsTests.swift -// CapableTests -// -// Created by Christoph Wendt on 24.08.18. -// - -#if os(iOS) || os(tvOS) || os(OSX) - -import Quick -import Nimble -@testable import Capable - -class FeatureNotificationsTests: QuickSpec { - override func spec() { - describe("The FeatureNotifications class") { - let featureDidChangeNotification = Notification.Name.CapableFeatureStatusDidChange - var targetNotificationCenterMock: NotificationCenterMock? - var systemNotificationCenterMock: NotificationCenterMock? - var featureStatusesProviderMock: FeatureStatusesProviderMock? - - beforeEach { - targetNotificationCenterMock = NotificationCenterMock() - systemNotificationCenterMock = NotificationCenterMock() - featureStatusesProviderMock = FeatureStatusesProviderMock() - } - - context("after initialization") { - var sut: FeatureNotifications? - var testFeatures: [CapableFeature]? - - beforeEach { - testFeatures = [] - sut = FeatureNotifications(featureStatusesProvider: featureStatusesProviderMock!, features: testFeatures!, targetNotificationCenter: targetNotificationCenterMock!, systemNotificationCenter: systemNotificationCenterMock!) - } - - it("creates a FeatureNotifications intsance") { - expect(sut!).to(beAnInstanceOf(FeatureNotifications.self)) - } - - it("sets properties correctly") { - // swiftlint:disable force_cast - expect((sut!.featureStatusesProvider as! FeatureStatusesProviderMock)).to(be(featureStatusesProviderMock!)) - // swiftlint:enable force_cast - expect((sut!.targetNotificationCenter)).to(equal(targetNotificationCenterMock!)) - expect((sut!.systemNotificationCenter)).to(equal(systemNotificationCenterMock!)) - } - } - - context("after initialization with required initializer") { - var sut: FeatureNotifications? - - beforeEach { - sut = FeatureNotifications(featureStatusesProvider: featureStatusesProviderMock!, targetNotificationCenter: targetNotificationCenterMock!, systemNotificationCenter: systemNotificationCenterMock!) - } - - it("creates a FeatureNotifications intsance") { - expect(sut!).to(beAnInstanceOf(FeatureNotifications.self)) - } - - it("sets statuses property correctly") { - // swiftlint:disable force_cast - expect((sut!.featureStatusesProvider as! FeatureStatusesProviderMock)).to(be(featureStatusesProviderMock!)) - // swiftlint:enable force_cast - expect((sut!.targetNotificationCenter)).to(equal(targetNotificationCenterMock!)) - expect((sut!.systemNotificationCenter)).to(equal(systemNotificationCenterMock!)) - } - } - - #if os(iOS) || os(tvOS) || os(OSX) - - context("after initialization with all features available") { - var sut: FeatureNotifications? - var testFeatures: [CapableFeature]? - - beforeEach { - testFeatures = CapableFeature.allCases - sut = FeatureNotifications(featureStatusesProvider: featureStatusesProviderMock!, features: testFeatures!, targetNotificationCenter: targetNotificationCenterMock!, systemNotificationCenter: systemNotificationCenterMock!) - } - - #if os(iOS) || os(tvOS) - - it("registers itself as observer for feature related notifications") { - expect(systemNotificationCenterMock!.observedNotifications).to(haveCount(testFeatures!.count)) - for feature in testFeatures! { - expect(systemNotificationCenterMock!.hasRegisteredNotification(forFeature: feature)).to(beTrue()) - } - } - - #endif - - #if os(OSX) - - it("registers itself as observer for the display options notification only once") { - expect(systemNotificationCenterMock!.observedNotifications).to(haveCount(1)) - expect(systemNotificationCenterMock!.hasRegisteredNotification(forName: NSWorkspace.accessibilityDisplayOptionsDidChangeNotification)).to(beTrue()) - } - - it("observs key path changes for features not related to display options") { - expect(sut!.keyValueObservations).to(haveCount(2)) - } - - #endif - - #if os(iOS) - - context("when AssistiveTouch was activated by the user") { - beforeEach { - featureStatusesProviderMock!.assistiveTouchEnabled = true - sut!.assistiveTouchStatusChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .assistiveTouch, statusString: "enabled") - } - } - - context("when DarkerSystemColors was activated by the user") { - beforeEach { - featureStatusesProviderMock!.darkerSystemColorsEnabled = true - sut!.darkerSystemColorsStatusChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .darkerSystemColors, statusString: "enabled") - } - } - - context("when DifferentiateWithoutColor was activated by the user") { - beforeEach { - featureStatusesProviderMock!.differentiateWithoutColor = true - sut!.differentiateWithoutColorStatusChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .differentiateWithoutColor, statusString: "enabled") - } - } - - context("when GuidedAccess was activated by the user") { - beforeEach { - featureStatusesProviderMock!.guidedAccessEnabled = true - sut!.guidedAccessStatusChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .guidedAccess, statusString: "enabled") - } - } - - context("when HearingDevice was activated by the user") { - beforeEach { - featureStatusesProviderMock!.hearingDeviceEar = .both - sut!.hearingDeviceStatusChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .hearingDevice, statusString: "both") - } - } - - context("when LargerText was activated by the user") { - var testContentSizeCategory: UIContentSizeCategory? - - beforeEach { - testContentSizeCategory = .accessibilityExtraExtraExtraLarge - featureStatusesProviderMock!.textCatagory = testContentSizeCategory! - sut!.largerTextStatusChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .largerText, statusString: testContentSizeCategory!.stringValue) - } - } - - context("when OnOffSwitchLabels was activated by the user") { - beforeEach { - featureStatusesProviderMock!.onOffSwitchLabelsEnabled = true - sut!.onOffSwitchLabelsStatusChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .onOffSwitchLabels, statusString: "enabled") - } - } - - context("when ShakeToUndo was activated by the user") { - beforeEach { - featureStatusesProviderMock!.shakeToUndoEnabled = true - sut!.shakeToUndoStatusChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .shakeToUndo, statusString: "enabled") - } - } - - context("when SpeakScreen was activated by the user") { - beforeEach { - featureStatusesProviderMock!.speakScreenEnabled = true - sut!.speakScreenStatusChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .speakScreen, statusString: "enabled") - } - } - - context("when SpeackSelection was activated by the user") { - beforeEach { - featureStatusesProviderMock!.speakSelectionEnabled = true - sut!.speakSelectionStatusChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .speakSelection, statusString: "enabled") - } - } - - #endif - - #if os(OSX) - - context("when DifferentiateWithoutColor was activated by the user") { - beforeEach { - featureStatusesProviderMock!.differentiateWithoutColor = true - sut!.displayOptionsChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .differentiateWithoutColor, statusString: "enabled") - } - } - - context("when IncreaseContrast was activated by the user") { - beforeEach { - featureStatusesProviderMock!.increaseContrast = true - sut!.displayOptionsChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .increaseContrast, statusString: "enabled") - } - } - - context("when InvertColors was activated by the user") { - beforeEach { - featureStatusesProviderMock!.invertColorsEnabled = true - sut!.displayOptionsChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .invertColors, statusString: "enabled") - } - } - - context("when ReduceMotion was activated by the user") { - beforeEach { - featureStatusesProviderMock!.reduceMotionEnabled = true - sut!.displayOptionsChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .reduceMotion, statusString: "enabled") - } - } - - context("when ReduceTransparency was activated by the user") { - beforeEach { - featureStatusesProviderMock!.reduceTransparencyEnabled = true - sut!.displayOptionsChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .reduceTransparency, statusString: "enabled") - } - } - - #endif - - #if os(iOS) || os(tvOS) - - context("when BoldText was activated by the user") { - beforeEach { - featureStatusesProviderMock!.boldTextEnabled = true - sut!.boldTextStatusChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .boldText, statusString: "enabled") - } - } - - context("when ClosedCaptioning was activated by the user") { - beforeEach { - featureStatusesProviderMock!.closedCaptioningEnabled = true - sut!.closedCaptioningStatusChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .closedCaptioning, statusString: "enabled") - } - } - - context("when Grayscale was activated by the user") { - beforeEach { - featureStatusesProviderMock!.grayscaleEnabled = true - sut!.grayscaleStatusChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .grayscale, statusString: "enabled") - } - } - - context("when InvertColors was activated by the user") { - beforeEach { - featureStatusesProviderMock!.invertColorsEnabled = true - sut!.invertColorsStatusChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .invertColors, statusString: "enabled") - } - } - - context("when MonoAudio was activated by the user") { - beforeEach { - featureStatusesProviderMock!.monoAudioEnabled = true - sut!.monoAudioStatusChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .monoAudio, statusString: "enabled") - } - } - - context("when ReduceMotion was activated by the user") { - beforeEach { - featureStatusesProviderMock!.reduceMotionEnabled = true - sut!.reduceMotionStatusChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .reduceMotion, statusString: "enabled") - } - } - - context("when ReduceTransparency was activated by the user") { - beforeEach { - featureStatusesProviderMock!.reduceTransparencyEnabled = true - sut!.reduceTransparencyStatusChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .reduceTransparency, statusString: "enabled") - } - } - - context("when VideoAutoplay was activated by the user") { - beforeEach { - featureStatusesProviderMock!.videoAutoplayEnabled = true - sut!.videoAutoplayStatusChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .videoAutoplay, statusString: "enabled") - } - } - - #endif - - context("when SwitchControl was activated by the user") { - beforeEach { - featureStatusesProviderMock!.switchControlEnabled = true - sut!.switchControlStatusChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .switchControl, statusString: "enabled") - } - } - - context("when VoiceOver was activated by the user") { - beforeEach { - featureStatusesProviderMock!.voiceOverEnabled = true - sut!.voiceOverStatusChanged() - } - - it("posts a CapableFeatureStatusDidChange notification with the correct FeatureStatus") { - verifyFeatureDidChangeNotificationWasPosted(withFeature: .voiceOver, statusString: "enabled") - } - } - } - - func verifyFeatureDidChangeNotificationWasPosted(withFeature feature: CapableFeature, statusString: String) { - expect(targetNotificationCenterMock!.postedNotifications).to(haveCount(1)) - - let notificationObject = targetNotificationCenterMock!.postedNotifications[featureDidChangeNotification] - guard let featureStatus = notificationObject as? FeatureStatus else { - fail("Notification does not contain a FeatureStatus object.") - return - } - expect(featureStatus.feature).to(equal(feature)) - expect(featureStatus.statusString).to(equal(statusString)) - } - - #endif - - } - } -} - -#endif diff --git a/Tests/Features/FeatureStatusesProviderTests.swift b/Tests/Features/FeatureStatusesProviderTests.swift deleted file mode 100644 index 2d373e8..0000000 --- a/Tests/Features/FeatureStatusesProviderTests.swift +++ /dev/null @@ -1,265 +0,0 @@ -// -// FeatureStatusesProviderTests.swift -// CapableTests -// -// Created by Wendt, Christoph on 06.10.18. -// - -#if os(iOS) || os(tvOS) || os(OSX) - -import Quick -import Nimble -@testable import Capable - -class FeatureStatusesProviderTests: QuickSpec { - override func spec() { - describe("The FeatureStatusesProvider class") { - var sut: FeatureStatusesProviderMock? - - beforeEach { - sut = FeatureStatusesProviderMock() - } - - context("when calling isFeatureEnabled") { - - #if os(iOS) - - context("for AssistiveTouch") { - beforeEach { - sut!.assistiveTouchEnabled = true - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .assistiveTouch)).to(beTrue()) - } - } - - context("for DarkerSystemColors") { - beforeEach { - sut!.darkerSystemColorsEnabled = true - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .darkerSystemColors)).to(beTrue()) - } - } - - context("for GuidedAccess") { - beforeEach { - sut!.guidedAccessEnabled = true - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .guidedAccess)).to(beTrue()) - } - } - - context("for HearingDevice") { - beforeEach { - sut!.hearingDeviceEar = .both - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .hearingDevice)).to(beTrue()) - } - } - - context("for InvertColors") { - beforeEach { - sut!.invertColorsEnabled = true - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .invertColors)).to(beTrue()) - } - } - - context("for LargerText") { - beforeEach { - sut!.textCatagory = .accessibilityLarge - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .largerText)).to(beTrue()) - } - } - - context("for OnOffSwitchLabels") { - beforeEach { - sut!.onOffSwitchLabelsEnabled = true - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .onOffSwitchLabels)).to(beTrue()) - } - } - - context("for ShakeToUndo") { - beforeEach { - sut!.shakeToUndoEnabled = true - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .shakeToUndo)).to(beTrue()) - } - } - - context("for SpeakScreen") { - beforeEach { - sut!.speakScreenEnabled = true - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .speakScreen)).to(beTrue()) - } - } - - context("for SpeakSelection") { - beforeEach { - sut!.speakSelectionEnabled = true - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .speakSelection)).to(beTrue()) - } - } - - #endif - - #if os(OSX) - - context("for FullKeyboardAccess") { - beforeEach { - sut!.fullKeyboardAccess = true - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .fullKeyboardAccess)).to(beTrue()) - } - } - - context("for IncreaseContrast") { - beforeEach { - sut!.increaseContrast = true - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .increaseContrast)).to(beTrue()) - } - } - - #endif - - #if os(iOS) || os(tvOS) - - context("for BoldText") { - beforeEach { - sut!.boldTextEnabled = true - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .boldText)).to(beTrue()) - } - } - - context("for ClosedCaptioning") { - beforeEach { - sut!.closedCaptioningEnabled = true - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .closedCaptioning)).to(beTrue()) - } - } - - context("for Grayscale") { - beforeEach { - sut!.grayscaleEnabled = true - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .grayscale)).to(beTrue()) - } - } - - context("for MonoAudio") { - beforeEach { - sut!.monoAudioEnabled = true - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .monoAudio)).to(beTrue()) - } - } - - context("for VideoAutoplay") { - beforeEach { - sut!.videoAutoplayEnabled = true - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .videoAutoplay)).to(beTrue()) - } - } - - #endif - - #if os(iOS) || os(OSX) - - context("for DifferentiateWithoutColor") { - beforeEach { - sut!.differentiateWithoutColor = true - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .differentiateWithoutColor)).to(beTrue()) - } - } - - #endif - - context("for ReduceMotion") { - beforeEach { - sut!.reduceMotionEnabled = true - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .reduceMotion)).to(beTrue()) - } - } - - context("for ReduceTransparency") { - beforeEach { - sut!.reduceTransparencyEnabled = true - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .reduceTransparency)).to(beTrue()) - } - } - - context("for SwitchControl") { - beforeEach { - sut!.switchControlEnabled = true - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .switchControl)).to(beTrue()) - } - } - - context("for VoiceOver") { - beforeEach { - sut!.voiceOverEnabled = true - } - - it("returns correct state") { - expect(sut!.isFeatureEnabled(feature: .voiceOver)).to(beTrue()) - } - } - } - } - } -} - -#endif diff --git a/Tests/Features/FeatureStatusesTests.swift b/Tests/Features/FeatureStatusesTests.swift deleted file mode 100644 index 74ead27..0000000 --- a/Tests/Features/FeatureStatusesTests.swift +++ /dev/null @@ -1,115 +0,0 @@ -// -// FeatureStatusesTest.swift -// CapableTests -// -// Created by Christoph Wendt on 05.10.18. -// - -#if os(iOS) || os(tvOS) || os(OSX) - -import Quick -import Nimble -@testable import Capable - -class FeatureStatusesTests: QuickSpec { - override func spec() { - describe("The FeatureStatuses class") { - var featureStatusesProviderMock: FeatureStatusesProviderMock? - - beforeEach { - featureStatusesProviderMock = FeatureStatusesProviderMock() - } - - context("after initialization with all features") { - var sut: FeatureStatuses? - var testFeatures: [CapableFeature]? - - beforeEach { - testFeatures = CapableFeature.allCases - sut = FeatureStatuses(withFeatures: testFeatures!, featureStatusesProvider: featureStatusesProviderMock!) - } - - it("creates a FeatureStatuses instance with all properties set ") { - expect(sut!).to(beAnInstanceOf(FeatureStatuses.self)) - expect(sut!.features).to(equal(testFeatures)) - expect(sut!.featureStatusesProvider).to(be(featureStatusesProviderMock!)) - } - - context("when calling statusMap") { - var statusMap: [String: String]? - - beforeEach { - featureStatusesProviderMock!.enableAllFeatures() - statusMap = sut!.statusMap - } - - it("returns a status map containing all features") { - expect(statusMap!.count).to(equal(testFeatures!.count)) - expect(Array(statusMap!.keys)).to(contain(CapableFeature.keys(forFeatures: testFeatures!))) - } - - it("returns a status map containing the correct statuses") { - for key in statusMap!.keys { - - #if os(iOS) - - if key == CapableFeature.largerText.rawValue { - expect(statusMap![key]).to(equal("Accessibility XXXL")) - } else if key == CapableFeature.hearingDevice.rawValue { - expect(statusMap![key]).to(equal("both")) - } else { - expect(statusMap![key]).to(equal("enabled")) - } - - #else - - expect(statusMap![key]).to(equal("enabled")) - - #endif - } - } - } - } - - context("when checking equality of two instances") { - var featureStatuses1: FeatureStatuses? - var featureStatuses2: FeatureStatuses? - - context("when they are holding different features") { - beforeEach { - featureStatuses1 = FeatureStatuses(withFeatures: [.voiceOver], featureStatusesProvider: FeatureStatusesProvider()) - featureStatuses2 = FeatureStatuses(withFeatures: [.reduceMotion], featureStatusesProvider: FeatureStatusesProvider()) - } - - it("returns false") { - expect(featureStatuses1 == featureStatuses2).to(beFalse()) - } - } - - context("when they use different feature status provider implementations") { - beforeEach { - featureStatuses1 = FeatureStatuses(withFeatures: [.voiceOver], featureStatusesProvider: featureStatusesProviderMock!) - featureStatuses2 = FeatureStatuses(withFeatures: [.voiceOver], featureStatusesProvider: FeatureStatusesProvider()) - } - - it("returns false") { - expect(featureStatuses1 == featureStatuses2).to(beFalse()) - } - } - - context("when they are holding the same features and using the same feature status provider implementation") { - beforeEach { - featureStatuses1 = FeatureStatuses(withFeatures: [.voiceOver], featureStatusesProvider: FeatureStatusesProvider()) - featureStatuses2 = FeatureStatuses(withFeatures: [.voiceOver], featureStatusesProvider: FeatureStatusesProvider()) - } - - it("returns true") { - expect(featureStatuses1 == featureStatuses2).to(beTrue()) - } - } - } - } - } -} - -#endif diff --git a/Tests/Features/HandicapNotificationsTests.swift b/Tests/Features/HandicapNotificationsTests.swift deleted file mode 100644 index 9f6a4aa..0000000 --- a/Tests/Features/HandicapNotificationsTests.swift +++ /dev/null @@ -1,240 +0,0 @@ -// -// HandicapNotificationsTests.swift -// CapableTests -// -// Created by Christoph Wendt on 25.08.18. -// - -#if os(iOS) || os(tvOS) || os(OSX) - -import Quick -import Nimble -@testable import Capable - -class HandicapNotificationsTests: QuickSpec { - override func spec() { - describe("The HandicapNotifications class") { - let handicapDidChangeNotification = Notification.Name.CapableHandicapStatusDidChange - var targetNotificationCenterMock: NotificationCenterMock? - var systemNotificationCenterMock: NotificationCenterMock? - var featureStatusesProviderMock: FeatureStatusesProviderMock? - - beforeEach { - targetNotificationCenterMock = NotificationCenterMock() - systemNotificationCenterMock = NotificationCenterMock() - featureStatusesProviderMock = FeatureStatusesProviderMock() - } - - context("after initialization") { - var sut: HandicapNotifications? - var testStatuses: HandicapStatuses? - var testHandicaps: [Handicap]? - - beforeEach { - let handicap = Handicap(features: [], name: "test", enabledIf: .allFeaturesEnabled) - testHandicaps = [handicap] - testStatuses = HandicapStatuses(withHandicaps: [], featureStatusesProvider: featureStatusesProviderMock!) - sut = HandicapNotifications(statusesModule: testStatuses!, handicaps: testHandicaps!, featureStatusesProvider: featureStatusesProviderMock!, targetNotificationCenter: targetNotificationCenterMock!, systemNotificationCenter: systemNotificationCenterMock!) - } - - it("creates a HandicapNotifications intsance") { - expect(sut!).to(beAnInstanceOf(HandicapNotifications.self)) - } - - it("sets properties correctly") { - // swiftlint:disable force_cast - expect((sut!.statusesModule as! HandicapStatuses)).to(equal(testStatuses!)) - expect((sut!.featureStatusesProvider as! FeatureStatusesProviderMock)).to(be(featureStatusesProviderMock!)) - // swiftlint:enable force_cast - expect((sut!.targetNotificationCenter)).to(equal(targetNotificationCenterMock!)) - expect((sut!.systemNotificationCenter)).to(equal(systemNotificationCenterMock!)) - } - } - - context("after initialization with required initializer") { - var sut: HandicapNotifications? - var testStatuses: HandicapStatuses? - - beforeEach { - testStatuses = HandicapStatuses(withHandicaps: [], featureStatusesProvider: featureStatusesProviderMock!) - sut = HandicapNotifications(statusesModule: testStatuses!, handicaps: [], featureStatusesProvider: featureStatusesProviderMock!, targetNotificationCenter: targetNotificationCenterMock!, systemNotificationCenter: systemNotificationCenterMock!) - } - - it("creates a HandicapNotifications intsance") { - expect(sut!).to(beAnInstanceOf(HandicapNotifications.self)) - } - - it("sets statuses property correctly") { - // swiftlint:disable force_cast - expect((sut!.statusesModule as! HandicapStatuses)).to(equal(testStatuses!)) - expect((sut!.featureStatusesProvider as! FeatureStatusesProviderMock)).to(be(featureStatusesProviderMock!)) - // swiftlint:enable force_cast - expect((sut!.targetNotificationCenter)).to(equal(targetNotificationCenterMock!)) - expect((sut!.systemNotificationCenter)).to(equal(systemNotificationCenterMock!)) - } - } - - context("after initialization with two Handicaps containing the same feature") { - var sut: HandicapNotifications? - var testStatuses: HandicapStatuses? - var testHandicap1: Handicap? - var testHandicap2: Handicap? - var testFeature: CapableFeature? - - beforeEach { - testFeature = .voiceOver - testHandicap1 = Handicap(features: [testFeature!], name: "testHandicap1", enabledIf: .oneFeatureEnabled) - testHandicap2 = Handicap(features: [testFeature!], name: "testHandicap2", enabledIf: .oneFeatureEnabled) - testStatuses = HandicapStatuses(withHandicaps: [testHandicap1!, testHandicap2!], featureStatusesProvider: featureStatusesProviderMock!) - sut = HandicapNotifications(statusesModule: testStatuses!, handicaps: [testHandicap1!, testHandicap2!], featureStatusesProvider: featureStatusesProviderMock!, targetNotificationCenter: targetNotificationCenterMock!, systemNotificationCenter: systemNotificationCenterMock!) - } - - #if os(iOS) || os(tvOS) - - it("registers itself as observer for the feature notification only once") { - expect(systemNotificationCenterMock!.observedNotifications).to(haveCount(1)) - expect(systemNotificationCenterMock!.hasRegisteredNotification(forFeature: testFeature!)).to(beTrue()) - } - - #endif - - #if os(OSX) - - it("registers itself as observer for the display options notification only once") { - expect(systemNotificationCenterMock!.observedNotifications).to(haveCount(1)) - expect(systemNotificationCenterMock!.hasRegisteredNotification(forName: NSWorkspace.accessibilityDisplayOptionsDidChangeNotification)).to(beTrue()) - } - - it("observs key path changes for this feature only once") { - expect(sut!.keyValueObservations).to(haveCount(1)) - } - - #endif - - } - - context("after initialization with a Handicap containing two features") { - var sut: HandicapNotifications? - var testStatuses: HandicapStatuses? - var testHandicap: Handicap? - var testFeature1: CapableFeature? - var testFeature2: CapableFeature? - - beforeEach { - testFeature1 = .voiceOver - testFeature2 = .reduceMotion - } - - context("when .enabledIf is set to .oneFeatureEnabled and both features are currently disabled") { - beforeEach { - testHandicap = Handicap(features: [testFeature1!, testFeature2!], name: "testHandicap", enabledIf: .oneFeatureEnabled) - testStatuses = HandicapStatuses(withHandicaps: [testHandicap!], featureStatusesProvider: featureStatusesProviderMock!) - featureStatusesProviderMock!.voiceOverEnabled = false - featureStatusesProviderMock!.reduceMotionEnabled = false - sut = HandicapNotifications(statusesModule: testStatuses!, handicaps: [testHandicap!], featureStatusesProvider: featureStatusesProviderMock!, targetNotificationCenter: targetNotificationCenterMock!, systemNotificationCenter: systemNotificationCenterMock!) - } - - afterEach { - featureStatusesProviderMock!.voiceOverEnabled = false - featureStatusesProviderMock!.reduceMotionEnabled = false - } - - #if os(iOS) || os(tvOS) - - it("registers itself as observer for both notifications") { - expect(systemNotificationCenterMock!.observedNotifications).to(haveCount(2)) - expect(systemNotificationCenterMock!.hasRegisteredNotification(forFeature: testFeature1!)).to(beTrue()) - expect(systemNotificationCenterMock!.hasRegisteredNotification(forFeature: testFeature2!)).to(beTrue()) - } - - #endif - - #if os(OSX) - - it("registers itself as observer for the display options notification (ReduceMotion)") { - expect(systemNotificationCenterMock!.observedNotifications).to(haveCount(1)) - expect(systemNotificationCenterMock!.hasRegisteredNotification(forName: NSWorkspace.accessibilityDisplayOptionsDidChangeNotification)).to(beTrue()) - } - - it("observs key path changes (VoiceOver) feature") { - expect(sut!.keyValueObservations).to(haveCount(1)) - } - - #endif - - context("when features get enabled one by one") { - it("posts a CapableHandicapStatusDidChange notification with the correct HandicapStatus only if needed") { - // Enable feature 1 => a notification is posted with status "enabled" - featureStatusesProviderMock!.voiceOverEnabled = true - sut!.voiceOverStatusChanged() - verifyHandicapDidChangeNotificationWasPosted(withHandicap: testHandicap!, statusString: "enabled") - - // Enable feature 2 => no notification is posted - featureStatusesProviderMock!.reduceMotionEnabled = true - sut!.reduceMotionStatusChanged() - expect(targetNotificationCenterMock!.postedNotifications).to(haveCount(1)) - - // Disable feature 2 => no notification is posted - featureStatusesProviderMock!.reduceMotionEnabled = false - sut!.reduceMotionStatusChanged() - expect(targetNotificationCenterMock!.postedNotifications).to(haveCount(1)) - - // Disable feature 2 => a notification is posted with status "disabled" - featureStatusesProviderMock!.voiceOverEnabled = false - sut!.voiceOverStatusChanged() - verifyHandicapDidChangeNotificationWasPosted(withHandicap: testHandicap!, statusString: "disabled") - } - } - } - - context("when .enabledIf is set to .allFeaturesEnabled and both features are currently disabled") { - beforeEach { - testHandicap = Handicap(features: [testFeature1!, testFeature2!], name: "testHandicap", enabledIf: .allFeaturesEnabled) - testStatuses = HandicapStatuses(withHandicaps: [testHandicap!], featureStatusesProvider: featureStatusesProviderMock!) - featureStatusesProviderMock!.voiceOverEnabled = false - featureStatusesProviderMock!.reduceMotionEnabled = false - sut = HandicapNotifications(statusesModule: testStatuses!, handicaps: [testHandicap!], featureStatusesProvider: featureStatusesProviderMock!, targetNotificationCenter: targetNotificationCenterMock!, systemNotificationCenter: systemNotificationCenterMock!) - } - - afterEach { - featureStatusesProviderMock!.voiceOverEnabled = false - featureStatusesProviderMock!.reduceMotionEnabled = false - } - - context("when features get enabled one by one") { - it("posts a CapableHandicapStatusDidChange notification with the correct HandicapStatus only if needed") { - // Enable feature 1 => no notification is posted - featureStatusesProviderMock!.voiceOverEnabled = true - sut!.voiceOverStatusChanged() - expect(targetNotificationCenterMock!.postedNotifications).to(haveCount(0)) - - // Enable feature 2 => a notification is posted with status "enabled" - featureStatusesProviderMock!.reduceMotionEnabled = true - sut!.reduceMotionStatusChanged() - verifyHandicapDidChangeNotificationWasPosted(withHandicap: testHandicap!, statusString: "enabled") - - // Disable feature 1 => a notification is posted with status "disabled" - featureStatusesProviderMock!.voiceOverEnabled = false - sut!.voiceOverStatusChanged() - verifyHandicapDidChangeNotificationWasPosted(withHandicap: testHandicap!, statusString: "disabled") - } - } - } - } - - func verifyHandicapDidChangeNotificationWasPosted(withHandicap handicap: Handicap, statusString: String) { - expect(targetNotificationCenterMock!.postedNotifications).to(haveCount(1)) - - let notificationObject = targetNotificationCenterMock!.postedNotifications[handicapDidChangeNotification] - guard let handicapStatus = notificationObject as? HandicapStatus else { - fail("Notification does not contain a HandicapStatus object.") - return - } - expect(handicapStatus.handicap).to(equal(handicap)) - expect(handicapStatus.statusString).to(equal(statusString)) - } - } - } -} - -#endif diff --git a/Tests/Features/HandicapStatusesTests.swift b/Tests/Features/HandicapStatusesTests.swift deleted file mode 100644 index 4660af9..0000000 --- a/Tests/Features/HandicapStatusesTests.swift +++ /dev/null @@ -1,180 +0,0 @@ -// -// HandicapStatusesTests.swift -// CapableTests -// -// Created by Christoph Wendt on 05.10.18. -// - -#if os(iOS) || os(tvOS) || os(OSX) - -import Quick -import Nimble -@testable import Capable - -class HandicapStatusesTests: QuickSpec { - override func spec() { - describe("The HandicapStatuses class") { - var sut: HandicapStatuses? - var featureStatusesProviderMock: FeatureStatusesProviderMock? - - beforeEach { - featureStatusesProviderMock = FeatureStatusesProviderMock() - } - - context("after initialization with multiple handicaps") { - var testHandicap1: Handicap? - var testHandicap2: Handicap? - - beforeEach { - let testFeatures: [CapableFeature] = [.reduceMotion, .voiceOver] - testHandicap1 = Handicap(features: testFeatures, name: "TestHandicap1", enabledIf: .oneFeatureEnabled) - testHandicap2 = Handicap(features: testFeatures, name: "TestHandicap2", enabledIf: .allFeaturesEnabled) - sut = HandicapStatuses(withHandicaps: [testHandicap1!, testHandicap2!], featureStatusesProvider: featureStatusesProviderMock!) - } - - it("creates a HandicapStatuses instance with all properties set ") { - expect(sut!).to(beAnInstanceOf(HandicapStatuses.self)) - expect(sut!.handicapMap.count).to(equal(2)) - expect(Array(sut!.handicapMap.keys)).to(contain([testHandicap1!.name, testHandicap2!.name])) - expect(sut!.handicapMap[testHandicap1!.name]).to(equal(testHandicap1)) - expect(sut!.handicapMap[testHandicap2!.name]).to(equal(testHandicap2)) - expect(sut!.featureStatusesProvider).to(be(featureStatusesProviderMock!)) - } - - context("when calling statusMap") { - var statusMap: [String: String]? - - beforeEach { - featureStatusesProviderMock!.enableAllFeatures() - statusMap = sut!.statusMap - } - - it("returns a status map containing all features") { - expect(statusMap!.count).to(equal(2)) - expect(Array(statusMap!.keys)).to(contain([testHandicap1!.name, testHandicap2!.name])) - } - - it("returns a status map containing the correct statuses") { - for key in statusMap!.keys { - expect(statusMap![key]).to(equal("enabled")) - } - } - } - - context("when calling isHandicapEnabled") { - context("when requested Handicap has not been registered") { - - beforeEach { - featureStatusesProviderMock!.enableAllFeatures() - } - - it("returns false") { - expect(sut!.isHandicapEnabled(handicapName: "notAvailable")).to(beFalse()) - } - } - - context("when enabledIf is set to .allFeaturesEnabled") { - var testHandicap: Handicap? - - beforeEach { - testHandicap = testHandicap2 - } - - context("when all features are enabled") { - beforeEach { - featureStatusesProviderMock!.reduceMotionEnabled = true - featureStatusesProviderMock!.voiceOverEnabled = true - } - - it("returns true") { - expect(sut!.isHandicapEnabled(handicapName: testHandicap!.name)).to(beTrue()) - } - } - - context("when one features is enabled") { - beforeEach { - featureStatusesProviderMock!.reduceMotionEnabled = true - featureStatusesProviderMock!.voiceOverEnabled = false - } - - it("returns false") { - expect(sut!.isHandicapEnabled(handicapName: testHandicap!.name)).to(beFalse()) - } - } - } - - context("when enabledIf is set to .oneFeatureEnabled") { - var testHandicap: Handicap? - - beforeEach { - testHandicap = testHandicap1 - } - - context("when one features are enabled") { - beforeEach { - featureStatusesProviderMock!.reduceMotionEnabled = true - featureStatusesProviderMock!.voiceOverEnabled = false - } - - it("returns true") { - expect(sut!.isHandicapEnabled(handicapName: testHandicap!.name)).to(beTrue()) - } - } - - context("when no features is enabled") { - beforeEach { - featureStatusesProviderMock!.reduceMotionEnabled = false - featureStatusesProviderMock!.voiceOverEnabled = false - } - - it("returns false") { - expect(sut!.isHandicapEnabled(handicapName: testHandicap!.name)).to(beFalse()) - } - } - } - } - } - - #if os(iOS) - - context("after initialization with a Handicap holding the .largerText feature") { - var testHandicapName: String? - - beforeEach { - testHandicapName = "TestHandicap" - let testHandicap = Handicap(features: [.largerText], name: testHandicapName!, enabledIf: .allFeaturesEnabled) - let testTextCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge - featureStatusesProviderMock!.textCatagory = testTextCategory - sut = HandicapStatuses(withHandicaps: [testHandicap], featureStatusesProvider: featureStatusesProviderMock!) - } - - it("returns a status map containing enabled/disabled rather than the actual text category for the Handicap") { - let statusMap = sut!.statusMap - expect(statusMap[testHandicapName!]).to(equal("enabled")) - } - } - - context("after initialization with a Handicap holding the .hearingDevice feature") { - var testHandicapName: String? - - beforeEach { - testHandicapName = "TestHandicap" - let testHandicap = Handicap(features: [.hearingDevice], name: testHandicapName!, enabledIf: .allFeaturesEnabled) - let testHearingDeviceEar: UIAccessibility.HearingDeviceEar = .both - featureStatusesProviderMock!.hearingDeviceEar = testHearingDeviceEar - sut = HandicapStatuses(withHandicaps: [testHandicap], featureStatusesProvider: featureStatusesProviderMock!) - } - - it("returns a status map containing enabled/disabled rather than the actual text category for the Handicap") { - let statusMap = sut!.statusMap - expect(statusMap[testHandicapName!]).to(equal("enabled")) - } - } - - #endif - - } - } -} - -#endif diff --git a/Tests/Features/HandicapTests.swift b/Tests/Features/HandicapTests.swift deleted file mode 100644 index 0f6eff9..0000000 --- a/Tests/Features/HandicapTests.swift +++ /dev/null @@ -1,44 +0,0 @@ -// -// HandicapTests.swift -// CapableTests -// -// Created by Christoph Wendt on 29.10.18. -// - -#if os(iOS) || os(tvOS) || os(OSX) - -import Quick -import Nimble -@testable import Capable - -class HandicapTests: QuickSpec { - override func spec() { - describe("The Handicap class") { - context("after initialization with features") { - var sut: Handicap? - var testFeatures: [CapableFeature]? - var testName: String? - var testMode: HandicapEnabledMode? - - beforeEach { - testName = "TestHandicap" - testFeatures = [.reduceMotion, .voiceOver] - testMode = .allFeaturesEnabled - sut = Handicap(features: testFeatures!, name: testName!, enabledIf: testMode!) - } - - it("returns a Handicap instance") { - expect(sut!).to(beAnInstanceOf(Handicap.self)) - } - - it("sets all properties correctly") { - expect(sut!.features).to(equal(testFeatures)) - expect(sut!.name).to(equal(testName)) - expect(sut!.enabledIf).to(equal(testMode)) - } - } - } - } -} - -#endif diff --git a/Tests/Features/Mocks/FeatureStatusesMock.swift b/Tests/Features/Mocks/FeatureStatusesMock.swift deleted file mode 100644 index 9ddd089..0000000 --- a/Tests/Features/Mocks/FeatureStatusesMock.swift +++ /dev/null @@ -1,29 +0,0 @@ -// -// FeatureStatusesMock.swift -// CapableTests -// -// Created by Christoph Wendt on 05.10.18. -// - -#if os(iOS) || os(tvOS) || os(OSX) - -@testable import Capable - -class FeatureStatusesMock: FeatureStatusesProtocol { - var statusMapMock: [String: String] = [:] - var featureEnabled: Bool = false - var didCallStatusMap: Bool = false - var didCallIsFeatureEnabled: Bool = false - - func isFeatureEnabled(feature: CapableFeature) -> Bool { - didCallIsFeatureEnabled = true - return featureEnabled - } - - var statusMap: [String: String] { - didCallStatusMap = true - return statusMapMock - } -} - -#endif diff --git a/Tests/Features/Mocks/FeatureStatusesProviderMock.swift b/Tests/Features/Mocks/FeatureStatusesProviderMock.swift deleted file mode 100644 index b3cce17..0000000 --- a/Tests/Features/Mocks/FeatureStatusesProviderMock.swift +++ /dev/null @@ -1,210 +0,0 @@ -// -// FeatureStatusesProviderMock.swift -// CapableTests -// -// Created by Wendt, Christoph on 16.08.18. -// - -#if os(iOS) || os(tvOS) || os(OSX) - -@testable import Capable - -#if os(iOS) -import UIKit -#endif - -class FeatureStatusesProviderMock: FeatureStatusesProvider { - var didCallIsFeatureEnabled = false - - #if os(iOS) - var assistiveTouchEnabled = false - var darkerSystemColorsEnabled = false - var guidedAccessEnabled = false - var hearingDeviceEar: UIAccessibility.HearingDeviceEar = UIAccessibility.HearingDeviceEar(rawValue: 0) - var onOffSwitchLabelsEnabled = false - var shakeToUndoEnabled = false - var speakScreenEnabled = false - var speakSelectionEnabled = false - var textCatagory: UIContentSizeCategory = .unspecified - #endif - - #if os(OSX) - var fullKeyboardAccess = false - var increaseContrast = false - #endif - - #if os(iOS) || os(tvOS) - var boldTextEnabled = false - var closedCaptioningEnabled = false - var grayscaleEnabled = false - var monoAudioEnabled = false - var videoAutoplayEnabled = false - #endif - - #if os(iOS) || os(OSX) - var differentiateWithoutColor = false - #endif - - var invertColorsEnabled = false - var reduceMotionEnabled = false - var reduceTransparencyEnabled = false - var switchControlEnabled = false - var voiceOverEnabled = false - - #if os(iOS) - - override var isAssistiveTouchEnabled: Bool { - return self.assistiveTouchEnabled - } - - override var isDarkerSystemColorsEnabled: Bool { - return self.darkerSystemColorsEnabled - } - - override var isGuidedAccessEnabled: Bool { - return self.guidedAccessEnabled - } - - override var hearingDevicePairedEar: UIAccessibility.HearingDeviceEar { - return self.hearingDeviceEar - } - - override var largerTextCatagory: UIContentSizeCategory { - return self.textCatagory - } - - override var isOnOffSwitchLabelsEnabled: Bool { - return self.onOffSwitchLabelsEnabled - } - - override var isShakeToUndoEnabled: Bool { - return self.shakeToUndoEnabled - } - - override var isSpeakScreenEnabled: Bool { - return self.speakScreenEnabled - } - - override var isSpeakSelectionEnabled: Bool { - return self.speakSelectionEnabled - } - - #endif - - #if os(OSX) - - override var isFullKeyboardAccessEnabled: Bool { - return self.fullKeyboardAccess - } - - override var isIncreaseContrastEnabled: Bool { - return self.increaseContrast - } - - #endif - - #if os(iOS) || os(tvOS) - - override var isBoldTextEnabled: Bool { - return self.boldTextEnabled - } - - override var isClosedCaptioningEnabled: Bool { - return self.closedCaptioningEnabled - } - - override var isGrayscaleEnabled: Bool { - return self.grayscaleEnabled - } - - override var isMonoAudioEnabled: Bool { - return self.monoAudioEnabled - } - - override var isVideoAutoplayEnabled: Bool { - return self.videoAutoplayEnabled - } - - #endif - - #if os(iOS) || os(OSX) - - override var isDifferentiateWithoutColorEnabled: Bool { - return self.differentiateWithoutColor - } - - #endif - - override var isInvertColorsEnabled: Bool { - return self.invertColorsEnabled - } - - override var isReduceMotionEnabled: Bool { - return self.reduceMotionEnabled - } - - override var isReduceTransparencyEnabled: Bool { - return self.reduceTransparencyEnabled - } - - override var isSwitchControlEnabled: Bool { - return self.switchControlEnabled - } - - override var isVoiceOverEnabled: Bool { - return self.voiceOverEnabled - } - - func enableAllFeatures() { - - #if os(iOS) - - self.assistiveTouchEnabled = true - self.darkerSystemColorsEnabled = true - self.textCatagory = .accessibilityExtraExtraExtraLarge - self.guidedAccessEnabled = true - self.hearingDeviceEar = .both - self.onOffSwitchLabelsEnabled = true - self.shakeToUndoEnabled = true - self.speakScreenEnabled = true - self.speakSelectionEnabled = true - - #endif - - #if os(OSX) - - self.fullKeyboardAccess = true - self.increaseContrast = true - - #endif - - #if os(iOS) || os(tvOS) - - self.boldTextEnabled = true - self.closedCaptioningEnabled = true - self.grayscaleEnabled = true - self.monoAudioEnabled = true - self.videoAutoplayEnabled = true - - #endif - - #if os(iOS) || os(OSX) - - self.differentiateWithoutColor = true - - #endif - - self.invertColorsEnabled = true - self.reduceMotionEnabled = true - self.reduceTransparencyEnabled = true - self.switchControlEnabled = true - self.voiceOverEnabled = true - } - - override func isFeatureEnabled(feature: CapableFeature) -> Bool { - didCallIsFeatureEnabled = true - return super.isFeatureEnabled(feature: feature) - } -} - -#endif diff --git a/Tests/Features/Mocks/HandicapStatusesMock.swift b/Tests/Features/Mocks/HandicapStatusesMock.swift deleted file mode 100644 index 5564722..0000000 --- a/Tests/Features/Mocks/HandicapStatusesMock.swift +++ /dev/null @@ -1,29 +0,0 @@ -// -// HandicapStatusesMock.swift -// CapableTests -// -// Created by Christoph Wendt on 05.10.18. -// - -#if os(iOS) || os(tvOS) || os(OSX) - -@testable import Capable - -class HandicapStatusesMock: HandicapStatusesProtocol { - var statusMapMock: [String: String] = [:] - var handicapEnabled: Bool = false - var didCallStatusMap: Bool = false - var didCallIsHandicapEnabled: Bool = false - - func isHandicapEnabled(handicapName: String) -> Bool { - didCallIsHandicapEnabled = true - return handicapEnabled - } - - var statusMap: [String: String] { - didCallStatusMap = true - return statusMapMock - } -} - -#endif diff --git a/Tests/Features/Mocks/NotificationCenterMock.swift b/Tests/Features/Mocks/NotificationCenterMock.swift deleted file mode 100644 index 5948023..0000000 --- a/Tests/Features/Mocks/NotificationCenterMock.swift +++ /dev/null @@ -1,68 +0,0 @@ -// -// NotificationCenterMock.swift -// CapableTests -// -// Created by Christoph Wendt on 23.08.18. -// - -#if os(iOS) || os(tvOS) || os(OSX) - -#if os(iOS) || os(tvOS) -import UIKit -#endif - -@testable import Capable - -class NotificationCenterMock: NotificationCenter { - var observedNotifications: [Notification.Name] = [] - var postedNotifications: [Notification.Name: Any?] = [:] - - override func addObserver(_ observer: Any, selector aSelector: Selector, name aName: NSNotification.Name?, object anObject: Any?) { - if let notificationName = aName { - self.observedNotifications.append(notificationName) - } - super.addObserver(observer, selector: aSelector, name: aName, object: anObject) - } - - override func post(name aName: NSNotification.Name, object anObject: Any?) { - self.postedNotifications[aName] = anObject - super.post(name: aName, object: anObject) - } - - func hasRegisteredNotification(forFeature feature: CapableFeature) -> Bool { - #if os(iOS) - if feature == .largerText { - return self.observedNotifications.contains(UIContentSizeCategory.didChangeNotification) - } - #endif - - return self.observedNotifications.contains(where: { - $0.rawValue.range(of: feature.rawValue, options: .caseInsensitive) != nil - }) - } - - func hasRegisteredNotification(forName name: Notification.Name) -> Bool { - return self.observedNotifications.contains(name) - } - - func hasPostedNotification(forFeature feature: CapableFeature) -> Bool { - let notificationNames = Array(self.postedNotifications.keys) - - #if os(iOS) - if feature == .largerText { - return notificationNames.contains(UIContentSizeCategory.didChangeNotification) - } - #endif - - return notificationNames.contains(where: { - $0.rawValue.range(of: feature.rawValue, options: .caseInsensitive) != nil - }) - } - - func hasPostedNotification(forName name: Notification.Name) -> Bool { - let notificationNames = Array(self.postedNotifications.keys) - return notificationNames.contains(name) - } -} - -#endif diff --git a/Tests/Features/NotificationsTests.swift b/Tests/Features/NotificationsTests.swift deleted file mode 100644 index eee50c9..0000000 --- a/Tests/Features/NotificationsTests.swift +++ /dev/null @@ -1,59 +0,0 @@ -// -// NotificationsTests.swift -// CapableTests -// -// Created by Christoph Wendt on 12.09.18. -// - -#if os(iOS) || os(tvOS) || os(OSX) - -import Quick -import Nimble -@testable import Capable - -class NotificationsTests: QuickSpec { - override func spec() { - describe("The Notifications class") { - var targetNotificationCenterMock: NotificationCenterMock? - var systemNotificationCenterMock: NotificationCenterMock? - var featureStatusesProviderMock: FeatureStatusesProviderMock? - - beforeEach { - targetNotificationCenterMock = NotificationCenterMock() - systemNotificationCenterMock = NotificationCenterMock() - featureStatusesProviderMock = FeatureStatusesProviderMock() - } - - context("after initialization") { - var sut: Notifications? - - beforeEach { - sut = Notifications(featureStatusesProvider: featureStatusesProviderMock!, targetNotificationCenter: targetNotificationCenterMock!, systemNotificationCenter: systemNotificationCenterMock!) - } - - it("creates a Notifications intsance") { - expect(sut!).to(beAnInstanceOf(Notifications.self)) - } - - it("sets properties correctly") { - expect(sut!.featureStatusesProvider).to(be(featureStatusesProviderMock!)) - expect((sut!.targetNotificationCenter)).to(equal(targetNotificationCenterMock!)) - expect((sut!.systemNotificationCenter)).to(equal(systemNotificationCenterMock!)) - } - - #if os(iOS) || os(OSX) - - context("when calling postNotification") { - it("throws an error") { - expect(sut!.postNotification(withFeature: .voiceOver, statusString: "enabled")).to(throwAssertion()) - } - } - - #endif - - } - } - } -} - -#endif diff --git a/Tests/Fonts/FontMetricsProviderTests.swift b/Tests/Fonts/FontMetricsProviderTests.swift deleted file mode 100644 index 1a824e6..0000000 --- a/Tests/Fonts/FontMetricsProviderTests.swift +++ /dev/null @@ -1,48 +0,0 @@ -// -// FontMetricsProviderTests.swift -// CapableTests -// -// Created by Wendt, Christoph on 03.08.18. -// - -#if os(iOS) || os(tvOS) - -import Quick -import Nimble -@testable import Capable - -class FontMetricsProviderTests: QuickSpec { - override func spec() { - describe("The FontMetricsProvider") { - var sut: FontMetricsProvider? - - if #available(iOS 11.0, tvOS 11.0, watchOS 4.0, *) { - context("when running on device with OS that comes with UIFontMetrics support") { - beforeEach { - let osVersionProviderMock = OsVersionProviderMock() - osVersionProviderMock.osVersionWithUIFontMetrics = true - sut = FontMetricsProvider(osVersionProvider: osVersionProviderMock) - } - - it("provides the default UIFontMetrics") { - expect((sut!.fontMetrics as? UIFontMetrics)).to(beIdenticalTo(UIFontMetrics.default)) - } - } - } - - context("when running on device with OS without UIFontMetrics support") { - beforeEach { - let osVersionProviderMock = OsVersionProviderMock() - osVersionProviderMock.osVersionWithUIFontMetrics = false - sut = FontMetricsProvider(osVersionProvider: osVersionProviderMock) - } - - it("provides an instance of FontMetricsSupport") { - expect(sut!.fontMetrics).to(beAnInstanceOf(FontMetricsSupport.self)) - } - } - } - } -} - -#endif diff --git a/Tests/Fonts/FontMetricsSupportTests.swift b/Tests/Fonts/FontMetricsSupportTests.swift deleted file mode 100644 index 9f72a44..0000000 --- a/Tests/Fonts/FontMetricsSupportTests.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// FontMetricsSupportTests.swift -// CapableTests -// -// Created by Wendt, Christoph on 03.08.18. -// - -#if os(iOS) || os(tvOS) - -import Quick -import Nimble -@testable import Capable - -class FontMetricsSupportTests: QuickSpec { - override func spec() { - describe("The FontMetricsSupport") { - var sut: FontMetricsSupport? - - context("after initialization") { - beforeEach { - sut = FontMetricsSupport() - } - - it("conforms to UIFontMetricsProtocol") { - expect(sut!).to(beAKindOf(FontMetricsProtocol.self)) - } - - context("scaling a font") { - it("returns a UIFont instance") { - let testFont = UIFont.boldSystemFont(ofSize: 99) - let scaledFont = sut!.scaledFont(for: testFont) - - expect(scaledFont).to(beAKindOf(UIFont.self)) - } - } - } - } - } -} - -#endif diff --git a/Tests/Fonts/FontMetricsTests.swift b/Tests/Fonts/FontMetricsTests.swift deleted file mode 100644 index f5a7cdd..0000000 --- a/Tests/Fonts/FontMetricsTests.swift +++ /dev/null @@ -1,50 +0,0 @@ -// -// FontMetricsTests.swift -// CapableTests -// -// Created by Wendt, Christoph on 03.08.18. -// - -#if os(iOS) || os(tvOS) - -import Quick -import Nimble -@testable import Capable - -class FontMetricsTests: QuickSpec { - override func spec() { - describe("The FontMetrics") { - var testFont: UIFont? - var sut: FontMetrics? - var fontMetricsMock: FontMetricsMock? - - beforeEach { - fontMetricsMock = FontMetricsMock() - testFont = UIFont.boldSystemFont(ofSize: 99) - - let fontMetricsProviderMock = FontMetricsProviderMock(fontMetrics: fontMetricsMock!) - sut = FontMetrics(fontMetricsProvider: fontMetricsProviderMock) - } - - context("after initialization") { - it("has the fontMetrics instance from the provider") { - expect((sut!.fontMetrics as? FontMetricsMock)).to(beIdenticalTo(fontMetricsMock!)) - } - - context("calling scaledFont:for") { - it("calls scaledFont:for on its fontMetrics object") { - _ = sut!.scaledFont(for: testFont!) - expect(fontMetricsMock!.didCallScaledFont).to(beTrue()) - } - - it("calls scaledFont:for with the passed font") { - _ = sut!.scaledFont(for: testFont!) - expect(fontMetricsMock!.scaledFont!).to(equal(testFont!)) - } - } - } - } - } -} - -#endif diff --git a/Tests/Fonts/Mocks/FontMetricsMock.swift b/Tests/Fonts/Mocks/FontMetricsMock.swift deleted file mode 100644 index 93d012e..0000000 --- a/Tests/Fonts/Mocks/FontMetricsMock.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// FontMetricsMock.swift -// CapableTests -// -// Created by Wendt, Christoph on 03.08.18. -// - -#if os(iOS) || os(tvOS) - -import UIKit - -@testable import Capable - -class FontMetricsMock: FontMetricsProtocol { - var didCallScaledFont: Bool = false - var scaledFont: UIFont? - - func scaledFont(for font: UIFont) -> UIFont { - didCallScaledFont = true - scaledFont = font - return font - } -} - -#endif diff --git a/Tests/Fonts/Mocks/FontMetricsProviderMock.swift b/Tests/Fonts/Mocks/FontMetricsProviderMock.swift deleted file mode 100644 index b61581f..0000000 --- a/Tests/Fonts/Mocks/FontMetricsProviderMock.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// FontMetricsProviderMock.swift -// CapableTests -// -// Created by Wendt, Christoph on 03.08.18. -// - -#if os(iOS) || os(tvOS) - -@testable import Capable - -class FontMetricsProviderMock: FontMetricsProviderProtocol { - let fontMetrics: FontMetricsProtocol - - init(fontMetrics: FontMetricsProtocol) { - self.fontMetrics = fontMetrics - } -} - -#endif diff --git a/Tests/Fonts/Mocks/OsVersionProviderMock.swift b/Tests/Fonts/Mocks/OsVersionProviderMock.swift deleted file mode 100644 index a777e64..0000000 --- a/Tests/Fonts/Mocks/OsVersionProviderMock.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// OsVersionProviderMock.swift -// Capable -// -// Created by Christoph Wendt on 30.04.18. -// - -#if os(iOS) || os(tvOS) - -@testable import Capable - -class OsVersionProviderMock: OsVersionProviderProtocol { - var osVersionWithUIFontMetrics = false - - func isOsVersionWithUIFontMetrics() -> Bool { - return self.osVersionWithUIFontMetrics - } -} - -#endif