├── Design └── HexClock.sketch ├── Fastlane └── Fastfile ├── Gemfile ├── Gemfile.lock ├── HexClock.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ └── HexClock.xcscheme ├── HexClock.xcworkspace ├── contents.xcworkspacedata └── xcuserdata │ └── mac.xcuserdatad │ └── UserInterfaceState.xcuserstate ├── HexClock ├── Resources │ ├── Assets.xcassets │ │ ├── App Icon & Top Shelf Image.brandassets │ │ │ ├── App Icon - Large.imagestack │ │ │ │ ├── Back.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ │ ├── Background Large.png │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ │ ├── Contents.json │ │ │ │ ├── Front.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ │ ├── Contents.json │ │ │ │ │ │ └── Foreground Large.png │ │ │ │ │ └── Contents.json │ │ │ │ └── Middle.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ ├── App Icon - Small.imagestack │ │ │ │ ├── Back.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ │ ├── Background.png │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ │ ├── Contents.json │ │ │ │ ├── Front.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ │ ├── Contents.json │ │ │ │ │ │ └── Foreground.png │ │ │ │ │ └── Contents.json │ │ │ │ └── Middle.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── Top Shelf Image Wide.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── Top Shelf Wide.png │ │ │ └── Top Shelf Image.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── Top Shelf.png │ │ ├── Contents.json │ │ └── LaunchImage.launchimage │ │ │ ├── Contents.json │ │ │ └── Launch Image.png │ └── Info.plist └── Source │ ├── Application │ └── AppDelegate.swift │ ├── Extensions │ ├── Date+HMS.swift │ ├── UIColor+FromTime.swift │ └── UIView+AutoLayout.swift │ └── UI │ ├── HexClockView.swift │ └── HexClockViewController.swift ├── LICENSE.md ├── README.md └── Screenshot.png /Design/HexClock.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powermobileweb/Hexclockapp/1115f7f823f1445422f5b4b9495e8c1247c0dc30/Design/HexClock.sketch -------------------------------------------------------------------------------- /Fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | fastlane_require 'dotenv/load' 2 | 3 | fastlane_version "2.23.0" 4 | default_platform :ios 5 | 6 | APP_ID = "me.colindrake.HexClock" 7 | CERTS_REPO = ENV["HEXCLOCK_CERTS_REPO"] 8 | 9 | lane :fetch_dev_cert do 10 | match(app_identifier: APP_ID, platform: "tvos", type: "development", git_url: CERTS_REPO) 11 | end 12 | 13 | lane :fetch_release_cert do 14 | match(app_identifier: APP_ID, platform: "tvos", type: "appstore", git_url: CERTS_REPO) 15 | end 16 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'dotenv' 4 | gem 'fastlane' 5 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (2.3.5) 5 | activesupport (4.2.8) 6 | i18n (~> 0.7) 7 | minitest (~> 5.1) 8 | thread_safe (~> 0.3, >= 0.3.4) 9 | tzinfo (~> 1.1) 10 | addressable (2.5.0) 11 | public_suffix (~> 2.0, >= 2.0.2) 12 | babosa (1.0.2) 13 | claide (1.0.1) 14 | colored (1.2) 15 | commander-fastlane (4.4.4) 16 | highline (~> 1.7.2) 17 | domain_name (0.5.20170223) 18 | unf (>= 0.0.5, < 1.0.0) 19 | dotenv (2.2.0) 20 | excon (0.55.0) 21 | faraday (0.11.0) 22 | multipart-post (>= 1.2, < 3) 23 | faraday-cookie_jar (0.0.6) 24 | faraday (>= 0.7.4) 25 | http-cookie (~> 1.0.0) 26 | faraday_middleware (0.11.0.1) 27 | faraday (>= 0.7.4, < 1.0) 28 | fastimage (2.1.0) 29 | fastlane (2.23.0) 30 | activesupport (< 5) 31 | addressable (>= 2.3, < 3.0.0) 32 | babosa (>= 1.0.2, < 2.0.0) 33 | bundler (>= 1.12.0, < 2.0.0) 34 | colored 35 | commander-fastlane (>= 4.4.0, < 5.0.0) 36 | dotenv (>= 2.1.1, < 3.0.0) 37 | excon (>= 0.45.0, < 1.0.0) 38 | faraday (~> 0.9) 39 | faraday-cookie_jar (~> 0.0.6) 40 | faraday_middleware (~> 0.9) 41 | fastimage (>= 1.6) 42 | gh_inspector (>= 1.0.1, < 2.0.0) 43 | google-api-client (~> 0.9.2) 44 | highline (>= 1.7.2, < 2.0.0) 45 | json (< 3.0.0) 46 | mini_magick (~> 4.5.1) 47 | multi_json 48 | multi_xml (~> 0.5) 49 | multipart-post (~> 2.0.0) 50 | plist (>= 3.1.0, < 4.0.0) 51 | rubyzip (>= 1.1.0, < 2.0.0) 52 | security (= 0.1.3) 53 | slack-notifier (>= 1.3, < 2.0.0) 54 | terminal-notifier (>= 1.6.2, < 2.0.0) 55 | terminal-table (>= 1.4.5, < 2.0.0) 56 | tty-screen (~> 0.5.0) 57 | word_wrap (~> 1.0.0) 58 | xcodeproj (>= 0.20, < 2.0.0) 59 | xcpretty (>= 0.2.4, < 1.0.0) 60 | xcpretty-travis-formatter (>= 0.0.3) 61 | gh_inspector (1.0.3) 62 | google-api-client (0.9.28) 63 | addressable (~> 2.3) 64 | googleauth (~> 0.5) 65 | httpclient (~> 2.7) 66 | hurley (~> 0.1) 67 | memoist (~> 0.11) 68 | mime-types (>= 1.6) 69 | representable (~> 2.3.0) 70 | retriable (~> 2.0) 71 | googleauth (0.5.1) 72 | faraday (~> 0.9) 73 | jwt (~> 1.4) 74 | logging (~> 2.0) 75 | memoist (~> 0.12) 76 | multi_json (~> 1.11) 77 | os (~> 0.9) 78 | signet (~> 0.7) 79 | highline (1.7.8) 80 | http-cookie (1.0.3) 81 | domain_name (~> 0.5) 82 | httpclient (2.8.3) 83 | hurley (0.2) 84 | i18n (0.8.1) 85 | json (2.0.3) 86 | jwt (1.5.6) 87 | little-plugger (1.1.4) 88 | logging (2.2.0) 89 | little-plugger (~> 1.1) 90 | multi_json (~> 1.10) 91 | memoist (0.15.0) 92 | mime-types (3.1) 93 | mime-types-data (~> 3.2015) 94 | mime-types-data (3.2016.0521) 95 | mini_magick (4.5.1) 96 | minitest (5.10.1) 97 | multi_json (1.12.1) 98 | multi_xml (0.6.0) 99 | multipart-post (2.0.0) 100 | nanaimo (0.2.3) 101 | os (0.9.6) 102 | plist (3.2.0) 103 | public_suffix (2.0.5) 104 | representable (2.3.0) 105 | uber (~> 0.0.7) 106 | retriable (2.1.0) 107 | rouge (1.11.1) 108 | rubyzip (1.2.1) 109 | security (0.1.3) 110 | signet (0.7.3) 111 | addressable (~> 2.3) 112 | faraday (~> 0.9) 113 | jwt (~> 1.5) 114 | multi_json (~> 1.10) 115 | slack-notifier (1.5.1) 116 | terminal-notifier (1.7.1) 117 | terminal-table (1.7.3) 118 | unicode-display_width (~> 1.1.1) 119 | thread_safe (0.3.6) 120 | tty-screen (0.5.0) 121 | tzinfo (1.2.3) 122 | thread_safe (~> 0.1) 123 | uber (0.0.15) 124 | unf (0.1.4) 125 | unf_ext 126 | unf_ext (0.0.7.2) 127 | unicode-display_width (1.1.3) 128 | word_wrap (1.0.0) 129 | xcodeproj (1.4.2) 130 | CFPropertyList (~> 2.3.3) 131 | activesupport (>= 3) 132 | claide (>= 1.0.1, < 2.0) 133 | colored (~> 1.2) 134 | nanaimo (~> 0.2.3) 135 | xcpretty (0.2.4) 136 | rouge (~> 1.8) 137 | xcpretty-travis-formatter (0.0.4) 138 | xcpretty (~> 0.2, >= 0.0.7) 139 | 140 | PLATFORMS 141 | ruby 142 | 143 | DEPENDENCIES 144 | dotenv 145 | fastlane 146 | 147 | BUNDLED WITH 148 | 1.12.5 149 | -------------------------------------------------------------------------------- /HexClock.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 3B056C681E886EAD0045E50D /* HexClockView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B056C671E886EAD0045E50D /* HexClockView.swift */; }; 11 | 3B056C6A1E88853D0045E50D /* UIView+AutoLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B056C691E88853D0045E50D /* UIView+AutoLayout.swift */; }; 12 | 3B056C6C1E8885C70045E50D /* UIColor+FromTime.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B056C6B1E8885C70045E50D /* UIColor+FromTime.swift */; }; 13 | 3B056C6E1E88AD9F0045E50D /* Date+HMS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B056C6D1E88AD9F0045E50D /* Date+HMS.swift */; }; 14 | 3B9D51511E302D96005B0F02 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B9D51501E302D96005B0F02 /* AppDelegate.swift */; }; 15 | 3B9D51531E302D96005B0F02 /* HexClockViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B9D51521E302D96005B0F02 /* HexClockViewController.swift */; }; 16 | 3B9D51581E302D96005B0F02 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3B9D51571E302D96005B0F02 /* Assets.xcassets */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | 3B056C671E886EAD0045E50D /* HexClockView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HexClockView.swift; sourceTree = ""; }; 21 | 3B056C691E88853D0045E50D /* UIView+AutoLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+AutoLayout.swift"; sourceTree = ""; }; 22 | 3B056C6B1E8885C70045E50D /* UIColor+FromTime.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+FromTime.swift"; sourceTree = ""; }; 23 | 3B056C6D1E88AD9F0045E50D /* Date+HMS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+HMS.swift"; sourceTree = ""; }; 24 | 3B9D514D1E302D96005B0F02 /* HexClock.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HexClock.app; sourceTree = BUILT_PRODUCTS_DIR; }; 25 | 3B9D51501E302D96005B0F02 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 26 | 3B9D51521E302D96005B0F02 /* HexClockViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HexClockViewController.swift; sourceTree = ""; }; 27 | 3B9D51571E302D96005B0F02 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 28 | 3B9D51591E302D96005B0F02 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 29 | /* End PBXFileReference section */ 30 | 31 | /* Begin PBXFrameworksBuildPhase section */ 32 | 3B9D514A1E302D96005B0F02 /* Frameworks */ = { 33 | isa = PBXFrameworksBuildPhase; 34 | buildActionMask = 2147483647; 35 | files = ( 36 | ); 37 | runOnlyForDeploymentPostprocessing = 0; 38 | }; 39 | /* End PBXFrameworksBuildPhase section */ 40 | 41 | /* Begin PBXGroup section */ 42 | 3B056C6F1E88AF930045E50D /* Extensions */ = { 43 | isa = PBXGroup; 44 | children = ( 45 | 3B056C6D1E88AD9F0045E50D /* Date+HMS.swift */, 46 | 3B056C6B1E8885C70045E50D /* UIColor+FromTime.swift */, 47 | 3B056C691E88853D0045E50D /* UIView+AutoLayout.swift */, 48 | ); 49 | path = Extensions; 50 | sourceTree = ""; 51 | }; 52 | 3B056C701E88AF9C0045E50D /* Application */ = { 53 | isa = PBXGroup; 54 | children = ( 55 | 3B9D51501E302D96005B0F02 /* AppDelegate.swift */, 56 | ); 57 | path = Application; 58 | sourceTree = ""; 59 | }; 60 | 3B056C711E88AFA00045E50D /* UI */ = { 61 | isa = PBXGroup; 62 | children = ( 63 | 3B056C671E886EAD0045E50D /* HexClockView.swift */, 64 | 3B9D51521E302D96005B0F02 /* HexClockViewController.swift */, 65 | ); 66 | path = UI; 67 | sourceTree = ""; 68 | }; 69 | 3B4CB91C1E870CE200D70CD9 /* Source */ = { 70 | isa = PBXGroup; 71 | children = ( 72 | 3B056C701E88AF9C0045E50D /* Application */, 73 | 3B056C6F1E88AF930045E50D /* Extensions */, 74 | 3B056C711E88AFA00045E50D /* UI */, 75 | ); 76 | path = Source; 77 | sourceTree = ""; 78 | }; 79 | 3B4CB91D1E870CE700D70CD9 /* Resources */ = { 80 | isa = PBXGroup; 81 | children = ( 82 | 3B9D51571E302D96005B0F02 /* Assets.xcassets */, 83 | 3B9D51591E302D96005B0F02 /* Info.plist */, 84 | ); 85 | path = Resources; 86 | sourceTree = ""; 87 | }; 88 | 3B9D51441E302D96005B0F02 = { 89 | isa = PBXGroup; 90 | children = ( 91 | 3B9D514F1E302D96005B0F02 /* HexClock */, 92 | 3B9D514E1E302D96005B0F02 /* Products */, 93 | ); 94 | sourceTree = ""; 95 | }; 96 | 3B9D514E1E302D96005B0F02 /* Products */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | 3B9D514D1E302D96005B0F02 /* HexClock.app */, 100 | ); 101 | name = Products; 102 | sourceTree = ""; 103 | }; 104 | 3B9D514F1E302D96005B0F02 /* HexClock */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 3B4CB91D1E870CE700D70CD9 /* Resources */, 108 | 3B4CB91C1E870CE200D70CD9 /* Source */, 109 | ); 110 | path = HexClock; 111 | sourceTree = ""; 112 | }; 113 | /* End PBXGroup section */ 114 | 115 | /* Begin PBXNativeTarget section */ 116 | 3B9D514C1E302D96005B0F02 /* HexClock */ = { 117 | isa = PBXNativeTarget; 118 | buildConfigurationList = 3B9D515C1E302D96005B0F02 /* Build configuration list for PBXNativeTarget "HexClock" */; 119 | buildPhases = ( 120 | 3B9D51491E302D96005B0F02 /* Sources */, 121 | 3B9D514A1E302D96005B0F02 /* Frameworks */, 122 | 3B9D514B1E302D96005B0F02 /* Resources */, 123 | ); 124 | buildRules = ( 125 | ); 126 | dependencies = ( 127 | ); 128 | name = HexClock; 129 | productName = HexClock; 130 | productReference = 3B9D514D1E302D96005B0F02 /* HexClock.app */; 131 | productType = "com.apple.product-type.application"; 132 | }; 133 | /* End PBXNativeTarget section */ 134 | 135 | /* Begin PBXProject section */ 136 | 3B9D51451E302D96005B0F02 /* Project object */ = { 137 | isa = PBXProject; 138 | attributes = { 139 | LastSwiftUpdateCheck = 0820; 140 | LastUpgradeCheck = 0820; 141 | ORGANIZATIONNAME = ""; 142 | TargetAttributes = { 143 | 3B9D514C1E302D96005B0F02 = { 144 | CreatedOnToolsVersion = 8.2.1; 145 | DevelopmentTeam = D225BPT86F; 146 | ProvisioningStyle = Manual; 147 | }; 148 | }; 149 | }; 150 | buildConfigurationList = 3B9D51481E302D96005B0F02 /* Build configuration list for PBXProject "HexClock" */; 151 | compatibilityVersion = "Xcode 3.2"; 152 | developmentRegion = English; 153 | hasScannedForEncodings = 0; 154 | knownRegions = ( 155 | en, 156 | Base, 157 | ); 158 | mainGroup = 3B9D51441E302D96005B0F02; 159 | productRefGroup = 3B9D514E1E302D96005B0F02 /* Products */; 160 | projectDirPath = ""; 161 | projectRoot = ""; 162 | targets = ( 163 | 3B9D514C1E302D96005B0F02 /* HexClock */, 164 | ); 165 | }; 166 | /* End PBXProject section */ 167 | 168 | /* Begin PBXResourcesBuildPhase section */ 169 | 3B9D514B1E302D96005B0F02 /* Resources */ = { 170 | isa = PBXResourcesBuildPhase; 171 | buildActionMask = 2147483647; 172 | files = ( 173 | 3B9D51581E302D96005B0F02 /* Assets.xcassets in Resources */, 174 | ); 175 | runOnlyForDeploymentPostprocessing = 0; 176 | }; 177 | /* End PBXResourcesBuildPhase section */ 178 | 179 | /* Begin PBXSourcesBuildPhase section */ 180 | 3B9D51491E302D96005B0F02 /* Sources */ = { 181 | isa = PBXSourcesBuildPhase; 182 | buildActionMask = 2147483647; 183 | files = ( 184 | 3B056C6E1E88AD9F0045E50D /* Date+HMS.swift in Sources */, 185 | 3B056C6C1E8885C70045E50D /* UIColor+FromTime.swift in Sources */, 186 | 3B9D51531E302D96005B0F02 /* HexClockViewController.swift in Sources */, 187 | 3B056C6A1E88853D0045E50D /* UIView+AutoLayout.swift in Sources */, 188 | 3B056C681E886EAD0045E50D /* HexClockView.swift in Sources */, 189 | 3B9D51511E302D96005B0F02 /* AppDelegate.swift in Sources */, 190 | ); 191 | runOnlyForDeploymentPostprocessing = 0; 192 | }; 193 | /* End PBXSourcesBuildPhase section */ 194 | 195 | /* Begin XCBuildConfiguration section */ 196 | 3B9D515A1E302D96005B0F02 /* Debug */ = { 197 | isa = XCBuildConfiguration; 198 | buildSettings = { 199 | ALWAYS_SEARCH_USER_PATHS = NO; 200 | CLANG_ANALYZER_NONNULL = YES; 201 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 202 | CLANG_CXX_LIBRARY = "libc++"; 203 | CLANG_ENABLE_MODULES = YES; 204 | CLANG_ENABLE_OBJC_ARC = YES; 205 | CLANG_WARN_BOOL_CONVERSION = YES; 206 | CLANG_WARN_CONSTANT_CONVERSION = YES; 207 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 208 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 209 | CLANG_WARN_EMPTY_BODY = YES; 210 | CLANG_WARN_ENUM_CONVERSION = YES; 211 | CLANG_WARN_INFINITE_RECURSION = YES; 212 | CLANG_WARN_INT_CONVERSION = YES; 213 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 214 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 215 | CLANG_WARN_UNREACHABLE_CODE = YES; 216 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 217 | COPY_PHASE_STRIP = NO; 218 | DEBUG_INFORMATION_FORMAT = dwarf; 219 | ENABLE_STRICT_OBJC_MSGSEND = YES; 220 | ENABLE_TESTABILITY = YES; 221 | GCC_C_LANGUAGE_STANDARD = gnu99; 222 | GCC_DYNAMIC_NO_PIC = NO; 223 | GCC_NO_COMMON_BLOCKS = YES; 224 | GCC_OPTIMIZATION_LEVEL = 0; 225 | GCC_PREPROCESSOR_DEFINITIONS = ( 226 | "DEBUG=1", 227 | "$(inherited)", 228 | ); 229 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 230 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 231 | GCC_WARN_UNDECLARED_SELECTOR = YES; 232 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 233 | GCC_WARN_UNUSED_FUNCTION = YES; 234 | GCC_WARN_UNUSED_VARIABLE = YES; 235 | MTL_ENABLE_DEBUG_INFO = YES; 236 | ONLY_ACTIVE_ARCH = YES; 237 | SDKROOT = appletvos; 238 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 239 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 240 | TARGETED_DEVICE_FAMILY = 3; 241 | TVOS_DEPLOYMENT_TARGET = 10.1; 242 | }; 243 | name = Debug; 244 | }; 245 | 3B9D515B1E302D96005B0F02 /* Release */ = { 246 | isa = XCBuildConfiguration; 247 | buildSettings = { 248 | ALWAYS_SEARCH_USER_PATHS = NO; 249 | CLANG_ANALYZER_NONNULL = YES; 250 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 251 | CLANG_CXX_LIBRARY = "libc++"; 252 | CLANG_ENABLE_MODULES = YES; 253 | CLANG_ENABLE_OBJC_ARC = YES; 254 | CLANG_WARN_BOOL_CONVERSION = YES; 255 | CLANG_WARN_CONSTANT_CONVERSION = YES; 256 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 257 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 258 | CLANG_WARN_EMPTY_BODY = YES; 259 | CLANG_WARN_ENUM_CONVERSION = YES; 260 | CLANG_WARN_INFINITE_RECURSION = YES; 261 | CLANG_WARN_INT_CONVERSION = YES; 262 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 263 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 264 | CLANG_WARN_UNREACHABLE_CODE = YES; 265 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 266 | COPY_PHASE_STRIP = NO; 267 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 268 | ENABLE_NS_ASSERTIONS = NO; 269 | ENABLE_STRICT_OBJC_MSGSEND = YES; 270 | GCC_C_LANGUAGE_STANDARD = gnu99; 271 | GCC_NO_COMMON_BLOCKS = YES; 272 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 273 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 274 | GCC_WARN_UNDECLARED_SELECTOR = YES; 275 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 276 | GCC_WARN_UNUSED_FUNCTION = YES; 277 | GCC_WARN_UNUSED_VARIABLE = YES; 278 | MTL_ENABLE_DEBUG_INFO = NO; 279 | SDKROOT = appletvos; 280 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 281 | TARGETED_DEVICE_FAMILY = 3; 282 | TVOS_DEPLOYMENT_TARGET = 10.1; 283 | VALIDATE_PRODUCT = YES; 284 | }; 285 | name = Release; 286 | }; 287 | 3B9D515D1E302D96005B0F02 /* Debug */ = { 288 | isa = XCBuildConfiguration; 289 | buildSettings = { 290 | ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; 291 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 292 | DEVELOPMENT_TEAM = D225BPT86F; 293 | INFOPLIST_FILE = HexClock/Resources/Info.plist; 294 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 295 | PRODUCT_BUNDLE_IDENTIFIER = me.colindrake.HexClock; 296 | PRODUCT_NAME = "$(TARGET_NAME)"; 297 | PROVISIONING_PROFILE_SPECIFIER = "match Development me.colindrake.HexClock tvos"; 298 | SWIFT_VERSION = 3.0; 299 | }; 300 | name = Debug; 301 | }; 302 | 3B9D515E1E302D96005B0F02 /* Release */ = { 303 | isa = XCBuildConfiguration; 304 | buildSettings = { 305 | ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; 306 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 307 | CODE_SIGN_IDENTITY = "iPhone Distribution"; 308 | DEVELOPMENT_TEAM = D225BPT86F; 309 | INFOPLIST_FILE = HexClock/Resources/Info.plist; 310 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 311 | PRODUCT_BUNDLE_IDENTIFIER = me.colindrake.HexClock; 312 | PRODUCT_NAME = "$(TARGET_NAME)"; 313 | PROVISIONING_PROFILE_SPECIFIER = "match AppStore me.colindrake.HexClock tvos"; 314 | SWIFT_VERSION = 3.0; 315 | }; 316 | name = Release; 317 | }; 318 | /* End XCBuildConfiguration section */ 319 | 320 | /* Begin XCConfigurationList section */ 321 | 3B9D51481E302D96005B0F02 /* Build configuration list for PBXProject "HexClock" */ = { 322 | isa = XCConfigurationList; 323 | buildConfigurations = ( 324 | 3B9D515A1E302D96005B0F02 /* Debug */, 325 | 3B9D515B1E302D96005B0F02 /* Release */, 326 | ); 327 | defaultConfigurationIsVisible = 0; 328 | defaultConfigurationName = Release; 329 | }; 330 | 3B9D515C1E302D96005B0F02 /* Build configuration list for PBXNativeTarget "HexClock" */ = { 331 | isa = XCConfigurationList; 332 | buildConfigurations = ( 333 | 3B9D515D1E302D96005B0F02 /* Debug */, 334 | 3B9D515E1E302D96005B0F02 /* Release */, 335 | ); 336 | defaultConfigurationIsVisible = 0; 337 | defaultConfigurationName = Release; 338 | }; 339 | /* End XCConfigurationList section */ 340 | }; 341 | rootObject = 3B9D51451E302D96005B0F02 /* Project object */; 342 | } 343 | -------------------------------------------------------------------------------- /HexClock.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /HexClock.xcodeproj/xcshareddata/xcschemes/HexClock.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /HexClock.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /HexClock.xcworkspace/xcuserdata/mac.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powermobileweb/Hexclockapp/1115f7f823f1445422f5b4b9495e8c1247c0dc30/HexClock.xcworkspace/xcuserdata/mac.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Background Large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powermobileweb/Hexclockapp/1115f7f823f1445422f5b4b9495e8c1247c0dc30/HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Background Large.png -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "filename" : "Background Large.png", 6 | "scale" : "1x" 7 | } 8 | ], 9 | "info" : { 10 | "version" : 1, 11 | "author" : "xcode" 12 | } 13 | } -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers" : [ 3 | { 4 | "filename" : "Front.imagestacklayer" 5 | }, 6 | { 7 | "filename" : "Middle.imagestacklayer" 8 | }, 9 | { 10 | "filename" : "Back.imagestacklayer" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "filename" : "Foreground Large.png", 6 | "scale" : "1x" 7 | } 8 | ], 9 | "info" : { 10 | "version" : 1, 11 | "author" : "xcode" 12 | } 13 | } -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Content.imageset/Foreground Large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powermobileweb/Hexclockapp/1115f7f823f1445422f5b4b9495e8c1247c0dc30/HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Content.imageset/Foreground Large.png -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powermobileweb/Hexclockapp/1115f7f823f1445422f5b4b9495e8c1247c0dc30/HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Background.png -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "filename" : "Background.png", 6 | "scale" : "1x" 7 | } 8 | ], 9 | "info" : { 10 | "version" : 1, 11 | "author" : "xcode" 12 | } 13 | } -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers" : [ 3 | { 4 | "filename" : "Front.imagestacklayer" 5 | }, 6 | { 7 | "filename" : "Middle.imagestacklayer" 8 | }, 9 | { 10 | "filename" : "Back.imagestacklayer" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "filename" : "Foreground.png", 6 | "scale" : "1x" 7 | } 8 | ], 9 | "info" : { 10 | "version" : 1, 11 | "author" : "xcode" 12 | } 13 | } -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Content.imageset/Foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powermobileweb/Hexclockapp/1115f7f823f1445422f5b4b9495e8c1247c0dc30/HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Content.imageset/Foreground.png -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "assets" : [ 3 | { 4 | "size" : "1280x768", 5 | "idiom" : "tv", 6 | "filename" : "App Icon - Large.imagestack", 7 | "role" : "primary-app-icon" 8 | }, 9 | { 10 | "size" : "400x240", 11 | "idiom" : "tv", 12 | "filename" : "App Icon - Small.imagestack", 13 | "role" : "primary-app-icon" 14 | }, 15 | { 16 | "size" : "2320x720", 17 | "idiom" : "tv", 18 | "filename" : "Top Shelf Image Wide.imageset", 19 | "role" : "top-shelf-image-wide" 20 | }, 21 | { 22 | "size" : "1920x720", 23 | "idiom" : "tv", 24 | "filename" : "Top Shelf Image.imageset", 25 | "role" : "top-shelf-image" 26 | } 27 | ], 28 | "info" : { 29 | "version" : 1, 30 | "author" : "xcode" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "filename" : "Top Shelf Wide.png", 6 | "scale" : "1x" 7 | } 8 | ], 9 | "info" : { 10 | "version" : 1, 11 | "author" : "xcode" 12 | } 13 | } -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Top Shelf Wide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powermobileweb/Hexclockapp/1115f7f823f1445422f5b4b9495e8c1247c0dc30/HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Top Shelf Wide.png -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "filename" : "Top Shelf.png", 6 | "scale" : "1x" 7 | } 8 | ], 9 | "info" : { 10 | "version" : 1, 11 | "author" : "xcode" 12 | } 13 | } -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Top Shelf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powermobileweb/Hexclockapp/1115f7f823f1445422f5b4b9495e8c1247c0dc30/HexClock/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Top Shelf.png -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "landscape", 5 | "idiom" : "tv", 6 | "filename" : "Launch Image.png", 7 | "extent" : "full-screen", 8 | "minimum-system-version" : "9.0", 9 | "scale" : "1x" 10 | } 11 | ], 12 | "info" : { 13 | "version" : 1, 14 | "author" : "xcode" 15 | } 16 | } -------------------------------------------------------------------------------- /HexClock/Resources/Assets.xcassets/LaunchImage.launchimage/Launch Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powermobileweb/Hexclockapp/1115f7f823f1445422f5b4b9495e8c1247c0dc30/HexClock/Resources/Assets.xcassets/LaunchImage.launchimage/Launch Image.png -------------------------------------------------------------------------------- /HexClock/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Hex Color Clock 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 2 23 | LSRequiresIPhoneOS 24 | 25 | UIRequiredDeviceCapabilities 26 | 27 | arm64 28 | 29 | UIUserInterfaceStyle 30 | Automatic 31 | 32 | 33 | -------------------------------------------------------------------------------- /HexClock/Source/Application/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // HexClock 4 | // 5 | 6 | import UIKit 7 | 8 | @UIApplicationMain 9 | class AppDelegate: UIResponder, UIApplicationDelegate { 10 | 11 | // MARK: Properties 12 | 13 | var window: UIWindow? 14 | 15 | // MARK: UIApplicationDelegate 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Avoid showing the screensaver while running this app. 19 | application.isIdleTimerDisabled = true 20 | 21 | window = UIWindow() 22 | window?.rootViewController = HexClockViewController() 23 | window?.makeKeyAndVisible() 24 | return true 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /HexClock/Source/Extensions/Date+HMS.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Date+HMS.swift 3 | // HexClock 4 | // 5 | 6 | import Foundation 7 | 8 | extension Date { 9 | 10 | /// A tuple of (hour, minute, second) representing the time component of this date. 11 | var timeComponents: (Int, Int, Int) { 12 | let components = Calendar.current.dateComponents([.hour, .minute, .second], from: self) 13 | 14 | guard let hour = components.hour, 15 | let minute = components.minute, 16 | let second = components.second else { fatalError("Could not parse date") } 17 | 18 | return (hour, minute, second) 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /HexClock/Source/Extensions/UIColor+FromTime.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+FromTime.swift 3 | // HexClock 4 | // 5 | 6 | import UIKit 7 | 8 | extension UIColor { 9 | 10 | static func fromTime(hour: Int, minute: Int, second: Int) -> UIColor { 11 | let red = CGFloat(hour) / 255.0 12 | let green = CGFloat(minute) / 255.0 13 | let blue = CGFloat(second) / 255.0 14 | 15 | return UIColor(red: red, green: green, blue: blue, alpha: 1.0) 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /HexClock/Source/Extensions/UIView+AutoLayout.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+AutoLayout.swift 3 | // HexClock 4 | // 5 | 6 | import UIKit 7 | 8 | extension UIView { 9 | 10 | func pinTo(_ otherView: UIView) { 11 | topAnchor.constraint(equalTo: otherView.topAnchor).isActive = true 12 | bottomAnchor.constraint(equalTo: otherView.bottomAnchor).isActive = true 13 | leadingAnchor.constraint(equalTo: otherView.leadingAnchor).isActive = true 14 | trailingAnchor.constraint(equalTo: otherView.trailingAnchor).isActive = true 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /HexClock/Source/UI/HexClockView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HexClockView.swift 3 | // HexClock 4 | // 5 | 6 | import UIKit 7 | 8 | /// Applies a property-change block, with or without, animations depending on the `animated` flag. 9 | func animateOrApply(animationDuration: TimeInterval, animated: Bool, block: @escaping () -> Void) { 10 | if animated { 11 | UIView.animate(withDuration: animationDuration, animations: block) 12 | } else { 13 | block() 14 | } 15 | } 16 | 17 | /// Hex Clock view. 18 | final class HexClockView: UIView { 19 | 20 | // MARK: Properties 21 | 22 | private var clockLabel: UILabel? 23 | private var timer: Timer? 24 | 25 | // MARK: Initialization 26 | 27 | init() { 28 | super.init(frame: CGRect(x: 0, y: 0, width: 400, height: 200)) 29 | setup() 30 | } 31 | 32 | override init(frame: CGRect) { 33 | super.init(frame: frame) 34 | setup() 35 | } 36 | 37 | required init?(coder aDecoder: NSCoder) { 38 | super.init(coder: aDecoder) 39 | setup() 40 | } 41 | 42 | // MARK: UIView 43 | 44 | private func setup() { 45 | translatesAutoresizingMaskIntoConstraints = false 46 | 47 | // Create clock label. 48 | let clockLabel = UILabel() 49 | 50 | clockLabel.translatesAutoresizingMaskIntoConstraints = false 51 | clockLabel.textColor = UIColor.white 52 | clockLabel.textAlignment = .center 53 | clockLabel.font = UIFont.monospacedDigitSystemFont(ofSize: 250, weight: UIFontWeightUltraLight) 54 | 55 | addSubview(clockLabel) 56 | clockLabel.pinTo(self) 57 | 58 | self.clockLabel = clockLabel 59 | 60 | // Setup timer. 61 | timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in 62 | DispatchQueue.main.async { 63 | self.updateTime() 64 | } 65 | } 66 | 67 | updateTime(animated: false) 68 | } 69 | 70 | // MARK: Actions 71 | 72 | private func updateTime(animated: Bool = true) { 73 | let now = Date() 74 | let (hour, minute, second) = now.timeComponents 75 | let padNumber = { n in String(format: "%02d", n) } 76 | 77 | clockLabel?.text = "#\(padNumber(hour))\(padNumber(minute))\(padNumber(second))" 78 | 79 | animateOrApply(animationDuration: 1.0, animated: animated) { 80 | self.backgroundColor = UIColor.fromTime(hour: hour, minute: minute, second: second) 81 | } 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /HexClock/Source/UI/HexClockViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HexClockViewController.swift 3 | // HexClock 4 | // 5 | 6 | import UIKit 7 | 8 | /// Hex Clock view controller. 9 | class HexClockViewController: UIViewController { 10 | 11 | // MARK: UIViewController 12 | 13 | override func viewDidLoad() { 14 | let clockView = HexClockView() 15 | view.addSubview(clockView) 16 | clockView.pinTo(view) 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | 3 | Copyright (c) 2017 PowerMobile Team 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 9 | of the Software, and to permit persons to whom the Software is furnished to do 10 | so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hex Color Clock 2 | 3 | A simple, minimal hexadecimal clock for the Apple TV. 4 | 5 | [Download it on the App Store!](https://itunes.apple.com/us/app/hex-color-clock/id1207660670?mt%3D8) 6 | 7 | 8 | 9 | ## Dependencies 10 | 11 | Fastlane is used to manage the build and deploy process - please install Fastlane via Bundler: 12 | 13 | ``` 14 | $ bundle install 15 | ``` 16 | 17 | ## Building 18 | 19 | ### Development 20 | 21 | Deploying and testing on the Simulator requires no certificate. Simply build and run as normal. 22 | 23 | To deploy and test on a physical Apple TV, begin by fetching the development certificate: 24 | 25 | ``` 26 | $ export FASTLANE_USER="" 27 | $ export HEXCLOCK_CERTS_REPO="" 28 | $ bundle exec fastlane fetch_dev_cert 29 | ``` 30 | 31 | To run on physical device, select your Apple TV device, then select `Product > Run`. 32 | 33 | ### Release 34 | 35 | First, begin by fetching the App Store certificate: 36 | 37 | ``` 38 | $ export FASTLANE_USER="" 39 | $ export HEXCLOCK_CERTS_REPO="" 40 | $ bundle exec fastlane fetch_release_cert 41 | ``` 42 | 43 | To build for the App Store, select `Product > Archive`. 44 | 45 | ## License 46 | 47 | Please see the `LICENSE.md` file. 48 | 49 | Please contact me if there is any question. 50 | info@powermobile.org 51 | -------------------------------------------------------------------------------- /Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/powermobileweb/Hexclockapp/1115f7f823f1445422f5b4b9495e8c1247c0dc30/Screenshot.png --------------------------------------------------------------------------------