├── .gitignore
├── KTPomodoro WatchKit App
├── Base.lproj
│ ├── Interface.storyboard
│ └── KTWatchTaskCompletedNotificationStoryboard.storyboard
├── Images.xcassets
│ ├── AppIcon.appiconset
│ │ ├── AppIcon-24@2x.png
│ │ ├── AppIcon-27.5@2x.png
│ │ ├── AppIcon-80@2x copy.png
│ │ ├── AppIcon-88@2x.png
│ │ └── Contents.json
│ ├── LaunchImage.launchimage
│ │ └── Contents.json
│ ├── circles_0.imageset
│ │ ├── Contents.json
│ │ └── circles_0@2x.png
│ ├── circles_1.imageset
│ │ ├── Contents.json
│ │ └── circles_1@2x.png
│ ├── circles_10.imageset
│ │ ├── Contents.json
│ │ └── circles_10@2x.png
│ ├── circles_11.imageset
│ │ ├── Contents.json
│ │ └── circles_11@2x.png
│ ├── circles_12.imageset
│ │ ├── Contents.json
│ │ └── circles_12@2x.png
│ ├── circles_2.imageset
│ │ ├── Contents.json
│ │ └── circles_2@2x.png
│ ├── circles_3.imageset
│ │ ├── Contents.json
│ │ └── circles_3@2x.png
│ ├── circles_4.imageset
│ │ ├── Contents.json
│ │ └── circles_4@2x.png
│ ├── circles_5.imageset
│ │ ├── Contents.json
│ │ └── circles_5@2x.png
│ ├── circles_6.imageset
│ │ ├── Contents.json
│ │ └── circles_6@2x.png
│ ├── circles_7.imageset
│ │ ├── Contents.json
│ │ └── circles_7@2x.png
│ ├── circles_8.imageset
│ │ ├── Contents.json
│ │ └── circles_8@2x.png
│ ├── circles_9.imageset
│ │ ├── Contents.json
│ │ └── circles_9@2x.png
│ ├── circles_background.imageset
│ │ ├── Contents.json
│ │ └── circles_background@2x.png
│ ├── listview_background_red.imageset
│ │ ├── Contents.json
│ │ ├── listview_background_red.png
│ │ └── listview_background_red@2x.png
│ └── pomodoro_watch_activity_background.imageset
│ │ ├── Contents.json
│ │ └── pomodoro_watch_activity_background@2x.png
└── Info.plist
├── KTPomodoro WatchKit Extension
├── Images.xcassets
│ └── MyImage.imageset
│ │ └── Contents.json
├── Info.plist
├── KTPomodoro WatchKit Extension.entitlements
├── KTWatchAddTaskRowInterfaceController.h
├── KTWatchAddTaskRowInterfaceController.m
├── KTWatchGlanceController.h
├── KTWatchGlanceController.m
├── KTWatchInterfaceAddTaskInterfaceController.h
├── KTWatchInterfaceAddTaskInterfaceController.m
├── KTWatchInterfaceController.h
├── KTWatchInterfaceController.m
├── KTWatchPomodoroCompletedNotificationController.h
├── KTWatchPomodoroCompletedNotificationController.m
├── KTWatchTaskCompletedNotificationController.h
├── KTWatchTaskCompletedNotificationController.m
├── KTWatchTasksListInterfaceController.h
├── KTWatchTasksListInterfaceController.m
├── KTWatchTasksRowInterfaceController.h
├── KTWatchTasksRowInterfaceController.m
├── PomodoroFinishedPayload.apns
└── TaskCompletedPayload.apns
├── KTPomodoro.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── xcuserdata
│ └── ktang.xcuserdatad
│ └── xcschemes
│ ├── KTPomodoro.xcscheme
│ └── xcschememanagement.plist
├── KTPomodoro
├── Base.lproj
│ └── LaunchScreen.xib
├── Images.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── tomato_app.imageset
│ │ ├── Contents.json
│ │ └── tomato_app@2x.png
├── Info.plist
├── KTAppDelegate.h
├── KTAppDelegate.m
├── KTPomodoro.entitlements
├── Model
│ ├── KTActiveActivityState.h
│ ├── KTActiveActivityState.m
│ ├── KTCoreDataStack.h
│ ├── KTCoreDataStack.m
│ ├── KTPomodoroActivityModel.h
│ ├── KTPomodoroActivityModel.m
│ ├── KTPomodoroModel.xcdatamodeld
│ │ └── KTPomodoroModel.xcdatamodel
│ │ │ └── contents
│ ├── KTPomodoroTaskConstants.h
│ └── KTPomodoroTaskConstants.m
├── Resources
│ ├── KTPomodoroTableViewCell.xib
│ └── Shared
│ │ └── Settings-Watch.bundle
│ │ ├── Root.plist
│ │ └── en.lproj
│ │ └── Root.strings
├── Utils
│ ├── KTActivityManager.h
│ ├── KTActivityManager.m
│ ├── KTSharedUserDefaults.h
│ └── KTSharedUserDefaults.m
├── View Controller
│ ├── KTPomodoroTableViewCell.h
│ ├── KTPomodoroTableViewCell.m
│ ├── KTPomodoroTableViewController.h
│ └── KTPomodoroTableViewController.m
└── main.m
├── KTPomodoroTests
├── Info.plist
└── KTPomodoroTests.m
├── Mockup
└── KTPomodoro - app.sketch
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | xcuserdata
3 | Logs/
4 | /build/
5 | instruments.out
6 | instrumentscli*.trace
7 | *.pbxuser
8 | *.mode2v3
9 | *.mode1v3
10 | xcuserdata
11 | *~
12 | *.DS_Store
13 | *.swp
14 | *.out
15 | *.xccheckout
16 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Base.lproj/Interface.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
27 |
28 |
29 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
119 |
120 |
121 |
122 |
123 |
127 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
177 |
178 |
179 |
180 |
181 |
182 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
197 |
201 |
202 |
203 |
204 |
205 |
209 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
289 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Base.lproj/KTWatchTaskCompletedNotificationStoryboard.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
53 |
57 |
58 |
59 |
60 |
61 |
65 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/AppIcon.appiconset/AppIcon-24@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro WatchKit App/Images.xcassets/AppIcon.appiconset/AppIcon-24@2x.png
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/AppIcon.appiconset/AppIcon-27.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro WatchKit App/Images.xcassets/AppIcon.appiconset/AppIcon-27.5@2x.png
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/AppIcon.appiconset/AppIcon-80@2x copy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro WatchKit App/Images.xcassets/AppIcon.appiconset/AppIcon-80@2x copy.png
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/AppIcon.appiconset/AppIcon-88@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro WatchKit App/Images.xcassets/AppIcon.appiconset/AppIcon-88@2x.png
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "24x24",
5 | "idiom" : "watch",
6 | "scale" : "2x",
7 | "filename" : "AppIcon-24@2x.png",
8 | "role" : "notificationCenter",
9 | "subtype" : "38mm"
10 | },
11 | {
12 | "size" : "27.5x27.5",
13 | "idiom" : "watch",
14 | "scale" : "2x",
15 | "filename" : "AppIcon-27.5@2x.png",
16 | "role" : "notificationCenter",
17 | "subtype" : "42mm"
18 | },
19 | {
20 | "size" : "29x29",
21 | "idiom" : "watch",
22 | "role" : "companionSettings",
23 | "scale" : "2x"
24 | },
25 | {
26 | "size" : "29x29",
27 | "idiom" : "watch",
28 | "role" : "companionSettings",
29 | "scale" : "3x"
30 | },
31 | {
32 | "size" : "40x40",
33 | "idiom" : "watch",
34 | "scale" : "2x",
35 | "filename" : "AppIcon-80@2x copy.png",
36 | "role" : "appLauncher",
37 | "subtype" : "38mm"
38 | },
39 | {
40 | "size" : "44x44",
41 | "idiom" : "watch",
42 | "scale" : "2x",
43 | "filename" : "AppIcon-88@2x.png",
44 | "role" : "appLauncher",
45 | "subtype" : "42mm"
46 | },
47 | {
48 | "size" : "86x86",
49 | "idiom" : "watch",
50 | "scale" : "2x",
51 | "role" : "quickLook",
52 | "subtype" : "38mm"
53 | },
54 | {
55 | "size" : "98x98",
56 | "idiom" : "watch",
57 | "scale" : "2x",
58 | "role" : "quickLook",
59 | "subtype" : "42mm"
60 | },
61 | {
62 | "scale" : "2x",
63 | "idiom" : "watch",
64 | "unassigned" : true,
65 | "role" : "notificationCenter",
66 | "subtype" : "38mm"
67 | },
68 | {
69 | "scale" : "2x",
70 | "idiom" : "watch",
71 | "unassigned" : true,
72 | "role" : "notificationCenter",
73 | "subtype" : "38mm"
74 | },
75 | {
76 | "scale" : "2x",
77 | "idiom" : "watch",
78 | "unassigned" : true,
79 | "role" : "notificationCenter",
80 | "subtype" : "42mm"
81 | },
82 | {
83 | "idiom" : "watch",
84 | "unassigned" : true,
85 | "role" : "companionSettings",
86 | "scale" : "3x"
87 | }
88 | ],
89 | "info" : {
90 | "version" : 1,
91 | "author" : "xcode"
92 | }
93 | }
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "watch",
6 | "extent" : "full-screen",
7 | "minimum-system-version" : "8.0",
8 | "subtype" : "38mm",
9 | "scale" : "2x"
10 | },
11 | {
12 | "orientation" : "portrait",
13 | "idiom" : "watch",
14 | "extent" : "full-screen",
15 | "minimum-system-version" : "8.0",
16 | "subtype" : "42mm",
17 | "scale" : "2x"
18 | }
19 | ],
20 | "info" : {
21 | "version" : 1,
22 | "author" : "xcode"
23 | }
24 | }
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_0.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "circles_0@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_0.imageset/circles_0@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro WatchKit App/Images.xcassets/circles_0.imageset/circles_0@2x.png
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_1.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "circles_1@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_1.imageset/circles_1@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro WatchKit App/Images.xcassets/circles_1.imageset/circles_1@2x.png
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_10.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "circles_10@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_10.imageset/circles_10@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro WatchKit App/Images.xcassets/circles_10.imageset/circles_10@2x.png
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_11.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "circles_11@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_11.imageset/circles_11@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro WatchKit App/Images.xcassets/circles_11.imageset/circles_11@2x.png
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_12.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "circles_12@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_12.imageset/circles_12@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro WatchKit App/Images.xcassets/circles_12.imageset/circles_12@2x.png
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "circles_2@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_2.imageset/circles_2@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro WatchKit App/Images.xcassets/circles_2.imageset/circles_2@2x.png
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "circles_3@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_3.imageset/circles_3@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro WatchKit App/Images.xcassets/circles_3.imageset/circles_3@2x.png
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_4.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "circles_4@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_4.imageset/circles_4@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro WatchKit App/Images.xcassets/circles_4.imageset/circles_4@2x.png
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_5.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "circles_5@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_5.imageset/circles_5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro WatchKit App/Images.xcassets/circles_5.imageset/circles_5@2x.png
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_6.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "circles_6@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_6.imageset/circles_6@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro WatchKit App/Images.xcassets/circles_6.imageset/circles_6@2x.png
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_7.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "circles_7@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_7.imageset/circles_7@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro WatchKit App/Images.xcassets/circles_7.imageset/circles_7@2x.png
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_8.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "circles_8@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_8.imageset/circles_8@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro WatchKit App/Images.xcassets/circles_8.imageset/circles_8@2x.png
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_9.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "circles_9@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_9.imageset/circles_9@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro WatchKit App/Images.xcassets/circles_9.imageset/circles_9@2x.png
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_background.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "circles_background@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/circles_background.imageset/circles_background@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro WatchKit App/Images.xcassets/circles_background.imageset/circles_background@2x.png
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/listview_background_red.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "listview_background_red.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "listview_background_red@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/listview_background_red.imageset/listview_background_red.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro WatchKit App/Images.xcassets/listview_background_red.imageset/listview_background_red.png
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/listview_background_red.imageset/listview_background_red@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro WatchKit App/Images.xcassets/listview_background_red.imageset/listview_background_red@2x.png
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/pomodoro_watch_activity_background.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "pomodoro_watch_activity_background@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Images.xcassets/pomodoro_watch_activity_background.imageset/pomodoro_watch_activity_background@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro WatchKit App/Images.xcassets/pomodoro_watch_activity_background.imageset/pomodoro_watch_activity_background@2x.png
--------------------------------------------------------------------------------
/KTPomodoro WatchKit App/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | KTPomodoro
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | com.corgitoergosum.KTPomodoro.watchkitapp
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | UISupportedInterfaceOrientations
26 |
27 | UIInterfaceOrientationPortrait
28 | UIInterfaceOrientationPortraitUpsideDown
29 |
30 | WKCompanionAppBundleIdentifier
31 | com.corgitoergosum.KTPomodoro
32 | WKWatchKitApp
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit Extension/Images.xcassets/MyImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "scale" : "3x"
14 | }
15 | ],
16 | "info" : {
17 | "version" : 1,
18 | "author" : "xcode"
19 | }
20 | }
--------------------------------------------------------------------------------
/KTPomodoro WatchKit Extension/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | KTPomodoro WatchKit Extension
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | com.corgitoergosum.KTPomodoro.watchkitextension
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | XPC!
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.0
25 | NSExtension
26 |
27 | NSExtensionAttributes
28 |
29 | WKAppBundleIdentifier
30 | com.corgitoergosum.KTPomodoro.watchkitapp
31 |
32 | NSExtensionPointIdentifier
33 | com.apple.watchkit
34 |
35 | RemoteInterfacePrincipalClass
36 | InterfaceController
37 |
38 |
39 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit Extension/KTPomodoro WatchKit Extension.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.application-groups
6 |
7 | group.com.corgitoergosum.KTPomodoro
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit Extension/KTWatchAddTaskRowInterfaceController.h:
--------------------------------------------------------------------------------
1 | //
2 | // KTWatchAddTaskRowInterfaceController.h
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/9/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface KTWatchAddTaskRowInterfaceController : NSObject
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit Extension/KTWatchAddTaskRowInterfaceController.m:
--------------------------------------------------------------------------------
1 | //
2 | // KTWatchAddTaskRowInterfaceController.m
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/9/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import "KTWatchAddTaskRowInterfaceController.h"
10 |
11 | @implementation KTWatchAddTaskRowInterfaceController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit Extension/KTWatchGlanceController.h:
--------------------------------------------------------------------------------
1 | //
2 | // GlanceController.h
3 | // KTPomodoro WatchKit Extension
4 | //
5 | // Created by Kenny Tang on 1/1/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface KTWatchGlanceController : WKInterfaceController
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit Extension/KTWatchGlanceController.m:
--------------------------------------------------------------------------------
1 | //
2 | // GlanceController.m
3 | // KTPomodoro WatchKit Extension
4 | //
5 | // Created by Kenny Tang on 1/1/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import "KTWatchGlanceController.h"
10 |
11 |
12 | @interface KTWatchGlanceController()
13 |
14 | @end
15 |
16 |
17 | @implementation KTWatchGlanceController
18 |
19 | - (void)awakeWithContext:(id)context {
20 | [super awakeWithContext:context];
21 |
22 | // Configure interface objects here.
23 | }
24 |
25 | - (void)willActivate {
26 | // This method is called when watch view controller is about to be visible to user
27 | [super willActivate];
28 | }
29 |
30 | - (void)didDeactivate {
31 | // This method is called when watch view controller is no longer visible
32 | [super didDeactivate];
33 | }
34 |
35 | @end
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit Extension/KTWatchInterfaceAddTaskInterfaceController.h:
--------------------------------------------------------------------------------
1 | //
2 | // KTWatchInterfaceAddTaskInterfaceController.h
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/9/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface KTWatchInterfaceAddTaskInterfaceController : WKInterfaceController
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit Extension/KTWatchInterfaceAddTaskInterfaceController.m:
--------------------------------------------------------------------------------
1 | //
2 | // KTWatchInterfaceAddTaskInterfaceController.m
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/9/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import "KTWatchInterfaceAddTaskInterfaceController.h"
10 | #import "KTCoreDataStack.h"
11 |
12 | @interface KTWatchInterfaceAddTaskInterfaceController()
13 |
14 | @property (nonatomic) NSString *taskName;
15 | @property (nonatomic) NSInteger expectedPomodoros;
16 | @property (weak, nonatomic) IBOutlet WKInterfaceLabel *expectedPomodorosLabel;
17 |
18 | @property (weak, nonatomic) IBOutlet WKInterfaceButton *confirmButton;
19 | @property (weak, nonatomic) IBOutlet WKInterfaceButton *taskNameButton;
20 |
21 | @end
22 |
23 |
24 | @implementation KTWatchInterfaceAddTaskInterfaceController
25 |
26 | - (void)awakeWithContext:(id)context {
27 | [super awakeWithContext:context];
28 |
29 | // Configure interface objects here.
30 | }
31 |
32 | - (void)willActivate {
33 | // This method is called when watch view controller is about to be visible to user
34 | [super willActivate];
35 | self.expectedPomodoros = 1;
36 | }
37 |
38 | - (void)didDeactivate {
39 | // This method is called when watch view controller is no longer visible
40 | [super didDeactivate];
41 | }
42 |
43 | #pragma mark - Action handlers
44 |
45 | - (IBAction)enterTaskNameButtonTapped {
46 |
47 | [self presentTextInputControllerWithSuggestions:@[
48 | @"Watch Cat videos",
49 | @"Exercise",
50 | @"Do some writing",
51 | @"Read a book",
52 | @"Work"] allowedInputMode:WKTextInputModeAllowAnimatedEmoji completion:^(NSArray *results) {
53 | NSLog(@"enterTaskNameButtonTapped results: %@", results);
54 | if ([results count]) {
55 | self.taskName = results[0];
56 | if (self.taskName.length) {
57 | [self.taskNameButton setTitle:self.taskName];
58 | [self.confirmButton setEnabled:YES];
59 | [self.confirmButton setHidden:NO];
60 | }
61 | }
62 | }];
63 | }
64 |
65 | - (IBAction)pomodorosSliderValueChanged:(float)value {
66 | self.expectedPomodoros = (NSUInteger)floor(value);
67 | [self.expectedPomodorosLabel setText:[NSString stringWithFormat:@"%@", @(self.expectedPomodoros)]];
68 | }
69 |
70 |
71 | - (IBAction)confirmButtonTapped {
72 |
73 | [[KTCoreDataStack sharedInstance] createNewTask:self.taskName taskDesc:@"" pomodoros:self.expectedPomodoros];
74 |
75 | [[KTCoreDataStack sharedInstance] saveContext];
76 |
77 | [self dismissController];
78 | }
79 |
80 | @end
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit Extension/KTWatchInterfaceController.h:
--------------------------------------------------------------------------------
1 | //
2 | // InterfaceController.h
3 | // KTPomodoro WatchKit Extension
4 | //
5 | // Created by Kenny Tang on 1/1/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface KTWatchInterfaceController : WKInterfaceController
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit Extension/KTWatchInterfaceController.m:
--------------------------------------------------------------------------------
1 | //
2 | // InterfaceController.m
3 | // KTPomodoro WatchKit Extension
4 | //
5 | // Created by Kenny Tang on 1/1/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import "KTWatchInterfaceController.h"
10 | #import "KTActivityManager.h"
11 | #import "KTCoreDataStack.h"
12 | #import "KTPomodoroActivityModel.h"
13 | #import "KTPomodoroTaskConstants.h"
14 | #import "KTSharedUserDefaults.h"
15 |
16 | @interface KTWatchInterfaceController()
17 |
18 | @property (nonatomic) KTPomodoroActivityModel *activity;
19 | @property (weak, nonatomic) IBOutlet WKInterfaceLabel *taskNameLabel;
20 | @property (weak, nonatomic) IBOutlet WKInterfaceLabel *plannedPomoLabel;
21 | @property (weak, nonatomic) IBOutlet WKInterfaceLabel *remainingPomoLabel;
22 |
23 | @property (weak, nonatomic) IBOutlet WKInterfaceLabel *timeLabel;
24 | @property (weak, nonatomic) IBOutlet WKInterfaceGroup *timerRingInterfaceGroup;
25 |
26 | @property (nonatomic) NSString *currentBackgroundImageString;
27 |
28 | @end
29 |
30 | @implementation KTWatchInterfaceController
31 |
32 |
33 |
34 | - (void)awakeWithContext:(id)context {
35 | [super awakeWithContext:context];
36 |
37 | KTPomodoroActivityModel *activity = (KTPomodoroActivityModel*)context;
38 | self.activity = activity;
39 | [self.taskNameLabel setText:activity.name];
40 | [self.plannedPomoLabel setText:[activity.expected_pomo stringValue]];
41 | self.currentBackgroundImageString = @"";
42 | [self.remainingPomoLabel setText:[activity.expected_pomo stringValue]];
43 |
44 | [self registerUserDefaultChanges];
45 | [self clearAllMenuItems];
46 |
47 | KTActivityManager *activityManager = [KTActivityManager sharedInstance];
48 | if (activity.status.integerValue == KTPomodoroActivityStatusInProgress){
49 |
50 | if ([KTActivityManager sharedInstance].activity != self.activity) {
51 |
52 | [[KTActivityManager sharedInstance] startActivity:activity error:nil];
53 | }
54 |
55 | // continue task
56 | activityManager.delegate = self;
57 |
58 | [self addMenuItemWithItemIcon:WKMenuItemIconBlock title:@"Interrupt" action:@selector(interruptTask:)];
59 | [self addMenuItemWithItemIcon:WKMenuItemIconDecline title:@"Stop" action:@selector(stopTask:)];
60 |
61 | } else {
62 |
63 | if (![activityManager hasOtherActiveActivityInSharedState:activity.activityID]) {
64 | [self addMenuItemWithItemIcon:WKMenuItemIconPlay title:@"Start" action:@selector(startTask:)];
65 | [self addMenuItemWithItemIcon:WKMenuItemIconTrash title:@"Delete" action:@selector(deleteTask:)];
66 | }
67 | }
68 |
69 | }
70 |
71 |
72 | - (void)didDeactivate {
73 | // This method is called when watch view controller is no longer visible
74 | [super didDeactivate];
75 | [self unregisterUserDefaultChanges];
76 | [[KTCoreDataStack sharedInstance] saveContext];
77 |
78 | }
79 |
80 | #pragma mark - Private
81 |
82 | #pragma mark - awakeWithContext: helper methods
83 |
84 | - (void)registerUserDefaultChanges
85 | {
86 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(userDefaultsUpdated) name:NSUserDefaultsDidChangeNotification object:nil];
87 | }
88 |
89 | #pragma mark - didDeactivate helper methods
90 |
91 | - (void)unregisterUserDefaultChanges
92 | {
93 | [[NSNotificationCenter defaultCenter] removeObserver:self name:NSUserDefaultsDidChangeNotification object:nil];
94 | }
95 |
96 | #pragma mark - registerUserDefaultChanges helper methods
97 |
98 | - (void)userDefaultsUpdated
99 | {
100 | BOOL shouldAutoComplete = [KTSharedUserDefaults shouldAutoDeleteCompletedActivites];
101 | NSUInteger breakDuration = [KTSharedUserDefaults breakDuration];
102 | NSUInteger pomoDuration = [KTSharedUserDefaults pomoDuration];
103 | NSLog(@"shouldAutoComplete: %i", shouldAutoComplete);
104 | NSLog(@"breakDuration: %@", @(breakDuration));
105 | NSLog(@"pomoDuration: %@", @(pomoDuration));
106 | }
107 |
108 |
109 | #pragma mark - Action Outlets
110 |
111 | - (void)interruptTask:(id)sender
112 | {
113 | [self stopTask:sender];
114 |
115 | // increment interrupt
116 | NSInteger interruptions = [self.activity.interruptions integerValue];
117 | self.activity.interruptions = @(++interruptions);
118 |
119 | }
120 |
121 | - (void)startTask:(id)sender
122 | {
123 | NSError *startTaskError;
124 | KTActivityManager *activityManager = [KTActivityManager sharedInstance];
125 | activityManager.delegate = self;
126 | [activityManager startActivity:self.activity error:&startTaskError];
127 |
128 | if (!startTaskError) {
129 | [self.timeLabel setText:[NSString stringWithFormat:@"%@:00", @([KTActivityManager pomodoroDurationMinutes])]];
130 |
131 | [self clearAllMenuItems];
132 | [self addMenuItemWithItemIcon:WKMenuItemIconBlock title:@"Interrupt" action:@selector(interruptTask:)];
133 | [self addMenuItemWithItemIcon:WKMenuItemIconDecline title:@"Stop" action:@selector(stopTask:)];
134 | }
135 | }
136 |
137 | - (void)stopTask:(id)sender
138 | {
139 | [[KTActivityManager sharedInstance] stopActivity];
140 | [self resetMenuItemsTimeLabel];
141 | [self resetBackgroundImage];
142 | }
143 |
144 | - (void)taskCompleted
145 | {
146 | [self resetMenuItemsTimeLabel];
147 |
148 | if ([self shouldAutoDeleteCompletedTasks]) {
149 | [self deleteTask:nil];
150 | }
151 |
152 | }
153 |
154 | - (void)deleteTask:(id)sender
155 | {
156 | [self.timeLabel setText:@"00:00"];
157 | [[KTActivityManager sharedInstance] stopActivity];
158 | [[[KTCoreDataStack sharedInstance] managedObjectContext] deleteObject:self.activity];
159 | [[KTCoreDataStack sharedInstance] saveContext];
160 | [self popController];
161 | }
162 |
163 | - (void)openApp:(id)sender
164 | {
165 | // NSDictionary *userInfo = @{@"taskID" : self.task.name};
166 | // [WKInterfaceController openParentApplication:userInfo reply:^(NSDictionary *replyInfo, NSError *error) {
167 | // NSLog(@"error: %@", error);
168 | // }];
169 |
170 |
171 | [self presentTextInputControllerWithSuggestions:nil allowedInputMode:WKTextInputModePlain completion:^(NSArray *results) {
172 | NSLog(@"results: %@", results);
173 | }];
174 | }
175 |
176 | #pragma mark - taskCompleted helper methods
177 |
178 | - (void)resetBackgroundImage
179 | {
180 | [self.timerRingInterfaceGroup setBackgroundImageNamed:@"circles_background"];
181 | }
182 |
183 | - (void)resetMenuItemsTimeLabel
184 | {
185 | [self clearAllMenuItems];
186 | [self addMenuItemWithItemIcon:WKMenuItemIconPlay title:@"Start" action:@selector(startTask:)];
187 | [self addMenuItemWithItemIcon:WKMenuItemIconTrash title:@"Delete" action:@selector(deleteTask:)];
188 | [self.timeLabel setText:@"00:00"];
189 |
190 | }
191 |
192 | - (BOOL)shouldAutoDeleteCompletedTasks
193 | {
194 | return [KTSharedUserDefaults shouldAutoDeleteCompletedActivites];
195 | }
196 |
197 |
198 | #pragma mark - KTActivityManagerDelegate methods
199 |
200 | - (void)activityManager:(KTActivityManager *)manager activityPausedForBreak:(NSUInteger)elapsedTime
201 | {
202 |
203 | }
204 |
205 | - (void)activityManager:(KTActivityManager *)manager activityDidUpdate:(KTPomodoroActivityModel *)activity
206 | {
207 |
208 | [self updateTimerBackgroundImage:activity];
209 |
210 |
211 | NSString *displayMinutesString = [self formatTimeIntToTwoDigitsString:[KTActivityManager pomoRemainingMinutes:activity.current_pomo_elapsed_time_int]];
212 |
213 | NSString *displaySecsString = [self formatTimeIntToTwoDigitsString:[KTActivityManager pomoRemainingSecsInCurrentMinute:activity.current_pomo_elapsed_time_int]];
214 |
215 | NSString *remainingTimeString = [NSString stringWithFormat:@"%@:%@", displayMinutesString, displaySecsString];
216 |
217 | [self.timeLabel setText:remainingTimeString];
218 |
219 | NSUInteger remainingPomo = [activity.expected_pomo integerValue] - [activity.actual_pomo integerValue];
220 |
221 | [self.remainingPomoLabel setText:[@(remainingPomo) stringValue]];
222 |
223 | if ([activity.status integerValue] == KTPomodoroActivityStatusCompleted) {
224 | [self.taskNameLabel setText:@"Yeah done!"];
225 | [self taskCompleted];
226 | }
227 |
228 | }
229 |
230 | #pragma mark - activityManager:activityDidUpdate: helper method
231 |
232 | - (NSString*)formatTimeIntToTwoDigitsString:(NSUInteger)time
233 | {
234 | NSString *displayString = (time>9)?[@(time) stringValue]:[NSString stringWithFormat:@"0%@", @(time)];
235 | return displayString;
236 | }
237 |
238 | - (void)updateTimerBackgroundImage:(KTPomodoroActivityModel *)activity
239 | {
240 | NSUInteger elapsedSecs = activity.current_pomo_elapsed_time_int;
241 | NSUInteger elapsedSections = elapsedSecs/(([KTActivityManager pomodoroDurationMinutes]*60)/12);
242 |
243 | NSString *backgroundImageString = [NSString stringWithFormat:@"circles_%@", @(elapsedSections)];
244 | NSLog(@"backgroundImageString: %@", backgroundImageString);
245 | if (![self.currentBackgroundImageString isEqualToString:backgroundImageString]) {
246 | self.currentBackgroundImageString = backgroundImageString;
247 | [self.timerRingInterfaceGroup setBackgroundImageNamed:backgroundImageString];
248 | }
249 | }
250 |
251 |
252 |
253 | @end
254 |
255 |
256 |
257 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit Extension/KTWatchPomodoroCompletedNotificationController.h:
--------------------------------------------------------------------------------
1 | //
2 | // KTWatchNotificationController.h
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/8/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface KTWatchPomodoroCompletedNotificationController : WKUserNotificationInterfaceController
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit Extension/KTWatchPomodoroCompletedNotificationController.m:
--------------------------------------------------------------------------------
1 | //
2 | // KTWatchNotificationController.m
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/8/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import "KTWatchPomodoroCompletedNotificationController.h"
10 |
11 |
12 | @interface KTWatchPomodoroCompletedNotificationController()
13 |
14 | @property (nonatomic) IBOutlet WKInterfaceLabel *alertLabel;
15 | @property (nonatomic) IBOutlet WKInterfaceLabel *taskNameLabel;
16 | @property (nonatomic) IBOutlet WKInterfaceLabel *remainingPomodorosLabel;
17 |
18 | @end
19 |
20 |
21 | @implementation KTWatchPomodoroCompletedNotificationController
22 |
23 | - (instancetype)init {
24 | self = [super init];
25 | if (self){
26 | // Initialize variables here.
27 | // Configure interface objects here.
28 |
29 | }
30 | return self;
31 | }
32 |
33 | - (void)willActivate {
34 | // This method is called when watch view controller is about to be visible to user
35 | [super willActivate];
36 | }
37 |
38 | - (void)didDeactivate {
39 | // This method is called when watch view controller is no longer visible
40 | [super didDeactivate];
41 | }
42 |
43 | - (void)didReceiveLocalNotification:(UILocalNotification *)localNotification withCompletion:(void (^)(WKUserNotificationInterfaceType))completionHandler {
44 |
45 | NSLog(@"didReceiveLocalNotification");
46 |
47 |
48 | // This method is called when a local notification needs to be presented.
49 | // Implement it if you use a dynamic notification interface.
50 | // Populate your dynamic notification inteface as quickly as possible.
51 | //
52 | // After populating your dynamic notification interface call the completion block.
53 | completionHandler(WKUserNotificationInterfaceTypeCustom);
54 | }
55 |
56 | - (void)didReceiveRemoteNotification:(NSDictionary *)remoteNotification withCompletion:(void (^)(WKUserNotificationInterfaceType))completionHandler {
57 |
58 | NSLog(@"didReceiveRemoteNotification");
59 |
60 | NSString *alertString = remoteNotification[@"aps"][@"alert"];
61 |
62 | NSDictionary *payload = remoteNotification[@"payload"];
63 | // NSString *taskID = payload[@"id"];
64 | NSString *taskName = payload[@"name"];
65 | NSNumber *remainingPomos = payload[@"pomos_left"];
66 | [self.taskNameLabel setText:taskName];
67 | [self.remainingPomodorosLabel setText:[remainingPomos stringValue]];
68 |
69 | [self.alertLabel setText:alertString];
70 |
71 | // This method is called when a remote notification needs to be presented.
72 | // Implement it if you use a dynamic notification interface.
73 | // Populate your dynamic notification inteface as quickly as possible.
74 | //
75 | // After populating your dynamic notification interface call the completion block.
76 | completionHandler(WKUserNotificationInterfaceTypeCustom);
77 | }
78 |
79 | @end
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit Extension/KTWatchTaskCompletedNotificationController.h:
--------------------------------------------------------------------------------
1 | //
2 | // KTWatchTaskCompletedNotificationController.h
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/9/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface KTWatchTaskCompletedNotificationController : WKUserNotificationInterfaceController
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit Extension/KTWatchTaskCompletedNotificationController.m:
--------------------------------------------------------------------------------
1 | //
2 | // KTWatchTaskCompletedNotificationController.m
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/9/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import "KTWatchTaskCompletedNotificationController.h"
10 |
11 |
12 | @interface KTWatchTaskCompletedNotificationController()
13 |
14 | @property (nonatomic) IBOutlet WKInterfaceLabel *alertLabel;
15 | @property (nonatomic) IBOutlet WKInterfaceLabel *plannedPomosLabel;
16 | @property (nonatomic) IBOutlet WKInterfaceLabel *actualPomosLabel;
17 | @property (nonatomic) IBOutlet WKInterfaceLabel *interruptionsLabel;
18 |
19 | @end
20 |
21 |
22 | @implementation KTWatchTaskCompletedNotificationController
23 |
24 | - (instancetype)init {
25 | self = [super init];
26 | if (self){
27 | // Initialize variables here.
28 | // Configure interface objects here.
29 |
30 | }
31 | return self;
32 | }
33 |
34 | - (void)willActivate {
35 | // This method is called when watch view controller is about to be visible to user
36 | [super willActivate];
37 | }
38 |
39 | - (void)didDeactivate {
40 | // This method is called when watch view controller is no longer visible
41 | [super didDeactivate];
42 | }
43 |
44 | - (void)didReceiveLocalNotification:(UILocalNotification *)localNotification withCompletion:(void (^)(WKUserNotificationInterfaceType))completionHandler {
45 |
46 |
47 | NSLog(@"didReceiveLocalNotification");
48 |
49 | // This method is called when a local notification needs to be presented.
50 | // Implement it if you use a dynamic notification interface.
51 | // Populate your dynamic notification inteface as quickly as possible.
52 | //
53 | // After populating your dynamic notification interface call the completion block.
54 | completionHandler(WKUserNotificationInterfaceTypeCustom);
55 | }
56 |
57 | - (void)didReceiveRemoteNotification:(NSDictionary *)remoteNotification withCompletion:(void (^)(WKUserNotificationInterfaceType))completionHandler {
58 |
59 | NSLog(@"didReceiveRemoteNotification");
60 |
61 | NSString *alertString = remoteNotification[@"aps"][@"alert"];
62 |
63 | NSDictionary *payload = remoteNotification[@"payload"];
64 | // NSString *taskID = payload[@"id"];
65 | // NSString *taskName = payload[@"name"];
66 | NSNumber *plannedPomos = payload[@"planned_pomos"];
67 | NSNumber *actualPomos = payload[@"actual_pomos"];
68 | NSNumber *interrupts = payload[@"interrupts"];
69 |
70 | [self.plannedPomosLabel setText:[plannedPomos stringValue]];
71 | [self.actualPomosLabel setText:[actualPomos stringValue]];
72 | [self.interruptionsLabel setText:[interrupts stringValue]];
73 |
74 | [self.alertLabel setText:alertString];
75 |
76 |
77 | completionHandler(WKUserNotificationInterfaceTypeCustom);
78 | }
79 |
80 | @end
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit Extension/KTWatchTasksListInterfaceController.h:
--------------------------------------------------------------------------------
1 | //
2 | // KTWatchTasksListInterfaceController.h
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/1/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface KTWatchTasksListInterfaceController : WKInterfaceController
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit Extension/KTWatchTasksListInterfaceController.m:
--------------------------------------------------------------------------------
1 | //
2 | // KTWatchTasksListInterfaceController.m
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/1/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import "KTWatchTasksListInterfaceController.h"
10 | #import "KTCoreDataStack.h"
11 | #import "KTPomodoroActivityModel.h"
12 | #import "KTPomodoroTaskConstants.h"
13 | #import "KTWatchTasksRowInterfaceController.h"
14 | #import "KTWatchAddTaskRowInterfaceController.h"
15 |
16 | @interface KTWatchTasksListInterfaceController()
17 |
18 | @property (weak, nonatomic) IBOutlet WKInterfaceTable *table;
19 | @property (nonatomic) NSArray *allTasks;
20 |
21 | @end
22 |
23 |
24 | @implementation KTWatchTasksListInterfaceController
25 |
26 | - (void)awakeWithContext:(id)context {
27 | [super awakeWithContext:context];
28 |
29 | }
30 |
31 | - (void)willActivate {
32 | // This method is called when watch view controller is about to be visible to user
33 | [super willActivate];
34 |
35 | [self setUpTable];
36 | }
37 |
38 | - (void)didDeactivate {
39 | // This method is called when watch view controller is no longer visible
40 | [super didDeactivate];
41 |
42 | }
43 |
44 | #pragma mark - willActivate helper method
45 |
46 | - (void)setUpTable
47 | {
48 | NSArray *tasks = [[KTCoreDataStack sharedInstance] allTasks];
49 |
50 | // reload table
51 | if ([tasks count] != [self.allTasks count]) {
52 | [self clearTableRows];
53 |
54 | [self.table insertRowsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [tasks count])] withRowType:@"KTWatchTasksRowInterfaceController"];
55 | __block CGFloat cellAlpha = 1.0f;
56 | [tasks enumerateObjectsUsingBlock:^(KTPomodoroActivityModel *task, NSUInteger idx, BOOL *stop) {
57 | KTWatchTasksRowInterfaceController *row = (KTWatchTasksRowInterfaceController*)[self.table rowControllerAtIndex:idx];
58 | [row.taskNameLabel setText:task.name];
59 | if (task.status.integerValue == KTPomodoroActivityStatusInProgress) {
60 | [row.taskStatusLabel setText:@"In Progress"];
61 | } else {
62 | [row.taskStatusLabel setText:@""];
63 | }
64 | [row.rowGroup setCornerRadius:0.0f];
65 | [row.rowGroup setAlpha:cellAlpha];
66 | if (cellAlpha > 0.2f) {
67 | cellAlpha -= 0.2;
68 | }
69 | if (idx > 0) {
70 | [row.taskStatusLabel setHidden:YES];
71 | }
72 | }];
73 |
74 |
75 | // add "add task" row at end
76 | [self.table insertRowsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange([tasks count], 1)] withRowType:@"KTWatchAddTaskRowInterfaceController"];
77 |
78 | }
79 |
80 | [tasks enumerateObjectsUsingBlock:^(KTPomodoroActivityModel *task, NSUInteger idx, BOOL *stop) {
81 | KTWatchTasksRowInterfaceController *row = (KTWatchTasksRowInterfaceController*)[self.table rowControllerAtIndex:idx];
82 | [row.taskNameLabel setText:task.name];
83 | if (task.status.integerValue == KTPomodoroActivityStatusInProgress) {
84 | [row.taskStatusLabel setText:@"In Progress"];
85 | } else {
86 | [row.taskStatusLabel setText:@""];
87 | }
88 | if (idx > 0) {
89 | [row.taskStatusLabel setHidden:YES];
90 | }
91 | }];
92 | self.allTasks = tasks;
93 | }
94 |
95 | - (void)clearTableRows
96 | {
97 | [self.table removeRowsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [self.table numberOfRows])]];
98 | }
99 |
100 |
101 | - (KTPomodoroActivityModel*)contextForSegueWithIdentifier:(NSString *)segueIdentifier inTable:(WKInterfaceTable *)table rowIndex:(NSInteger)rowIndex
102 | {
103 | if ([segueIdentifier isEqualToString:@"taskDetailsSegue"]) {
104 | return self.allTasks[rowIndex];
105 | } else {
106 | return nil;
107 | }
108 | }
109 |
110 | #pragma mark - helper
111 |
112 |
113 | @end
114 |
115 |
116 |
117 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit Extension/KTWatchTasksRowInterfaceController.h:
--------------------------------------------------------------------------------
1 | //
2 | // KTWatchTasksRowInterfaceController.h
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/1/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface KTWatchTasksRowInterfaceController : NSObject
13 |
14 | @property (weak, nonatomic) IBOutlet WKInterfaceLabel *taskNameLabel;
15 | @property (weak, nonatomic) IBOutlet WKInterfaceLabel *taskStatusLabel;
16 | @property (weak, nonatomic) IBOutlet WKInterfaceGroup *rowGroup;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit Extension/KTWatchTasksRowInterfaceController.m:
--------------------------------------------------------------------------------
1 | //
2 | // KTWatchTasksRowInterfaceController.m
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/1/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import "KTWatchTasksRowInterfaceController.h"
10 | #import
11 |
12 | @implementation KTWatchTasksRowInterfaceController
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/KTPomodoro WatchKit Extension/PomodoroFinishedPayload.apns:
--------------------------------------------------------------------------------
1 | {
2 | "aps": {
3 | "alert":"Pomodoro #1 has finished. Time for a break!",
4 | "title":"Task #1",
5 | "category":"PomodoroFinishedCategory"
6 | },
7 | "WatchKit Simulator Actions" : [
8 | {
9 | "title" : "Don't need one",
10 | "identifier" : "PomodoroFinishedNotification"
11 | }
12 | ],
13 | "payload":{
14 | "id":"task1",
15 | "name":"Task 1",
16 | "pomos_left":2
17 | }
18 | }
--------------------------------------------------------------------------------
/KTPomodoro WatchKit Extension/TaskCompletedPayload.apns:
--------------------------------------------------------------------------------
1 | {
2 | "aps": {
3 | "alert": "Task #1 has finished.",
4 | "title": "Task #1",
5 | "category": "TaskCompletedCategory"
6 | },
7 | "WatchKit Simulator Actions" : [
8 | {
9 | "title" : "Next Task",
10 | "identifier" : "TaskCompletedNotification"
11 | }
12 | ],
13 | "payload":{
14 | "id":"task1",
15 | "name":"Task 1",
16 | "pomos_left":0,
17 | "planned_pomos":1,
18 | "actual_pomos":2,
19 | "interrupts":0,
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/KTPomodoro.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 8E0F77441A55D0CF0008C4ED /* KTWatchInterfaceController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E0F77431A55D0CF0008C4ED /* KTWatchInterfaceController.m */; };
11 | 8E0F77471A55D0CF0008C4ED /* KTWatchGlanceController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E0F77461A55D0CF0008C4ED /* KTWatchGlanceController.m */; };
12 | 8E0F77491A55D0CF0008C4ED /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8E0F77481A55D0CF0008C4ED /* Images.xcassets */; };
13 | 8E0F774D1A55D0CF0008C4ED /* KTPomodoro WatchKit App.app in Resources */ = {isa = PBXBuildFile; fileRef = 8E0F774C1A55D0CF0008C4ED /* KTPomodoro WatchKit App.app */; };
14 | 8E0F77551A55D0CF0008C4ED /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8E0F77531A55D0CF0008C4ED /* Interface.storyboard */; };
15 | 8E0F77571A55D0CF0008C4ED /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8E0F77561A55D0CF0008C4ED /* Images.xcassets */; };
16 | 8E0F775A1A55D0CF0008C4ED /* KTPomodoro WatchKit Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 8E0F773E1A55D0CF0008C4ED /* KTPomodoro WatchKit Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
17 | 8E0F77631A55D0FC0008C4ED /* KTCoreDataStack.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF55C5E1A54E29F002962DF /* KTCoreDataStack.m */; };
18 | 8E0F77691A55D7CB0008C4ED /* KTPomodoroModel.xcdatamodeld in Resources */ = {isa = PBXBuildFile; fileRef = 8EF55C681A54EA82002962DF /* KTPomodoroModel.xcdatamodeld */; };
19 | 8E0F776F1A55E0770008C4ED /* KTWatchTasksRowInterfaceController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E0F776E1A55E0770008C4ED /* KTWatchTasksRowInterfaceController.m */; };
20 | 8E0F77721A55E09D0008C4ED /* KTWatchTasksListInterfaceController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E0F77711A55E09D0008C4ED /* KTWatchTasksListInterfaceController.m */; };
21 | 8E2668011A5AF05800C36D0C /* KTPomodoroActivityModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E2668001A5AF05800C36D0C /* KTPomodoroActivityModel.m */; };
22 | 8E2668021A5AF05800C36D0C /* KTPomodoroActivityModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E2668001A5AF05800C36D0C /* KTPomodoroActivityModel.m */; };
23 | 8E362A431A8FE6D4006DD649 /* Settings-Watch.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 8EE78ABA1A8AE2E100F8A225 /* Settings-Watch.bundle */; };
24 | 8E64C1061A5F4B2700A4D526 /* KTPomodoroTaskConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E64C1051A5F4B2700A4D526 /* KTPomodoroTaskConstants.m */; };
25 | 8E64C1071A5F4B2700A4D526 /* KTPomodoroTaskConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E64C1051A5F4B2700A4D526 /* KTPomodoroTaskConstants.m */; };
26 | 8E64C1091A5F585100A4D526 /* PomodoroFinishedPayload.apns in Resources */ = {isa = PBXBuildFile; fileRef = 8E64C1081A5F585100A4D526 /* PomodoroFinishedPayload.apns */; };
27 | 8E64C16A1A5F608800A4D526 /* KTWatchPomodoroCompletedNotificationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E64C1691A5F608800A4D526 /* KTWatchPomodoroCompletedNotificationController.m */; };
28 | 8EC91CB41A71911B007D0CD6 /* KTSharedUserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EC91CB31A71911B007D0CD6 /* KTSharedUserDefaults.m */; };
29 | 8EC91CB51A7191E2007D0CD6 /* KTSharedUserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EC91CB31A71911B007D0CD6 /* KTSharedUserDefaults.m */; };
30 | 8EC91CB81A719268007D0CD6 /* KTActiveActivityState.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EC91CB71A719268007D0CD6 /* KTActiveActivityState.m */; };
31 | 8EC91CB91A719268007D0CD6 /* KTActiveActivityState.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EC91CB71A719268007D0CD6 /* KTActiveActivityState.m */; };
32 | 8EC91CBC1A719806007D0CD6 /* KTActivityManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EC91CBB1A719806007D0CD6 /* KTActivityManager.m */; };
33 | 8EC91CBD1A719806007D0CD6 /* KTActivityManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EC91CBB1A719806007D0CD6 /* KTActivityManager.m */; };
34 | 8EE78ABB1A8AE2E100F8A225 /* Settings-Watch.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 8EE78ABA1A8AE2E100F8A225 /* Settings-Watch.bundle */; };
35 | 8EF55C2E1A54DFC2002962DF /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF55C2D1A54DFC2002962DF /* main.m */; };
36 | 8EF55C311A54DFC2002962DF /* KTAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF55C301A54DFC2002962DF /* KTAppDelegate.m */; };
37 | 8EF55C3C1A54DFC2002962DF /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8EF55C3B1A54DFC2002962DF /* Images.xcassets */; };
38 | 8EF55C3F1A54DFC2002962DF /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8EF55C3D1A54DFC2002962DF /* LaunchScreen.xib */; };
39 | 8EF55C4B1A54DFC2002962DF /* KTPomodoroTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF55C4A1A54DFC2002962DF /* KTPomodoroTests.m */; };
40 | 8EF55C5F1A54E29F002962DF /* KTCoreDataStack.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF55C5E1A54E29F002962DF /* KTCoreDataStack.m */; };
41 | 8EF55C651A54E4AD002962DF /* KTPomodoroTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF55C641A54E4AD002962DF /* KTPomodoroTableViewController.m */; };
42 | 8EF55C6A1A54EA82002962DF /* KTPomodoroModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 8EF55C681A54EA82002962DF /* KTPomodoroModel.xcdatamodeld */; };
43 | 8EF55C6C1A54EBC4002962DF /* KTPomodoroTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8EF55C6B1A54EBC4002962DF /* KTPomodoroTableViewCell.xib */; };
44 | 8EF55C6F1A54EC48002962DF /* KTPomodoroTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF55C6E1A54EC48002962DF /* KTPomodoroTableViewCell.m */; };
45 | 8EF5AF2A1A6063E500A40CE8 /* KTWatchTaskCompletedNotificationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF5AF291A6063E500A40CE8 /* KTWatchTaskCompletedNotificationController.m */; };
46 | 8EF5AF2D1A60652D00A40CE8 /* KTWatchTaskCompletedNotificationStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8EF5AF2B1A60652D00A40CE8 /* KTWatchTaskCompletedNotificationStoryboard.storyboard */; };
47 | 8EF5AF301A60916700A40CE8 /* KTWatchAddTaskRowInterfaceController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF5AF2F1A60916700A40CE8 /* KTWatchAddTaskRowInterfaceController.m */; };
48 | 8EF5AF331A60955E00A40CE8 /* KTWatchInterfaceAddTaskInterfaceController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF5AF321A60955E00A40CE8 /* KTWatchInterfaceAddTaskInterfaceController.m */; };
49 | /* End PBXBuildFile section */
50 |
51 | /* Begin PBXContainerItemProxy section */
52 | 8E0F774E1A55D0CF0008C4ED /* PBXContainerItemProxy */ = {
53 | isa = PBXContainerItemProxy;
54 | containerPortal = 8EF55C201A54DFC1002962DF /* Project object */;
55 | proxyType = 1;
56 | remoteGlobalIDString = 8E0F774B1A55D0CF0008C4ED;
57 | remoteInfo = "KTPomodoro WatchKit App";
58 | };
59 | 8E0F77581A55D0CF0008C4ED /* PBXContainerItemProxy */ = {
60 | isa = PBXContainerItemProxy;
61 | containerPortal = 8EF55C201A54DFC1002962DF /* Project object */;
62 | proxyType = 1;
63 | remoteGlobalIDString = 8E0F773D1A55D0CF0008C4ED;
64 | remoteInfo = "KTPomodoro WatchKit Extension";
65 | };
66 | 8EF55C451A54DFC2002962DF /* PBXContainerItemProxy */ = {
67 | isa = PBXContainerItemProxy;
68 | containerPortal = 8EF55C201A54DFC1002962DF /* Project object */;
69 | proxyType = 1;
70 | remoteGlobalIDString = 8EF55C271A54DFC1002962DF;
71 | remoteInfo = KTPomodoro;
72 | };
73 | /* End PBXContainerItemProxy section */
74 |
75 | /* Begin PBXCopyFilesBuildPhase section */
76 | 8E0F77611A55D0CF0008C4ED /* Embed App Extensions */ = {
77 | isa = PBXCopyFilesBuildPhase;
78 | buildActionMask = 2147483647;
79 | dstPath = "";
80 | dstSubfolderSpec = 13;
81 | files = (
82 | 8E0F775A1A55D0CF0008C4ED /* KTPomodoro WatchKit Extension.appex in Embed App Extensions */,
83 | );
84 | name = "Embed App Extensions";
85 | runOnlyForDeploymentPostprocessing = 0;
86 | };
87 | /* End PBXCopyFilesBuildPhase section */
88 |
89 | /* Begin PBXFileReference section */
90 | 8E0F773E1A55D0CF0008C4ED /* KTPomodoro WatchKit Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "KTPomodoro WatchKit Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
91 | 8E0F77411A55D0CF0008C4ED /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
92 | 8E0F77421A55D0CF0008C4ED /* KTWatchInterfaceController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KTWatchInterfaceController.h; sourceTree = ""; };
93 | 8E0F77431A55D0CF0008C4ED /* KTWatchInterfaceController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KTWatchInterfaceController.m; sourceTree = ""; };
94 | 8E0F77451A55D0CF0008C4ED /* KTWatchGlanceController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KTWatchGlanceController.h; sourceTree = ""; };
95 | 8E0F77461A55D0CF0008C4ED /* KTWatchGlanceController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KTWatchGlanceController.m; sourceTree = ""; };
96 | 8E0F77481A55D0CF0008C4ED /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
97 | 8E0F774C1A55D0CF0008C4ED /* KTPomodoro WatchKit App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "KTPomodoro WatchKit App.app"; sourceTree = BUILT_PRODUCTS_DIR; };
98 | 8E0F77521A55D0CF0008C4ED /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
99 | 8E0F77541A55D0CF0008C4ED /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Interface.storyboard; sourceTree = ""; };
100 | 8E0F77561A55D0CF0008C4ED /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
101 | 8E0F77681A55D6E40008C4ED /* KTPomodoro WatchKit Extension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "KTPomodoro WatchKit Extension.entitlements"; sourceTree = ""; };
102 | 8E0F776D1A55E0770008C4ED /* KTWatchTasksRowInterfaceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KTWatchTasksRowInterfaceController.h; sourceTree = ""; };
103 | 8E0F776E1A55E0770008C4ED /* KTWatchTasksRowInterfaceController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KTWatchTasksRowInterfaceController.m; sourceTree = ""; };
104 | 8E0F77701A55E09D0008C4ED /* KTWatchTasksListInterfaceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KTWatchTasksListInterfaceController.h; sourceTree = ""; };
105 | 8E0F77711A55E09D0008C4ED /* KTWatchTasksListInterfaceController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KTWatchTasksListInterfaceController.m; sourceTree = ""; };
106 | 8E2667FF1A5AF05800C36D0C /* KTPomodoroActivityModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KTPomodoroActivityModel.h; path = Model/KTPomodoroActivityModel.h; sourceTree = ""; };
107 | 8E2668001A5AF05800C36D0C /* KTPomodoroActivityModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KTPomodoroActivityModel.m; path = Model/KTPomodoroActivityModel.m; sourceTree = ""; };
108 | 8E64C1041A5F4B2700A4D526 /* KTPomodoroTaskConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KTPomodoroTaskConstants.h; path = Model/KTPomodoroTaskConstants.h; sourceTree = ""; };
109 | 8E64C1051A5F4B2700A4D526 /* KTPomodoroTaskConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KTPomodoroTaskConstants.m; path = Model/KTPomodoroTaskConstants.m; sourceTree = ""; };
110 | 8E64C1081A5F585100A4D526 /* PomodoroFinishedPayload.apns */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PomodoroFinishedPayload.apns; sourceTree = ""; };
111 | 8E64C1681A5F608800A4D526 /* KTWatchPomodoroCompletedNotificationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KTWatchPomodoroCompletedNotificationController.h; sourceTree = ""; };
112 | 8E64C1691A5F608800A4D526 /* KTWatchPomodoroCompletedNotificationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KTWatchPomodoroCompletedNotificationController.m; sourceTree = ""; };
113 | 8EC91CB21A71911B007D0CD6 /* KTSharedUserDefaults.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KTSharedUserDefaults.h; path = Utils/KTSharedUserDefaults.h; sourceTree = ""; };
114 | 8EC91CB31A71911B007D0CD6 /* KTSharedUserDefaults.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KTSharedUserDefaults.m; path = Utils/KTSharedUserDefaults.m; sourceTree = ""; };
115 | 8EC91CB61A719268007D0CD6 /* KTActiveActivityState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KTActiveActivityState.h; path = Model/KTActiveActivityState.h; sourceTree = ""; };
116 | 8EC91CB71A719268007D0CD6 /* KTActiveActivityState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KTActiveActivityState.m; path = Model/KTActiveActivityState.m; sourceTree = ""; };
117 | 8EC91CBA1A719806007D0CD6 /* KTActivityManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KTActivityManager.h; path = Utils/KTActivityManager.h; sourceTree = ""; };
118 | 8EC91CBB1A719806007D0CD6 /* KTActivityManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KTActivityManager.m; path = Utils/KTActivityManager.m; sourceTree = ""; };
119 | 8EE78ABA1A8AE2E100F8A225 /* Settings-Watch.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = "Settings-Watch.bundle"; path = "Resources/Shared/Settings-Watch.bundle"; sourceTree = ""; };
120 | 8EF55C281A54DFC2002962DF /* KTPomodoro.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KTPomodoro.app; sourceTree = BUILT_PRODUCTS_DIR; };
121 | 8EF55C2C1A54DFC2002962DF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
122 | 8EF55C2D1A54DFC2002962DF /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
123 | 8EF55C2F1A54DFC2002962DF /* KTAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KTAppDelegate.h; sourceTree = ""; };
124 | 8EF55C301A54DFC2002962DF /* KTAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KTAppDelegate.m; sourceTree = ""; };
125 | 8EF55C3B1A54DFC2002962DF /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
126 | 8EF55C3E1A54DFC2002962DF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
127 | 8EF55C441A54DFC2002962DF /* KTPomodoroTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KTPomodoroTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
128 | 8EF55C491A54DFC2002962DF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
129 | 8EF55C4A1A54DFC2002962DF /* KTPomodoroTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KTPomodoroTests.m; sourceTree = ""; };
130 | 8EF55C5D1A54E29F002962DF /* KTCoreDataStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KTCoreDataStack.h; path = Model/KTCoreDataStack.h; sourceTree = ""; };
131 | 8EF55C5E1A54E29F002962DF /* KTCoreDataStack.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KTCoreDataStack.m; path = Model/KTCoreDataStack.m; sourceTree = ""; };
132 | 8EF55C631A54E4AD002962DF /* KTPomodoroTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KTPomodoroTableViewController.h; path = "View Controller/KTPomodoroTableViewController.h"; sourceTree = ""; };
133 | 8EF55C641A54E4AD002962DF /* KTPomodoroTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KTPomodoroTableViewController.m; path = "View Controller/KTPomodoroTableViewController.m"; sourceTree = ""; };
134 | 8EF55C691A54EA82002962DF /* KTPomodoroModel.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = KTPomodoroModel.xcdatamodel; sourceTree = ""; };
135 | 8EF55C6B1A54EBC4002962DF /* KTPomodoroTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = KTPomodoroTableViewCell.xib; path = Resources/KTPomodoroTableViewCell.xib; sourceTree = ""; };
136 | 8EF55C6D1A54EC48002962DF /* KTPomodoroTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KTPomodoroTableViewCell.h; path = "View Controller/KTPomodoroTableViewCell.h"; sourceTree = ""; };
137 | 8EF55C6E1A54EC48002962DF /* KTPomodoroTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KTPomodoroTableViewCell.m; path = "View Controller/KTPomodoroTableViewCell.m"; sourceTree = ""; };
138 | 8EF55C701A54F59B002962DF /* KTPomodoro.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = KTPomodoro.entitlements; sourceTree = ""; };
139 | 8EF5AF271A60631000A40CE8 /* TaskCompletedPayload.apns */ = {isa = PBXFileReference; lastKnownFileType = text; path = TaskCompletedPayload.apns; sourceTree = ""; };
140 | 8EF5AF281A6063E500A40CE8 /* KTWatchTaskCompletedNotificationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KTWatchTaskCompletedNotificationController.h; sourceTree = ""; };
141 | 8EF5AF291A6063E500A40CE8 /* KTWatchTaskCompletedNotificationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KTWatchTaskCompletedNotificationController.m; sourceTree = ""; };
142 | 8EF5AF2C1A60652D00A40CE8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/KTWatchTaskCompletedNotificationStoryboard.storyboard; sourceTree = ""; };
143 | 8EF5AF2E1A60916700A40CE8 /* KTWatchAddTaskRowInterfaceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KTWatchAddTaskRowInterfaceController.h; sourceTree = ""; };
144 | 8EF5AF2F1A60916700A40CE8 /* KTWatchAddTaskRowInterfaceController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KTWatchAddTaskRowInterfaceController.m; sourceTree = ""; };
145 | 8EF5AF311A60955E00A40CE8 /* KTWatchInterfaceAddTaskInterfaceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KTWatchInterfaceAddTaskInterfaceController.h; sourceTree = ""; };
146 | 8EF5AF321A60955E00A40CE8 /* KTWatchInterfaceAddTaskInterfaceController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KTWatchInterfaceAddTaskInterfaceController.m; sourceTree = ""; };
147 | /* End PBXFileReference section */
148 |
149 | /* Begin PBXFrameworksBuildPhase section */
150 | 8E0F773B1A55D0CF0008C4ED /* Frameworks */ = {
151 | isa = PBXFrameworksBuildPhase;
152 | buildActionMask = 2147483647;
153 | files = (
154 | );
155 | runOnlyForDeploymentPostprocessing = 0;
156 | };
157 | 8EF55C251A54DFC1002962DF /* Frameworks */ = {
158 | isa = PBXFrameworksBuildPhase;
159 | buildActionMask = 2147483647;
160 | files = (
161 | );
162 | runOnlyForDeploymentPostprocessing = 0;
163 | };
164 | 8EF55C411A54DFC2002962DF /* Frameworks */ = {
165 | isa = PBXFrameworksBuildPhase;
166 | buildActionMask = 2147483647;
167 | files = (
168 | );
169 | runOnlyForDeploymentPostprocessing = 0;
170 | };
171 | /* End PBXFrameworksBuildPhase section */
172 |
173 | /* Begin PBXGroup section */
174 | 8E0F77361A55CB0C0008C4ED /* Utils */ = {
175 | isa = PBXGroup;
176 | children = (
177 | 8EC91CB21A71911B007D0CD6 /* KTSharedUserDefaults.h */,
178 | 8EC91CB31A71911B007D0CD6 /* KTSharedUserDefaults.m */,
179 | 8EC91CBA1A719806007D0CD6 /* KTActivityManager.h */,
180 | 8EC91CBB1A719806007D0CD6 /* KTActivityManager.m */,
181 | );
182 | name = Utils;
183 | sourceTree = "";
184 | };
185 | 8E0F773F1A55D0CF0008C4ED /* KTPomodoro WatchKit Extension */ = {
186 | isa = PBXGroup;
187 | children = (
188 | 8E0F77681A55D6E40008C4ED /* KTPomodoro WatchKit Extension.entitlements */,
189 | 8E0F77421A55D0CF0008C4ED /* KTWatchInterfaceController.h */,
190 | 8E0F77431A55D0CF0008C4ED /* KTWatchInterfaceController.m */,
191 | 8E0F77701A55E09D0008C4ED /* KTWatchTasksListInterfaceController.h */,
192 | 8E0F77711A55E09D0008C4ED /* KTWatchTasksListInterfaceController.m */,
193 | 8E0F776D1A55E0770008C4ED /* KTWatchTasksRowInterfaceController.h */,
194 | 8E0F776E1A55E0770008C4ED /* KTWatchTasksRowInterfaceController.m */,
195 | 8EF5AF2E1A60916700A40CE8 /* KTWatchAddTaskRowInterfaceController.h */,
196 | 8EF5AF2F1A60916700A40CE8 /* KTWatchAddTaskRowInterfaceController.m */,
197 | 8EF5AF311A60955E00A40CE8 /* KTWatchInterfaceAddTaskInterfaceController.h */,
198 | 8EF5AF321A60955E00A40CE8 /* KTWatchInterfaceAddTaskInterfaceController.m */,
199 | 8E64C1681A5F608800A4D526 /* KTWatchPomodoroCompletedNotificationController.h */,
200 | 8E64C1691A5F608800A4D526 /* KTWatchPomodoroCompletedNotificationController.m */,
201 | 8EF5AF281A6063E500A40CE8 /* KTWatchTaskCompletedNotificationController.h */,
202 | 8EF5AF291A6063E500A40CE8 /* KTWatchTaskCompletedNotificationController.m */,
203 | 8E0F77451A55D0CF0008C4ED /* KTWatchGlanceController.h */,
204 | 8E0F77461A55D0CF0008C4ED /* KTWatchGlanceController.m */,
205 | 8E0F77481A55D0CF0008C4ED /* Images.xcassets */,
206 | 8E0F77401A55D0CF0008C4ED /* Supporting Files */,
207 | );
208 | path = "KTPomodoro WatchKit Extension";
209 | sourceTree = "";
210 | };
211 | 8E0F77401A55D0CF0008C4ED /* Supporting Files */ = {
212 | isa = PBXGroup;
213 | children = (
214 | 8E0F77411A55D0CF0008C4ED /* Info.plist */,
215 | 8E64C1081A5F585100A4D526 /* PomodoroFinishedPayload.apns */,
216 | 8EF5AF271A60631000A40CE8 /* TaskCompletedPayload.apns */,
217 | );
218 | name = "Supporting Files";
219 | sourceTree = "";
220 | };
221 | 8E0F77501A55D0CF0008C4ED /* KTPomodoro WatchKit App */ = {
222 | isa = PBXGroup;
223 | children = (
224 | 8E0F77531A55D0CF0008C4ED /* Interface.storyboard */,
225 | 8EF5AF2B1A60652D00A40CE8 /* KTWatchTaskCompletedNotificationStoryboard.storyboard */,
226 | 8E0F77561A55D0CF0008C4ED /* Images.xcassets */,
227 | 8E0F77511A55D0CF0008C4ED /* Supporting Files */,
228 | );
229 | path = "KTPomodoro WatchKit App";
230 | sourceTree = "";
231 | };
232 | 8E0F77511A55D0CF0008C4ED /* Supporting Files */ = {
233 | isa = PBXGroup;
234 | children = (
235 | 8E0F77521A55D0CF0008C4ED /* Info.plist */,
236 | );
237 | name = "Supporting Files";
238 | sourceTree = "";
239 | };
240 | 8EE78AB91A8AE2B900F8A225 /* Shared */ = {
241 | isa = PBXGroup;
242 | children = (
243 | 8EE78ABA1A8AE2E100F8A225 /* Settings-Watch.bundle */,
244 | );
245 | name = Shared;
246 | sourceTree = "";
247 | };
248 | 8EF55C1F1A54DFC1002962DF = {
249 | isa = PBXGroup;
250 | children = (
251 | 8EF55C2A1A54DFC2002962DF /* KTPomodoro */,
252 | 8EF55C471A54DFC2002962DF /* KTPomodoroTests */,
253 | 8E0F773F1A55D0CF0008C4ED /* KTPomodoro WatchKit Extension */,
254 | 8E0F77501A55D0CF0008C4ED /* KTPomodoro WatchKit App */,
255 | 8EF55C291A54DFC2002962DF /* Products */,
256 | );
257 | sourceTree = "";
258 | };
259 | 8EF55C291A54DFC2002962DF /* Products */ = {
260 | isa = PBXGroup;
261 | children = (
262 | 8EF55C281A54DFC2002962DF /* KTPomodoro.app */,
263 | 8EF55C441A54DFC2002962DF /* KTPomodoroTests.xctest */,
264 | 8E0F773E1A55D0CF0008C4ED /* KTPomodoro WatchKit Extension.appex */,
265 | 8E0F774C1A55D0CF0008C4ED /* KTPomodoro WatchKit App.app */,
266 | );
267 | name = Products;
268 | sourceTree = "";
269 | };
270 | 8EF55C2A1A54DFC2002962DF /* KTPomodoro */ = {
271 | isa = PBXGroup;
272 | children = (
273 | 8EF55C701A54F59B002962DF /* KTPomodoro.entitlements */,
274 | 8EF55C2F1A54DFC2002962DF /* KTAppDelegate.h */,
275 | 8EF55C301A54DFC2002962DF /* KTAppDelegate.m */,
276 | 8EF55C591A54E192002962DF /* Model */,
277 | 8E0F77361A55CB0C0008C4ED /* Utils */,
278 | 8EF55C551A54E061002962DF /* View Controllers */,
279 | 8EF55C541A54E006002962DF /* Resources */,
280 | 8EF55C2B1A54DFC2002962DF /* Supporting Files */,
281 | );
282 | path = KTPomodoro;
283 | sourceTree = "";
284 | };
285 | 8EF55C2B1A54DFC2002962DF /* Supporting Files */ = {
286 | isa = PBXGroup;
287 | children = (
288 | 8EF55C2C1A54DFC2002962DF /* Info.plist */,
289 | 8EF55C2D1A54DFC2002962DF /* main.m */,
290 | );
291 | name = "Supporting Files";
292 | sourceTree = "";
293 | };
294 | 8EF55C471A54DFC2002962DF /* KTPomodoroTests */ = {
295 | isa = PBXGroup;
296 | children = (
297 | 8EF55C4A1A54DFC2002962DF /* KTPomodoroTests.m */,
298 | 8EF55C481A54DFC2002962DF /* Supporting Files */,
299 | );
300 | path = KTPomodoroTests;
301 | sourceTree = "";
302 | };
303 | 8EF55C481A54DFC2002962DF /* Supporting Files */ = {
304 | isa = PBXGroup;
305 | children = (
306 | 8EF55C491A54DFC2002962DF /* Info.plist */,
307 | );
308 | name = "Supporting Files";
309 | sourceTree = "";
310 | };
311 | 8EF55C541A54E006002962DF /* Resources */ = {
312 | isa = PBXGroup;
313 | children = (
314 | 8EE78AB91A8AE2B900F8A225 /* Shared */,
315 | 8EF55C3B1A54DFC2002962DF /* Images.xcassets */,
316 | 8EF55C3D1A54DFC2002962DF /* LaunchScreen.xib */,
317 | 8EF55C681A54EA82002962DF /* KTPomodoroModel.xcdatamodeld */,
318 | 8EF55C6B1A54EBC4002962DF /* KTPomodoroTableViewCell.xib */,
319 | );
320 | name = Resources;
321 | sourceTree = "";
322 | };
323 | 8EF55C551A54E061002962DF /* View Controllers */ = {
324 | isa = PBXGroup;
325 | children = (
326 | 8EF55C631A54E4AD002962DF /* KTPomodoroTableViewController.h */,
327 | 8EF55C641A54E4AD002962DF /* KTPomodoroTableViewController.m */,
328 | 8EF55C6D1A54EC48002962DF /* KTPomodoroTableViewCell.h */,
329 | 8EF55C6E1A54EC48002962DF /* KTPomodoroTableViewCell.m */,
330 | );
331 | name = "View Controllers";
332 | sourceTree = "";
333 | };
334 | 8EF55C591A54E192002962DF /* Model */ = {
335 | isa = PBXGroup;
336 | children = (
337 | 8EC91CB61A719268007D0CD6 /* KTActiveActivityState.h */,
338 | 8EC91CB71A719268007D0CD6 /* KTActiveActivityState.m */,
339 | 8E2667FF1A5AF05800C36D0C /* KTPomodoroActivityModel.h */,
340 | 8E2668001A5AF05800C36D0C /* KTPomodoroActivityModel.m */,
341 | 8EF55C5D1A54E29F002962DF /* KTCoreDataStack.h */,
342 | 8EF55C5E1A54E29F002962DF /* KTCoreDataStack.m */,
343 | 8E64C1041A5F4B2700A4D526 /* KTPomodoroTaskConstants.h */,
344 | 8E64C1051A5F4B2700A4D526 /* KTPomodoroTaskConstants.m */,
345 | );
346 | name = Model;
347 | sourceTree = "";
348 | };
349 | /* End PBXGroup section */
350 |
351 | /* Begin PBXNativeTarget section */
352 | 8E0F773D1A55D0CF0008C4ED /* KTPomodoro WatchKit Extension */ = {
353 | isa = PBXNativeTarget;
354 | buildConfigurationList = 8E0F775E1A55D0CF0008C4ED /* Build configuration list for PBXNativeTarget "KTPomodoro WatchKit Extension" */;
355 | buildPhases = (
356 | 8E0F773A1A55D0CF0008C4ED /* Sources */,
357 | 8E0F773B1A55D0CF0008C4ED /* Frameworks */,
358 | 8E0F773C1A55D0CF0008C4ED /* Resources */,
359 | );
360 | buildRules = (
361 | );
362 | dependencies = (
363 | 8E0F774F1A55D0CF0008C4ED /* PBXTargetDependency */,
364 | );
365 | name = "KTPomodoro WatchKit Extension";
366 | productName = "KTPomodoro WatchKit Extension";
367 | productReference = 8E0F773E1A55D0CF0008C4ED /* KTPomodoro WatchKit Extension.appex */;
368 | productType = "com.apple.product-type.watchkit-extension";
369 | };
370 | 8E0F774B1A55D0CF0008C4ED /* KTPomodoro WatchKit App */ = {
371 | isa = PBXNativeTarget;
372 | buildConfigurationList = 8E0F775B1A55D0CF0008C4ED /* Build configuration list for PBXNativeTarget "KTPomodoro WatchKit App" */;
373 | buildPhases = (
374 | 8E0F774A1A55D0CF0008C4ED /* Resources */,
375 | );
376 | buildRules = (
377 | );
378 | dependencies = (
379 | );
380 | name = "KTPomodoro WatchKit App";
381 | productName = "KTPomodoro WatchKit App";
382 | productReference = 8E0F774C1A55D0CF0008C4ED /* KTPomodoro WatchKit App.app */;
383 | productType = "com.apple.product-type.application.watchapp";
384 | };
385 | 8EF55C271A54DFC1002962DF /* KTPomodoro */ = {
386 | isa = PBXNativeTarget;
387 | buildConfigurationList = 8EF55C4E1A54DFC2002962DF /* Build configuration list for PBXNativeTarget "KTPomodoro" */;
388 | buildPhases = (
389 | 8EF55C241A54DFC1002962DF /* Sources */,
390 | 8EF55C251A54DFC1002962DF /* Frameworks */,
391 | 8EF55C261A54DFC1002962DF /* Resources */,
392 | 8E0F77611A55D0CF0008C4ED /* Embed App Extensions */,
393 | );
394 | buildRules = (
395 | );
396 | dependencies = (
397 | 8E0F77591A55D0CF0008C4ED /* PBXTargetDependency */,
398 | );
399 | name = KTPomodoro;
400 | productName = KTPomodoro;
401 | productReference = 8EF55C281A54DFC2002962DF /* KTPomodoro.app */;
402 | productType = "com.apple.product-type.application";
403 | };
404 | 8EF55C431A54DFC2002962DF /* KTPomodoroTests */ = {
405 | isa = PBXNativeTarget;
406 | buildConfigurationList = 8EF55C511A54DFC2002962DF /* Build configuration list for PBXNativeTarget "KTPomodoroTests" */;
407 | buildPhases = (
408 | 8EF55C401A54DFC2002962DF /* Sources */,
409 | 8EF55C411A54DFC2002962DF /* Frameworks */,
410 | 8EF55C421A54DFC2002962DF /* Resources */,
411 | );
412 | buildRules = (
413 | );
414 | dependencies = (
415 | 8EF55C461A54DFC2002962DF /* PBXTargetDependency */,
416 | );
417 | name = KTPomodoroTests;
418 | productName = KTPomodoroTests;
419 | productReference = 8EF55C441A54DFC2002962DF /* KTPomodoroTests.xctest */;
420 | productType = "com.apple.product-type.bundle.unit-test";
421 | };
422 | /* End PBXNativeTarget section */
423 |
424 | /* Begin PBXProject section */
425 | 8EF55C201A54DFC1002962DF /* Project object */ = {
426 | isa = PBXProject;
427 | attributes = {
428 | CLASSPREFIX = KT;
429 | LastUpgradeCheck = 0620;
430 | ORGANIZATIONNAME = "Kenny Tang";
431 | TargetAttributes = {
432 | 8E0F773D1A55D0CF0008C4ED = {
433 | CreatedOnToolsVersion = 6.2;
434 | DevelopmentTeam = Y54H2D8RT6;
435 | SystemCapabilities = {
436 | com.apple.ApplicationGroups.iOS = {
437 | enabled = 1;
438 | };
439 | };
440 | };
441 | 8E0F774B1A55D0CF0008C4ED = {
442 | CreatedOnToolsVersion = 6.2;
443 | };
444 | 8EF55C271A54DFC1002962DF = {
445 | CreatedOnToolsVersion = 6.2;
446 | DevelopmentTeam = Y54H2D8RT6;
447 | SystemCapabilities = {
448 | com.apple.ApplicationGroups.iOS = {
449 | enabled = 1;
450 | };
451 | };
452 | };
453 | 8EF55C431A54DFC2002962DF = {
454 | CreatedOnToolsVersion = 6.2;
455 | TestTargetID = 8EF55C271A54DFC1002962DF;
456 | };
457 | };
458 | };
459 | buildConfigurationList = 8EF55C231A54DFC1002962DF /* Build configuration list for PBXProject "KTPomodoro" */;
460 | compatibilityVersion = "Xcode 3.2";
461 | developmentRegion = English;
462 | hasScannedForEncodings = 0;
463 | knownRegions = (
464 | en,
465 | Base,
466 | );
467 | mainGroup = 8EF55C1F1A54DFC1002962DF;
468 | productRefGroup = 8EF55C291A54DFC2002962DF /* Products */;
469 | projectDirPath = "";
470 | projectRoot = "";
471 | targets = (
472 | 8EF55C271A54DFC1002962DF /* KTPomodoro */,
473 | 8EF55C431A54DFC2002962DF /* KTPomodoroTests */,
474 | 8E0F773D1A55D0CF0008C4ED /* KTPomodoro WatchKit Extension */,
475 | 8E0F774B1A55D0CF0008C4ED /* KTPomodoro WatchKit App */,
476 | );
477 | };
478 | /* End PBXProject section */
479 |
480 | /* Begin PBXResourcesBuildPhase section */
481 | 8E0F773C1A55D0CF0008C4ED /* Resources */ = {
482 | isa = PBXResourcesBuildPhase;
483 | buildActionMask = 2147483647;
484 | files = (
485 | 8E0F774D1A55D0CF0008C4ED /* KTPomodoro WatchKit App.app in Resources */,
486 | 8E362A431A8FE6D4006DD649 /* Settings-Watch.bundle in Resources */,
487 | 8E64C1091A5F585100A4D526 /* PomodoroFinishedPayload.apns in Resources */,
488 | 8E0F77691A55D7CB0008C4ED /* KTPomodoroModel.xcdatamodeld in Resources */,
489 | 8E0F77491A55D0CF0008C4ED /* Images.xcassets in Resources */,
490 | );
491 | runOnlyForDeploymentPostprocessing = 0;
492 | };
493 | 8E0F774A1A55D0CF0008C4ED /* Resources */ = {
494 | isa = PBXResourcesBuildPhase;
495 | buildActionMask = 2147483647;
496 | files = (
497 | 8EF5AF2D1A60652D00A40CE8 /* KTWatchTaskCompletedNotificationStoryboard.storyboard in Resources */,
498 | 8E0F77551A55D0CF0008C4ED /* Interface.storyboard in Resources */,
499 | 8E0F77571A55D0CF0008C4ED /* Images.xcassets in Resources */,
500 | );
501 | runOnlyForDeploymentPostprocessing = 0;
502 | };
503 | 8EF55C261A54DFC1002962DF /* Resources */ = {
504 | isa = PBXResourcesBuildPhase;
505 | buildActionMask = 2147483647;
506 | files = (
507 | 8EF55C6C1A54EBC4002962DF /* KTPomodoroTableViewCell.xib in Resources */,
508 | 8EF55C3F1A54DFC2002962DF /* LaunchScreen.xib in Resources */,
509 | 8EE78ABB1A8AE2E100F8A225 /* Settings-Watch.bundle in Resources */,
510 | 8EF55C3C1A54DFC2002962DF /* Images.xcassets in Resources */,
511 | );
512 | runOnlyForDeploymentPostprocessing = 0;
513 | };
514 | 8EF55C421A54DFC2002962DF /* Resources */ = {
515 | isa = PBXResourcesBuildPhase;
516 | buildActionMask = 2147483647;
517 | files = (
518 | );
519 | runOnlyForDeploymentPostprocessing = 0;
520 | };
521 | /* End PBXResourcesBuildPhase section */
522 |
523 | /* Begin PBXSourcesBuildPhase section */
524 | 8E0F773A1A55D0CF0008C4ED /* Sources */ = {
525 | isa = PBXSourcesBuildPhase;
526 | buildActionMask = 2147483647;
527 | files = (
528 | 8E0F77721A55E09D0008C4ED /* KTWatchTasksListInterfaceController.m in Sources */,
529 | 8EC91CB51A7191E2007D0CD6 /* KTSharedUserDefaults.m in Sources */,
530 | 8E64C16A1A5F608800A4D526 /* KTWatchPomodoroCompletedNotificationController.m in Sources */,
531 | 8EC91CBD1A719806007D0CD6 /* KTActivityManager.m in Sources */,
532 | 8E0F77631A55D0FC0008C4ED /* KTCoreDataStack.m in Sources */,
533 | 8EF5AF331A60955E00A40CE8 /* KTWatchInterfaceAddTaskInterfaceController.m in Sources */,
534 | 8EC91CB91A719268007D0CD6 /* KTActiveActivityState.m in Sources */,
535 | 8E64C1071A5F4B2700A4D526 /* KTPomodoroTaskConstants.m in Sources */,
536 | 8EF5AF2A1A6063E500A40CE8 /* KTWatchTaskCompletedNotificationController.m in Sources */,
537 | 8E0F776F1A55E0770008C4ED /* KTWatchTasksRowInterfaceController.m in Sources */,
538 | 8E0F77441A55D0CF0008C4ED /* KTWatchInterfaceController.m in Sources */,
539 | 8EF5AF301A60916700A40CE8 /* KTWatchAddTaskRowInterfaceController.m in Sources */,
540 | 8E0F77471A55D0CF0008C4ED /* KTWatchGlanceController.m in Sources */,
541 | 8E2668021A5AF05800C36D0C /* KTPomodoroActivityModel.m in Sources */,
542 | );
543 | runOnlyForDeploymentPostprocessing = 0;
544 | };
545 | 8EF55C241A54DFC1002962DF /* Sources */ = {
546 | isa = PBXSourcesBuildPhase;
547 | buildActionMask = 2147483647;
548 | files = (
549 | 8EC91CB41A71911B007D0CD6 /* KTSharedUserDefaults.m in Sources */,
550 | 8EF55C311A54DFC2002962DF /* KTAppDelegate.m in Sources */,
551 | 8EF55C651A54E4AD002962DF /* KTPomodoroTableViewController.m in Sources */,
552 | 8EF55C2E1A54DFC2002962DF /* main.m in Sources */,
553 | 8EF55C5F1A54E29F002962DF /* KTCoreDataStack.m in Sources */,
554 | 8E2668011A5AF05800C36D0C /* KTPomodoroActivityModel.m in Sources */,
555 | 8EF55C6F1A54EC48002962DF /* KTPomodoroTableViewCell.m in Sources */,
556 | 8EC91CB81A719268007D0CD6 /* KTActiveActivityState.m in Sources */,
557 | 8EC91CBC1A719806007D0CD6 /* KTActivityManager.m in Sources */,
558 | 8E64C1061A5F4B2700A4D526 /* KTPomodoroTaskConstants.m in Sources */,
559 | 8EF55C6A1A54EA82002962DF /* KTPomodoroModel.xcdatamodeld in Sources */,
560 | );
561 | runOnlyForDeploymentPostprocessing = 0;
562 | };
563 | 8EF55C401A54DFC2002962DF /* Sources */ = {
564 | isa = PBXSourcesBuildPhase;
565 | buildActionMask = 2147483647;
566 | files = (
567 | 8EF55C4B1A54DFC2002962DF /* KTPomodoroTests.m in Sources */,
568 | );
569 | runOnlyForDeploymentPostprocessing = 0;
570 | };
571 | /* End PBXSourcesBuildPhase section */
572 |
573 | /* Begin PBXTargetDependency section */
574 | 8E0F774F1A55D0CF0008C4ED /* PBXTargetDependency */ = {
575 | isa = PBXTargetDependency;
576 | target = 8E0F774B1A55D0CF0008C4ED /* KTPomodoro WatchKit App */;
577 | targetProxy = 8E0F774E1A55D0CF0008C4ED /* PBXContainerItemProxy */;
578 | };
579 | 8E0F77591A55D0CF0008C4ED /* PBXTargetDependency */ = {
580 | isa = PBXTargetDependency;
581 | target = 8E0F773D1A55D0CF0008C4ED /* KTPomodoro WatchKit Extension */;
582 | targetProxy = 8E0F77581A55D0CF0008C4ED /* PBXContainerItemProxy */;
583 | };
584 | 8EF55C461A54DFC2002962DF /* PBXTargetDependency */ = {
585 | isa = PBXTargetDependency;
586 | target = 8EF55C271A54DFC1002962DF /* KTPomodoro */;
587 | targetProxy = 8EF55C451A54DFC2002962DF /* PBXContainerItemProxy */;
588 | };
589 | /* End PBXTargetDependency section */
590 |
591 | /* Begin PBXVariantGroup section */
592 | 8E0F77531A55D0CF0008C4ED /* Interface.storyboard */ = {
593 | isa = PBXVariantGroup;
594 | children = (
595 | 8E0F77541A55D0CF0008C4ED /* Base */,
596 | );
597 | name = Interface.storyboard;
598 | sourceTree = "";
599 | };
600 | 8EF55C3D1A54DFC2002962DF /* LaunchScreen.xib */ = {
601 | isa = PBXVariantGroup;
602 | children = (
603 | 8EF55C3E1A54DFC2002962DF /* Base */,
604 | );
605 | name = LaunchScreen.xib;
606 | sourceTree = "";
607 | };
608 | 8EF5AF2B1A60652D00A40CE8 /* KTWatchTaskCompletedNotificationStoryboard.storyboard */ = {
609 | isa = PBXVariantGroup;
610 | children = (
611 | 8EF5AF2C1A60652D00A40CE8 /* Base */,
612 | );
613 | name = KTWatchTaskCompletedNotificationStoryboard.storyboard;
614 | sourceTree = "";
615 | };
616 | /* End PBXVariantGroup section */
617 |
618 | /* Begin XCBuildConfiguration section */
619 | 8E0F775C1A55D0CF0008C4ED /* Debug */ = {
620 | isa = XCBuildConfiguration;
621 | buildSettings = {
622 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
623 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
624 | GCC_PREPROCESSOR_DEFINITIONS = (
625 | "DEBUG=1",
626 | "$(inherited)",
627 | );
628 | IBSC_MODULE = KTPomodoro_WatchKit_Extension;
629 | INFOPLIST_FILE = "KTPomodoro WatchKit App/Info.plist";
630 | PRODUCT_NAME = "$(TARGET_NAME)";
631 | SKIP_INSTALL = YES;
632 | TARGETED_DEVICE_FAMILY = 4;
633 | "TARGETED_DEVICE_FAMILY[sdk=iphonesimulator*]" = "1,4";
634 | };
635 | name = Debug;
636 | };
637 | 8E0F775D1A55D0CF0008C4ED /* Release */ = {
638 | isa = XCBuildConfiguration;
639 | buildSettings = {
640 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
641 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
642 | IBSC_MODULE = KTPomodoro_WatchKit_Extension;
643 | INFOPLIST_FILE = "KTPomodoro WatchKit App/Info.plist";
644 | PRODUCT_NAME = "$(TARGET_NAME)";
645 | SKIP_INSTALL = YES;
646 | TARGETED_DEVICE_FAMILY = 4;
647 | "TARGETED_DEVICE_FAMILY[sdk=iphonesimulator*]" = "1,4";
648 | };
649 | name = Release;
650 | };
651 | 8E0F775F1A55D0CF0008C4ED /* Debug */ = {
652 | isa = XCBuildConfiguration;
653 | buildSettings = {
654 | CODE_SIGN_ENTITLEMENTS = "KTPomodoro WatchKit Extension/KTPomodoro WatchKit Extension.entitlements";
655 | CODE_SIGN_IDENTITY = "iPhone Developer: Kenny Tang (3ZSQ9FX37R)";
656 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
657 | GCC_PREPROCESSOR_DEFINITIONS = (
658 | "DEBUG=1",
659 | "$(inherited)",
660 | );
661 | INFOPLIST_FILE = "KTPomodoro WatchKit Extension/Info.plist";
662 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
663 | PRODUCT_NAME = "${TARGET_NAME}";
664 | PROVISIONING_PROFILE = "98320b9c-a4f5-426d-87a1-5de36cea06e8";
665 | SKIP_INSTALL = YES;
666 | };
667 | name = Debug;
668 | };
669 | 8E0F77601A55D0CF0008C4ED /* Release */ = {
670 | isa = XCBuildConfiguration;
671 | buildSettings = {
672 | CODE_SIGN_ENTITLEMENTS = "KTPomodoro WatchKit Extension/KTPomodoro WatchKit Extension.entitlements";
673 | CODE_SIGN_IDENTITY = "iPhone Developer: Kenny Tang (3ZSQ9FX37R)";
674 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
675 | INFOPLIST_FILE = "KTPomodoro WatchKit Extension/Info.plist";
676 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
677 | PRODUCT_NAME = "${TARGET_NAME}";
678 | PROVISIONING_PROFILE = "98320b9c-a4f5-426d-87a1-5de36cea06e8";
679 | SKIP_INSTALL = YES;
680 | };
681 | name = Release;
682 | };
683 | 8EF55C4C1A54DFC2002962DF /* Debug */ = {
684 | isa = XCBuildConfiguration;
685 | buildSettings = {
686 | ALWAYS_SEARCH_USER_PATHS = NO;
687 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
688 | CLANG_CXX_LIBRARY = "libc++";
689 | CLANG_ENABLE_MODULES = YES;
690 | CLANG_ENABLE_OBJC_ARC = YES;
691 | CLANG_WARN_BOOL_CONVERSION = YES;
692 | CLANG_WARN_CONSTANT_CONVERSION = YES;
693 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
694 | CLANG_WARN_EMPTY_BODY = YES;
695 | CLANG_WARN_ENUM_CONVERSION = YES;
696 | CLANG_WARN_INT_CONVERSION = YES;
697 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
698 | CLANG_WARN_UNREACHABLE_CODE = YES;
699 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
700 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
701 | COPY_PHASE_STRIP = NO;
702 | ENABLE_STRICT_OBJC_MSGSEND = YES;
703 | GCC_C_LANGUAGE_STANDARD = gnu99;
704 | GCC_DYNAMIC_NO_PIC = NO;
705 | GCC_OPTIMIZATION_LEVEL = 0;
706 | GCC_PREPROCESSOR_DEFINITIONS = (
707 | "DEBUG=1",
708 | "$(inherited)",
709 | );
710 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
711 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
712 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
713 | GCC_WARN_UNDECLARED_SELECTOR = YES;
714 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
715 | GCC_WARN_UNUSED_FUNCTION = YES;
716 | GCC_WARN_UNUSED_VARIABLE = YES;
717 | IPHONEOS_DEPLOYMENT_TARGET = 8.2;
718 | MTL_ENABLE_DEBUG_INFO = YES;
719 | ONLY_ACTIVE_ARCH = YES;
720 | SDKROOT = iphoneos;
721 | };
722 | name = Debug;
723 | };
724 | 8EF55C4D1A54DFC2002962DF /* Release */ = {
725 | isa = XCBuildConfiguration;
726 | buildSettings = {
727 | ALWAYS_SEARCH_USER_PATHS = NO;
728 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
729 | CLANG_CXX_LIBRARY = "libc++";
730 | CLANG_ENABLE_MODULES = YES;
731 | CLANG_ENABLE_OBJC_ARC = YES;
732 | CLANG_WARN_BOOL_CONVERSION = YES;
733 | CLANG_WARN_CONSTANT_CONVERSION = YES;
734 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
735 | CLANG_WARN_EMPTY_BODY = YES;
736 | CLANG_WARN_ENUM_CONVERSION = YES;
737 | CLANG_WARN_INT_CONVERSION = YES;
738 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
739 | CLANG_WARN_UNREACHABLE_CODE = YES;
740 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
741 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
742 | COPY_PHASE_STRIP = NO;
743 | ENABLE_NS_ASSERTIONS = NO;
744 | ENABLE_STRICT_OBJC_MSGSEND = YES;
745 | GCC_C_LANGUAGE_STANDARD = gnu99;
746 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
747 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
748 | GCC_WARN_UNDECLARED_SELECTOR = YES;
749 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
750 | GCC_WARN_UNUSED_FUNCTION = YES;
751 | GCC_WARN_UNUSED_VARIABLE = YES;
752 | IPHONEOS_DEPLOYMENT_TARGET = 8.2;
753 | MTL_ENABLE_DEBUG_INFO = NO;
754 | SDKROOT = iphoneos;
755 | VALIDATE_PRODUCT = YES;
756 | };
757 | name = Release;
758 | };
759 | 8EF55C4F1A54DFC2002962DF /* Debug */ = {
760 | isa = XCBuildConfiguration;
761 | buildSettings = {
762 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
763 | CODE_SIGN_ENTITLEMENTS = KTPomodoro/KTPomodoro.entitlements;
764 | CODE_SIGN_IDENTITY = "iPhone Developer: Kenny Tang (3ZSQ9FX37R)";
765 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
766 | INFOPLIST_FILE = KTPomodoro/Info.plist;
767 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
768 | PRODUCT_NAME = "$(TARGET_NAME)";
769 | PROVISIONING_PROFILE = "ce7bb023-8f2a-48f2-9f84-732bfc519fd0";
770 | };
771 | name = Debug;
772 | };
773 | 8EF55C501A54DFC2002962DF /* Release */ = {
774 | isa = XCBuildConfiguration;
775 | buildSettings = {
776 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
777 | CODE_SIGN_ENTITLEMENTS = KTPomodoro/KTPomodoro.entitlements;
778 | CODE_SIGN_IDENTITY = "iPhone Developer: Kenny Tang (3ZSQ9FX37R)";
779 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
780 | INFOPLIST_FILE = KTPomodoro/Info.plist;
781 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
782 | PRODUCT_NAME = "$(TARGET_NAME)";
783 | PROVISIONING_PROFILE = "ce7bb023-8f2a-48f2-9f84-732bfc519fd0";
784 | };
785 | name = Release;
786 | };
787 | 8EF55C521A54DFC2002962DF /* Debug */ = {
788 | isa = XCBuildConfiguration;
789 | buildSettings = {
790 | BUNDLE_LOADER = "$(TEST_HOST)";
791 | FRAMEWORK_SEARCH_PATHS = (
792 | "$(SDKROOT)/Developer/Library/Frameworks",
793 | "$(inherited)",
794 | );
795 | GCC_PREPROCESSOR_DEFINITIONS = (
796 | "DEBUG=1",
797 | "$(inherited)",
798 | );
799 | INFOPLIST_FILE = KTPomodoroTests/Info.plist;
800 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
801 | PRODUCT_NAME = "$(TARGET_NAME)";
802 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/KTPomodoro.app/KTPomodoro";
803 | };
804 | name = Debug;
805 | };
806 | 8EF55C531A54DFC2002962DF /* Release */ = {
807 | isa = XCBuildConfiguration;
808 | buildSettings = {
809 | BUNDLE_LOADER = "$(TEST_HOST)";
810 | FRAMEWORK_SEARCH_PATHS = (
811 | "$(SDKROOT)/Developer/Library/Frameworks",
812 | "$(inherited)",
813 | );
814 | INFOPLIST_FILE = KTPomodoroTests/Info.plist;
815 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
816 | PRODUCT_NAME = "$(TARGET_NAME)";
817 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/KTPomodoro.app/KTPomodoro";
818 | };
819 | name = Release;
820 | };
821 | /* End XCBuildConfiguration section */
822 |
823 | /* Begin XCConfigurationList section */
824 | 8E0F775B1A55D0CF0008C4ED /* Build configuration list for PBXNativeTarget "KTPomodoro WatchKit App" */ = {
825 | isa = XCConfigurationList;
826 | buildConfigurations = (
827 | 8E0F775C1A55D0CF0008C4ED /* Debug */,
828 | 8E0F775D1A55D0CF0008C4ED /* Release */,
829 | );
830 | defaultConfigurationIsVisible = 0;
831 | defaultConfigurationName = Release;
832 | };
833 | 8E0F775E1A55D0CF0008C4ED /* Build configuration list for PBXNativeTarget "KTPomodoro WatchKit Extension" */ = {
834 | isa = XCConfigurationList;
835 | buildConfigurations = (
836 | 8E0F775F1A55D0CF0008C4ED /* Debug */,
837 | 8E0F77601A55D0CF0008C4ED /* Release */,
838 | );
839 | defaultConfigurationIsVisible = 0;
840 | defaultConfigurationName = Release;
841 | };
842 | 8EF55C231A54DFC1002962DF /* Build configuration list for PBXProject "KTPomodoro" */ = {
843 | isa = XCConfigurationList;
844 | buildConfigurations = (
845 | 8EF55C4C1A54DFC2002962DF /* Debug */,
846 | 8EF55C4D1A54DFC2002962DF /* Release */,
847 | );
848 | defaultConfigurationIsVisible = 0;
849 | defaultConfigurationName = Release;
850 | };
851 | 8EF55C4E1A54DFC2002962DF /* Build configuration list for PBXNativeTarget "KTPomodoro" */ = {
852 | isa = XCConfigurationList;
853 | buildConfigurations = (
854 | 8EF55C4F1A54DFC2002962DF /* Debug */,
855 | 8EF55C501A54DFC2002962DF /* Release */,
856 | );
857 | defaultConfigurationIsVisible = 0;
858 | defaultConfigurationName = Release;
859 | };
860 | 8EF55C511A54DFC2002962DF /* Build configuration list for PBXNativeTarget "KTPomodoroTests" */ = {
861 | isa = XCConfigurationList;
862 | buildConfigurations = (
863 | 8EF55C521A54DFC2002962DF /* Debug */,
864 | 8EF55C531A54DFC2002962DF /* Release */,
865 | );
866 | defaultConfigurationIsVisible = 0;
867 | defaultConfigurationName = Release;
868 | };
869 | /* End XCConfigurationList section */
870 |
871 | /* Begin XCVersionGroup section */
872 | 8EF55C681A54EA82002962DF /* KTPomodoroModel.xcdatamodeld */ = {
873 | isa = XCVersionGroup;
874 | children = (
875 | 8EF55C691A54EA82002962DF /* KTPomodoroModel.xcdatamodel */,
876 | );
877 | currentVersion = 8EF55C691A54EA82002962DF /* KTPomodoroModel.xcdatamodel */;
878 | name = KTPomodoroModel.xcdatamodeld;
879 | path = Model/KTPomodoroModel.xcdatamodeld;
880 | sourceTree = "";
881 | versionGroupType = wrapper.xcdatamodel;
882 | };
883 | /* End XCVersionGroup section */
884 | };
885 | rootObject = 8EF55C201A54DFC1002962DF /* Project object */;
886 | }
887 |
--------------------------------------------------------------------------------
/KTPomodoro.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/KTPomodoro.xcodeproj/xcuserdata/ktang.xcuserdatad/xcschemes/KTPomodoro.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
77 |
83 |
84 |
85 |
86 |
87 |
88 |
94 |
96 |
102 |
103 |
104 |
105 |
107 |
108 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/KTPomodoro.xcodeproj/xcuserdata/ktang.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | KTPomodoro WatchKit - Pomo Finished Notifications.xcscheme
8 |
9 | orderHint
10 | 2
11 |
12 | KTPomodoro WatchKit - Task Finished Notifications.xcscheme
13 |
14 | orderHint
15 | 3
16 |
17 | KTPomodoro WatchKit App.xcscheme
18 |
19 | orderHint
20 | 1
21 |
22 | KTPomodoro.xcscheme
23 |
24 | orderHint
25 | 0
26 |
27 |
28 | SuppressBuildableAutocreation
29 |
30 | 8E0F773D1A55D0CF0008C4ED
31 |
32 | primary
33 |
34 |
35 | 8E0F774B1A55D0CF0008C4ED
36 |
37 | primary
38 |
39 |
40 | 8EF55C271A54DFC1002962DF
41 |
42 | primary
43 |
44 |
45 | 8EF55C431A54DFC2002962DF
46 |
47 | primary
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/KTPomodoro/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/KTPomodoro/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/KTPomodoro/Images.xcassets/tomato_app.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "tomato_app@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/KTPomodoro/Images.xcassets/tomato_app.imageset/tomato_app@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro/Images.xcassets/tomato_app.imageset/tomato_app@2x.png
--------------------------------------------------------------------------------
/KTPomodoro/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Bundle Display Name
6 | Cherry
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | com.corgitoergosum.$(PRODUCT_NAME:rfc1034identifier)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UIStatusBarStyle
34 | UIStatusBarStyleLightContent
35 | UISupportedInterfaceOrientations
36 |
37 | UIInterfaceOrientationPortrait
38 |
39 | UIViewControllerBasedStatusBarAppearance
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/KTPomodoro/KTAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // KTAppDelegate.h
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 12/31/14.
6 | // Copyright (c) 2014 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface KTAppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/KTPomodoro/KTAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 12/31/14.
6 | // Copyright (c) 2014 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import "KTAppDelegate.h"
10 | #import "KTCoreDataStack.h"
11 | #import "KTPomodoroTableViewController.h"
12 |
13 | @interface KTAppDelegate ()
14 | @end
15 |
16 | @implementation KTAppDelegate
17 |
18 |
19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
20 | // Override point for customization after application launch.
21 |
22 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
23 |
24 | UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:[KTPomodoroTableViewController new]];
25 | navigationController.navigationBar.barTintColor = [UIColor redColor];
26 | [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
27 | [[UINavigationBar appearance] setTitleTextAttributes:@{
28 | NSForegroundColorAttributeName:[UIColor whiteColor],
29 | NSFontAttributeName:[UIFont fontWithName:@"HelveticaNeue" size:20.0f]
30 | }];
31 | self.window.rootViewController = navigationController;
32 |
33 | [self.window makeKeyAndVisible];
34 |
35 | return YES;
36 | }
37 |
38 | - (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply
39 | {
40 | NSLog(@"userInfo: %@", userInfo);
41 | reply(@{});
42 | }
43 |
44 |
45 | - (void)applicationWillResignActive:(UIApplication *)application {
46 | // 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.
47 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
48 | }
49 |
50 | - (void)applicationDidEnterBackground:(UIApplication *)application {
51 | // 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.
52 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
53 | }
54 |
55 | - (void)applicationWillEnterForeground:(UIApplication *)application {
56 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
57 | }
58 |
59 | - (void)applicationDidBecomeActive:(UIApplication *)application {
60 | // 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.
61 | }
62 |
63 | - (void)applicationWillTerminate:(UIApplication *)application {
64 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
65 | // Saves changes in the application's managed object context before the application terminates.
66 | [[KTCoreDataStack sharedInstance] saveContext];
67 | }
68 |
69 | @end
70 |
--------------------------------------------------------------------------------
/KTPomodoro/KTPomodoro.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.application-groups
6 |
7 | group.com.corgitoergosum.KTPomodoro
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/KTPomodoro/Model/KTActiveActivityState.h:
--------------------------------------------------------------------------------
1 | //
2 | // KTActiveActivityState.h
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/22/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface KTActiveActivityState : NSObject
12 |
13 | @property (nonatomic) NSString *activityID;
14 | @property (nonatomic) NSNumber *status;
15 | @property (nonatomic) NSNumber *currentPomo;
16 | @property (nonatomic) NSNumber *elapsedSecs;
17 |
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/KTPomodoro/Model/KTActiveActivityState.m:
--------------------------------------------------------------------------------
1 | //
2 | // KTActiveActivityState.m
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/22/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import "KTActiveActivityState.h"
10 |
11 | @implementation KTActiveActivityState
12 |
13 | - (void)encodeWithCoder:(NSCoder *)encoder {
14 | [encoder encodeObject:self.activityID forKey:@"activityID"];
15 | [encoder encodeObject:self.status forKey:@"status"];
16 | [encoder encodeObject:self.currentPomo forKey:@"currentPomo"];
17 | [encoder encodeObject:self.elapsedSecs forKey:@"elapsedSecs"];
18 | }
19 |
20 | - (id)initWithCoder:(NSCoder *)decoder {
21 | if((self = [super init])) {
22 | self.activityID = [decoder decodeObjectForKey:@"activityID"];
23 | self.status = [decoder decodeObjectForKey:@"status"];
24 | self.currentPomo = [decoder decodeObjectForKey:@"currentPomo"];
25 | self.elapsedSecs = [decoder decodeObjectForKey:@"elapsedSecs"];
26 | }
27 | return self;
28 | }
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/KTPomodoro/Model/KTCoreDataStack.h:
--------------------------------------------------------------------------------
1 | //
2 | // KTCoreDataStack.h
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 12/31/14.
6 | // Copyright (c) 2014 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import "KTPomodoroActivityModel.h"
12 |
13 | @interface KTCoreDataStack : NSObject
14 |
15 | + (KTCoreDataStack*)sharedInstance;
16 |
17 | - (NSArray*)allTasks;
18 |
19 | @property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
20 | @property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
21 | @property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
22 |
23 | - (KTPomodoroActivityModel*)createNewTask:(NSString*)taskName taskDesc:(NSString*)description pomodoros:(NSUInteger)pomodoros;
24 |
25 | - (void)saveContext;
26 | - (NSURL *)applicationDocumentsDirectory;
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/KTPomodoro/Model/KTCoreDataStack.m:
--------------------------------------------------------------------------------
1 | //
2 | // KTCoreDataStack.m
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 12/31/14.
6 | // Copyright (c) 2014 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import "KTCoreDataStack.h"
10 | #import "KTPomodoroTaskConstants.h"
11 |
12 | // This turns storing CoreData persistance store in app container on and off.
13 | #define kKTCoreDataStackShouldUseAppContainer 0
14 |
15 |
16 | @implementation KTCoreDataStack
17 |
18 | + (KTCoreDataStack*)sharedInstance
19 | {
20 | static KTCoreDataStack* _instance;
21 | static dispatch_once_t onceToken;
22 | dispatch_once(&onceToken, ^{
23 | _instance = [KTCoreDataStack new];
24 | [_instance seedData];
25 |
26 | });
27 | return _instance;
28 | }
29 |
30 | #pragma mark - Helpers
31 |
32 | - (KTPomodoroActivityModel*)createNewTask:(NSString*)taskName taskDesc:(NSString*)description pomodoros:(NSUInteger)pomodoros
33 | {
34 | NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"KTPomodoroActivityModel" inManagedObjectContext:self.managedObjectContext];
35 |
36 | KTPomodoroActivityModel *newTask1 = (KTPomodoroActivityModel*)[[NSManagedObject alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:self.managedObjectContext];
37 | newTask1.name = taskName;
38 | newTask1.desc = description;
39 | newTask1.status = @(KTPomodoroActivityStatusStopped);
40 | newTask1.expected_pomo = @(pomodoros);
41 | newTask1.actual_pomo = @(0);
42 | newTask1.created_time = [NSDate new];
43 | newTask1.activityID = [[NSUUID UUID] UUIDString];
44 |
45 | return newTask1;
46 | }
47 |
48 | - (void)seedData
49 | {
50 | if (![[self allTasks] count]) {
51 |
52 | // Create Managed Object
53 | NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"KTPomodoroActivityModel" inManagedObjectContext:self.managedObjectContext];
54 |
55 | KTPomodoroActivityModel *newTask1 = (KTPomodoroActivityModel*)[[NSManagedObject alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:self.managedObjectContext];
56 | newTask1.activityID = [[NSUUID UUID] UUIDString];
57 | newTask1.name = @"Task 1";
58 | newTask1.desc = @"Task desc";
59 | newTask1.status = @(KTPomodoroActivityStatusStopped);
60 | newTask1.expected_pomo = @(1);
61 | newTask1.actual_pomo = @(0);
62 | newTask1.created_time = [NSDate new];
63 |
64 | KTPomodoroActivityModel *newTask2 = (KTPomodoroActivityModel*)[[NSManagedObject alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:self.managedObjectContext];
65 | newTask2.activityID = [[NSUUID UUID] UUIDString];
66 | newTask2.name = @"Task 2";
67 | newTask2.desc = @"Task desc";
68 | newTask2.status = @(KTPomodoroActivityStatusStopped);
69 | newTask2.expected_pomo = @(1);
70 | newTask2.actual_pomo = @(0);
71 | newTask2.created_time = [NSDate new];
72 |
73 | }
74 | }
75 |
76 | - (NSArray*)allTasks
77 | {
78 | NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:@"KTPomodoroActivityModel"];
79 |
80 | NSSortDescriptor *createdTimeDescriptor = [[NSSortDescriptor alloc] initWithKey:@"created_time" ascending:NO];
81 | NSSortDescriptor *inProgressStatusDescriptor = [[NSSortDescriptor alloc] initWithKey:@"status" ascending:YES];
82 |
83 | request.sortDescriptors = @[inProgressStatusDescriptor, createdTimeDescriptor];
84 |
85 | NSArray* objects = [self.managedObjectContext executeFetchRequest:request error:NULL];
86 | return objects;
87 | }
88 |
89 |
90 | #pragma mark - Core Data stack
91 |
92 | @synthesize managedObjectContext = _managedObjectContext;
93 | @synthesize managedObjectModel = _managedObjectModel;
94 | @synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
95 |
96 | - (NSURL *)applicationDocumentsDirectory {
97 | // The directory the application uses to store the Core Data store file. This code uses a directory named "com.corgitoergosum.KTPomodoro" in the application's documents directory.
98 | return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
99 | }
100 |
101 | - (NSManagedObjectModel *)managedObjectModel {
102 | // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
103 | if (_managedObjectModel != nil) {
104 | return _managedObjectModel;
105 | }
106 | NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"KTPomodoroModel" withExtension:@"momd"];
107 | _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
108 | return _managedObjectModel;
109 | }
110 |
111 | - (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
112 | // The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it.
113 | if (_persistentStoreCoordinator != nil) {
114 | return _persistentStoreCoordinator;
115 | }
116 |
117 | // Create the coordinator and store
118 |
119 | _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
120 | NSURL *storeURL = nil;
121 |
122 | #if kKTCoreDataStackShouldUseAppContainer
123 | NSString *appGroupID = @"group.com.corgitoergosum.KTPomodoro";
124 | NSFileManager *fileManager = [NSFileManager defaultManager];
125 | NSURL *appGroupURL = [fileManager containerURLForSecurityApplicationGroupIdentifier:appGroupID];
126 | storeURL = [appGroupURL URLByAppendingPathComponent:@"KTPomodoro.sqlite"];
127 |
128 | #else
129 | storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"KTPomodoro.sqlite"];
130 | #endif
131 |
132 | NSError *error = nil;
133 | NSString *failureReason = @"There was an error creating or loading the application's saved data.";
134 | if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
135 | // Report any error we got.
136 | NSMutableDictionary *dict = [NSMutableDictionary dictionary];
137 | dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data";
138 | dict[NSLocalizedFailureReasonErrorKey] = failureReason;
139 | dict[NSUnderlyingErrorKey] = error;
140 | error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
141 | // Replace this with code to handle the error appropriately.
142 | // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
143 | NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
144 | abort();
145 | }
146 |
147 | return _persistentStoreCoordinator;
148 | }
149 |
150 |
151 | - (NSManagedObjectContext *)managedObjectContext {
152 | // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
153 | if (_managedObjectContext != nil) {
154 | return _managedObjectContext;
155 | }
156 |
157 | NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
158 | if (!coordinator) {
159 | return nil;
160 | }
161 | _managedObjectContext = [[NSManagedObjectContext alloc] init];
162 | [_managedObjectContext setPersistentStoreCoordinator:coordinator];
163 | return _managedObjectContext;
164 | }
165 |
166 | #pragma mark - Core Data Saving support
167 |
168 | - (void)saveContext {
169 | NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
170 | if (managedObjectContext != nil) {
171 | NSError *error = nil;
172 | if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
173 | // Replace this implementation with code to handle the error appropriately.
174 | // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
175 | NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
176 | abort();
177 | }
178 | }
179 | }
180 |
181 | @end
182 |
--------------------------------------------------------------------------------
/KTPomodoro/Model/KTPomodoroActivityModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // KTPomodoroTask.h
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/5/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 |
13 | @interface KTPomodoroActivityModel : NSManagedObject
14 |
15 | @property (nonatomic, retain) NSString * activityID;
16 | @property (nonatomic, retain) NSNumber * actual_pomo;
17 | @property (nonatomic, retain) NSString * desc;
18 | @property (nonatomic, retain) NSNumber * expected_pomo;
19 | @property (nonatomic, retain) NSString * name;
20 | @property (nonatomic, retain) NSNumber * status;
21 | @property (nonatomic, retain) NSNumber * interruptions;
22 | @property (nonatomic, retain) NSDate * created_time;
23 |
24 | @property (nonatomic, retain) NSNumber * current_pomo;
25 | @property (nonatomic, retain) NSNumber * current_pomo_elapsed_time;
26 | @property (nonatomic, readonly) NSUInteger current_pomo_elapsed_time_int;
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/KTPomodoro/Model/KTPomodoroActivityModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // KTPomodoroTask.m
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/5/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import "KTPomodoroActivityModel.h"
10 |
11 | @implementation KTPomodoroActivityModel
12 |
13 | @dynamic activityID;
14 | @dynamic actual_pomo;
15 | @dynamic desc;
16 | @dynamic expected_pomo;
17 | @dynamic name;
18 | @dynamic status;
19 | @dynamic interruptions;
20 | @dynamic created_time;
21 | @dynamic current_pomo;
22 | @dynamic current_pomo_elapsed_time;
23 |
24 | - (NSUInteger)current_pomo_elapsed_time_int
25 | {
26 | return [self.current_pomo_elapsed_time integerValue];
27 | }
28 | @end
29 |
--------------------------------------------------------------------------------
/KTPomodoro/Model/KTPomodoroModel.xcdatamodeld/KTPomodoroModel.xcdatamodel/contents:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/KTPomodoro/Model/KTPomodoroTaskConstants.h:
--------------------------------------------------------------------------------
1 | //
2 | // KTPomodoroTaskConstants.h
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/8/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 |
13 | @interface KTPomodoroTaskConstants : NSObject
14 |
15 | typedef NS_ENUM (NSUInteger, KTPomodoroActivityStatus) {
16 | KTPomodoroActivityStatusInProgress = 0,
17 | KTPomodoroActivityStatusStopped,
18 | KTPomodoroActivityStatusCompleted,
19 | KTPomodoroActivityStatusUnknown
20 | };
21 |
22 | typedef NS_ENUM (NSUInteger, KTPomodoroStartActivityError) {
23 | KTPomodoroStartActivityOtherActivityActiveError = 0,
24 | };
25 |
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/KTPomodoro/Model/KTPomodoroTaskConstants.m:
--------------------------------------------------------------------------------
1 | //
2 | // KTPomodoroTaskConstants.m
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/8/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import "KTPomodoroTaskConstants.h"
10 |
11 | @implementation KTPomodoroTaskConstants
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/KTPomodoro/Resources/KTPomodoroTableViewCell.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
24 |
30 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/KTPomodoro/Resources/Shared/Settings-Watch.bundle/Root.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | StringsTable
6 | Root
7 | PreferenceSpecifiers
8 |
9 |
10 | Type
11 | PSToggleSwitchSpecifier
12 | Title
13 | Delete completed activities
14 | Key
15 | delete_completed_activities
16 | DefaultValue
17 |
18 |
19 |
20 | Type
21 | PSTextFieldSpecifier
22 | Title
23 | Break Length
24 | Key
25 | break_length
26 | DefaultValue
27 | 5
28 | KeyboardType
29 | NumberPad
30 |
31 |
32 | Type
33 | PSTextFieldSpecifier
34 | Title
35 | Pomo Length
36 | Key
37 | pomo_length
38 | DefaultValue
39 | 25
40 | KeyboardType
41 | NumberPad
42 |
43 |
44 | ApplicationGroupContainerIdentifier
45 | group.com.corgitoergosum.KTPomodoro
46 |
47 |
48 |
--------------------------------------------------------------------------------
/KTPomodoro/Resources/Shared/Settings-Watch.bundle/en.lproj/Root.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/KTPomodoro/Resources/Shared/Settings-Watch.bundle/en.lproj/Root.strings
--------------------------------------------------------------------------------
/KTPomodoro/Utils/KTActivityManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // KTActivityManager.h
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/22/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "KTPomodoroActivityModel.h"
11 |
12 | @protocol KTActivityManagerDelegate;
13 |
14 |
15 | @interface KTActivityManager : NSObject
16 |
17 | @property (nonatomic, weak) id delegate;
18 | @property (nonatomic, readonly) KTPomodoroActivityModel *activity;
19 |
20 | + (instancetype)sharedInstance;
21 |
22 | + (NSUInteger)pomodoroDurationMinutes;
23 |
24 | + (NSUInteger)breakDurationMinutes;
25 |
26 | + (NSUInteger)pomoRemainingMinutes:(NSUInteger)totalRemainingSecs;
27 |
28 | + (NSUInteger)pomoRemainingSecsInCurrentMinute:(NSUInteger)totalRemainingSecs;
29 |
30 |
31 | - (void)startActivity:(KTPomodoroActivityModel*)activity error:(NSError**)error;
32 |
33 | - (void)stopActivity;
34 |
35 | - (void)stopActivityOnInterruption;
36 |
37 | - (BOOL)hasOtherActiveActivityInSharedState:(NSString*)activityID;
38 |
39 | @end
40 |
41 |
42 | @protocol KTActivityManagerDelegate
43 |
44 | - (void)activityManager:(KTActivityManager*)manager activityDidUpdate:(KTPomodoroActivityModel*)activity;
45 |
46 | - (void)activityManager:(KTActivityManager*)manager activityPausedForBreak:(NSUInteger)elapsedTime;
47 |
48 | @end
--------------------------------------------------------------------------------
/KTPomodoro/Utils/KTActivityManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // KTActivityManager.m
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/22/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import "KTActivityManager.h"
10 | #import "KTActiveActivityState.h"
11 | #import "KTCoreDataStack.h"
12 | #import "KTPomodoroTaskConstants.h"
13 | #import "KTSharedUserDefaults.h"
14 |
15 |
16 | @interface KTActivityManager()
17 |
18 | @property (atomic) KTPomodoroActivityModel *activity;
19 | @property (nonatomic) NSTimer *activityTimer;
20 | @property (nonatomic) NSTimer *breakTimer;
21 | @property (nonatomic) NSUInteger currentPomo;
22 |
23 | @property (nonatomic) NSUInteger breakElapsed;
24 |
25 | @end
26 |
27 | @implementation KTActivityManager
28 |
29 | #pragma mark - Public
30 |
31 | + (instancetype)sharedInstance {
32 | static KTActivityManager *_instance;
33 | static dispatch_once_t onceToken;
34 | dispatch_once(&onceToken, ^{
35 | _instance = [KTActivityManager new];
36 | });
37 | return _instance;
38 | }
39 |
40 | + (NSUInteger)pomodoroDurationMinutes
41 | {
42 | return [KTSharedUserDefaults pomoDuration];
43 | }
44 |
45 | + (NSUInteger)breakDurationMinutes
46 | {
47 | return [KTSharedUserDefaults breakDuration];
48 | }
49 |
50 | - (void)startActivity:(KTPomodoroActivityModel*)activity error:(NSError**)error
51 | {
52 | if ([self hasOtherActiveActivityInSharedState:activity.activityID]){
53 | // log error
54 | // inform delegate
55 | *error = [NSError errorWithDomain:@"com.corgitoergosum.net" code:KTPomodoroStartActivityOtherActivityActiveError userInfo:nil];
56 |
57 | return;
58 | }
59 | if (!activity) {
60 | return;
61 | }
62 |
63 | self.activity = activity;
64 | self.activity.current_pomo_elapsed_time = @(0);
65 | self.activity.status = @(KTPomodoroActivityStatusInProgress);
66 | self.currentPomo = 0;
67 | self.breakElapsed = 0;
68 |
69 | [self updateSharedActiveActivityState:activity.activityID
70 | currentPomo:self.currentPomo
71 | status:activity.status];
72 |
73 | [self invalidateTimers];
74 |
75 | [self scheduleTimerInRunLoop:self.activityTimer];
76 |
77 | }
78 |
79 | - (void)stopActivityOnInterruption
80 | {
81 | self.activity.status = @(KTPomodoroActivityStatusStopped);
82 | [self updateSharedActiveActivityState:self.activity.activityID
83 | currentPomo:self.currentPomo
84 | status:self.activity.status];
85 |
86 |
87 | // save to disk
88 | [[KTCoreDataStack sharedInstance] saveContext];
89 |
90 | // house keeping
91 | [self resetManagerInternalState];
92 |
93 | }
94 |
95 | - (void)stopActivity
96 | {
97 | self.activity.status = @(KTPomodoroActivityStatusStopped);
98 | [self updateSharedActiveActivityState:self.activity.activityID
99 | currentPomo:self.currentPomo
100 | status:self.activity.status];
101 |
102 | // save to disk
103 | [[KTCoreDataStack sharedInstance] saveContext];
104 |
105 | // house keeping
106 | [self resetManagerInternalState];
107 |
108 | }
109 |
110 | + (NSUInteger)pomoRemainingMinutes:(NSUInteger)totalRemainingSecs
111 | {
112 | NSInteger pomodoroSecs = [KTSharedUserDefaults pomoDuration]*60 - totalRemainingSecs;
113 |
114 | NSUInteger displayMinutes = (NSUInteger)floor(pomodoroSecs/60.0f);
115 |
116 | return displayMinutes;
117 |
118 | }
119 |
120 | + (NSUInteger)pomoRemainingSecsInCurrentMinute:(NSUInteger)totalRemainingSecs
121 | {
122 | NSInteger pomodoroSecs = [KTSharedUserDefaults pomoDuration]*60 - totalRemainingSecs;
123 |
124 | NSUInteger displaySecs = (NSUInteger)pomodoroSecs%60;
125 | return displaySecs;
126 |
127 | }
128 |
129 | #pragma mark - Private
130 |
131 |
132 | #pragma mark - Lazy Loading
133 |
134 | - (NSTimer*)activityTimer
135 | {
136 | if (!_activityTimer) {
137 | _activityTimer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(activityTimerFired:) userInfo:nil repeats:YES];
138 | }
139 | return _activityTimer;
140 | }
141 |
142 | - (NSTimer*)breakTimer
143 | {
144 | if (!_breakTimer) {
145 | _breakTimer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(breakTimerFired:) userInfo:nil repeats:YES];
146 | }
147 | return _breakTimer;
148 | }
149 |
150 |
151 | #pragma mark - startActivity: helper methods
152 |
153 | - (BOOL)hasOtherActiveActivityInSharedState:(NSString*)activityID
154 | {
155 | id encodedActivity = [[KTSharedUserDefaults sharedUserDefaults] objectForKey:@"ActiveActivity"];
156 | KTActiveActivityState *activity = (KTActiveActivityState*)[NSKeyedUnarchiver unarchiveObjectWithData:encodedActivity];
157 | if (!activityID || !activity) {
158 | return NO;
159 | }
160 | return [activity.activityID isEqualToString:activityID] ? NO : YES;
161 | }
162 |
163 | - (void)updateSharedActiveActivityState:(NSString*)activityID currentPomo:(NSUInteger)currentPomo status:(NSNumber*)status
164 | {
165 | KTActiveActivityState *activity = nil;
166 |
167 | id encodedActivity = [[KTSharedUserDefaults sharedUserDefaults] objectForKey:@"ActiveActivity"];
168 | NSObject *decodedActivity = [NSKeyedUnarchiver unarchiveObjectWithData:encodedActivity];
169 |
170 | activity = (KTActiveActivityState*)decodedActivity;
171 |
172 | if (!([activity isKindOfClass:[KTActiveActivityState class]]) ||
173 | !([activity.activityID isEqualToString:activityID])){
174 | activity = [KTActiveActivityState new];
175 | activity.activityID = activityID;
176 | }
177 | activity.currentPomo = @(currentPomo);
178 | activity.status = status;
179 |
180 | if (status.integerValue == KTPomodoroActivityStatusStopped) {
181 | [[KTSharedUserDefaults sharedUserDefaults] removeObjectForKey:@"ActiveActivity"];
182 |
183 | } else {
184 | encodedActivity = [NSKeyedArchiver archivedDataWithRootObject:activity];
185 | [[KTSharedUserDefaults sharedUserDefaults] setObject:encodedActivity forKey:@"ActiveActivity"];
186 | }
187 | }
188 |
189 | - (void)invalidateTimers
190 | {
191 | [self.activityTimer invalidate];
192 | [self.breakTimer invalidate];
193 | _activityTimer = nil;
194 | _breakTimer = nil;
195 | }
196 |
197 | - (void)scheduleTimerInRunLoop:(NSTimer*)timer
198 | {
199 | [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
200 | }
201 |
202 | #pragma mark - timer helper methods
203 |
204 | - (void)activityTimerFired:(id)sender
205 | {
206 | NSUInteger currentPomoElapsed = self.activity.current_pomo_elapsed_time_int+1;
207 | self.activity.current_pomo_elapsed_time = @(currentPomoElapsed);
208 |
209 | [self.delegate activityManager:self activityDidUpdate:self.activity];
210 |
211 | if (currentPomoElapsed == [KTActivityManager pomodoroDurationMinutes]*60) {
212 |
213 | // reached end of pomo, either:
214 | self.currentPomo++;
215 |
216 | if ([self activityHasMorePomo:self.activity]) {
217 | [self pauseActivityStartBreak];
218 |
219 | } else {
220 | // complete task if this is last pomo
221 | [self completeActivityOnLastPomo];
222 | }
223 | }
224 | }
225 |
226 | - (void)breakTimerFired:(id)sender
227 | {
228 | self.breakElapsed++;
229 | if (self.breakElapsed < [KTActivityManager breakDurationMinutes]*60) {
230 | // continue break
231 | [self.delegate activityManager:self activityPausedForBreak:self.breakElapsed];
232 | } else {
233 | // end of break. stop break timer. clear state.
234 | [self invalidateTimers];
235 | self.breakElapsed = 0;
236 |
237 | // start next pomo
238 | [self startNextPomo];
239 | }
240 | }
241 |
242 | #pragma mark - breakTimerFired: helper methods
243 |
244 | - (void)startNextPomo
245 | {
246 | self.currentPomo++;
247 | self.activity.current_pomo_elapsed_time = @(0);
248 | [self scheduleTimerInRunLoop:self.activityTimer];
249 |
250 | }
251 |
252 | #pragma mark - activityTimerFired: helper methods
253 |
254 | - (BOOL)activityHasMorePomo:(KTPomodoroActivityModel*)activity
255 | {
256 | return [activity.expected_pomo integerValue]-1 > self.currentPomo;
257 | }
258 |
259 | - (void)completeActivityOnLastPomo
260 | {
261 | self.activity.status = @(KTPomodoroActivityStatusCompleted);
262 | self.activity.actual_pomo = @(self.currentPomo);
263 |
264 | // save to disk
265 | [[KTCoreDataStack sharedInstance] saveContext];
266 |
267 | // inform delegate
268 | [self.delegate activityManager:self activityDidUpdate:self.activity];
269 |
270 |
271 | // house keeping
272 | [self resetManagerInternalState];
273 |
274 | }
275 |
276 | - (void)pauseActivityStartBreak
277 | {
278 | [self stopActivityTimer];
279 | [self startBreakTimer];
280 | }
281 |
282 | #pragma mark - pauseActivityStartBreak helper method
283 |
284 | - (void)stopActivityTimer
285 | {
286 | [self.activityTimer invalidate];
287 | _activityTimer = nil;
288 | }
289 |
290 | - (void)startBreakTimer
291 | {
292 | [self.breakTimer invalidate];
293 | _breakTimer = nil;
294 | [self scheduleTimerInRunLoop:self.breakTimer];
295 | }
296 |
297 | #pragma mark - completeActivityOnLastPomo and helper method
298 |
299 | - (void)resetManagerInternalState
300 | {
301 | // clear internal state
302 | _activity = nil;
303 | [self invalidateTimers];
304 | self.currentPomo = 0;
305 | self.breakElapsed = 0;
306 |
307 | }
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 | @end
317 |
--------------------------------------------------------------------------------
/KTPomodoro/Utils/KTSharedUserDefaults.h:
--------------------------------------------------------------------------------
1 | //
2 | // KTSharedUserDefaults.h
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/22/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 | @interface KTSharedUserDefaults : NSObject
13 |
14 | + (NSUserDefaults*)sharedUserDefaults;
15 |
16 | + (BOOL)shouldAutoDeleteCompletedActivites;
17 |
18 | + (NSUInteger)pomoDuration;
19 |
20 | + (NSUInteger)breakDuration;
21 |
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/KTPomodoro/Utils/KTSharedUserDefaults.m:
--------------------------------------------------------------------------------
1 | //
2 | // KTSharedUserDefaults.m
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 1/22/15.
6 | // Copyright (c) 2015 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import "KTSharedUserDefaults.h"
10 |
11 | // This turns storing UserDefaults storing in app container on and off.
12 | #define kKTSharedUserDefaultsShouldUseAppContainer 0
13 |
14 |
15 | static NSString *kKTSharedUserDefaultsShouldAutoDeleteCompletedActivities = @"delete_completed_activities";
16 | static NSString *kKTSharedUserDefaultsPomoDuration = @"pomo_length";
17 | static NSString *kKTSharedUserDefaultsBreakDuration = @"break_length";
18 |
19 | @implementation KTSharedUserDefaults
20 |
21 | + (NSUserDefaults*)sharedUserDefaults
22 | {
23 | static NSUserDefaults *sharedDefaults;
24 | static dispatch_once_t onceToken;
25 | dispatch_once(&onceToken, ^{
26 | #ifdef kKTSharedUserDefaultsShouldUseAppContainer
27 | sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.corgitoergosum.KTPomodoro"];
28 | #else
29 | sharedDefaults = [NSUserDefaults standardUserDefaults];
30 | #endif
31 | });
32 | return sharedDefaults;
33 | }
34 |
35 | + (NSUInteger)pomoDuration
36 | {
37 | return ([[KTSharedUserDefaults sharedUserDefaults] integerForKey:kKTSharedUserDefaultsPomoDuration]>0?[[KTSharedUserDefaults sharedUserDefaults] integerForKey:kKTSharedUserDefaultsPomoDuration]:25);
38 |
39 | }
40 |
41 | + (NSUInteger)breakDuration
42 | {
43 | return ([[KTSharedUserDefaults sharedUserDefaults] integerForKey:kKTSharedUserDefaultsBreakDuration]>0?[[KTSharedUserDefaults sharedUserDefaults] integerForKey:kKTSharedUserDefaultsBreakDuration]:5);
44 | }
45 |
46 |
47 | + (BOOL)shouldAutoDeleteCompletedActivites
48 | {
49 | return ([[KTSharedUserDefaults sharedUserDefaults] boolForKey:kKTSharedUserDefaultsShouldAutoDeleteCompletedActivities]?[[KTSharedUserDefaults sharedUserDefaults] boolForKey:kKTSharedUserDefaultsShouldAutoDeleteCompletedActivities]:YES);
50 | }
51 |
52 | @end
53 |
--------------------------------------------------------------------------------
/KTPomodoro/View Controller/KTPomodoroTableViewCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // KTPomodoroTableViewCell.h
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 12/31/14.
6 | // Copyright (c) 2014 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface KTPomodoroTableViewCell : UITableViewCell
12 |
13 | @property (weak, nonatomic) IBOutlet UILabel *taskNameLabel;
14 | @property (weak, nonatomic) IBOutlet UILabel *descLabel;
15 | @property (weak, nonatomic) IBOutlet UILabel *statusLabel;
16 | @property (weak, nonatomic) IBOutlet UILabel *timeLabel;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/KTPomodoro/View Controller/KTPomodoroTableViewCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // KTPomodoroTableViewCell.m
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 12/31/14.
6 | // Copyright (c) 2014 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import "KTPomodoroTableViewCell.h"
10 |
11 | @implementation KTPomodoroTableViewCell
12 |
13 | - (void)awakeFromNib {
14 |
15 |
16 | }
17 |
18 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
19 | [super setSelected:selected animated:animated];
20 |
21 | // Configure the view for the selected state
22 |
23 | }
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/KTPomodoro/View Controller/KTPomodoroTableViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // KTPomodoroTableViewController.h
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 12/31/14.
6 | // Copyright (c) 2014 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface KTPomodoroTableViewController : UITableViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/KTPomodoro/View Controller/KTPomodoroTableViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // KTPomodoroTableViewController.m
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 12/31/14.
6 | // Copyright (c) 2014 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import "KTPomodoroTableViewController.h"
10 | #import "KTCoreDataStack.h"
11 | #import "KTPomodoroTableViewCell.h"
12 | #import "KTPomodoroActivityModel.h"
13 |
14 | static NSString *kKTPomodoroTableRow = @"kKTPomodoroTableRow";
15 | static CGFloat kKTPomodoroTableRowHeight = 110.0f;
16 |
17 |
18 | @interface KTPomodoroTableViewController ()
19 |
20 | //@property (nonatomic) KTActiveActivityTimer *activeTaskTimer;
21 | @property (nonatomic) NSInteger activeTimerRowIndex;
22 |
23 | @end
24 |
25 | @implementation KTPomodoroTableViewController
26 |
27 | - (void)viewDidLoad {
28 | [super viewDidLoad];
29 | [self.tableView registerNib:[UINib nibWithNibName:@"KTPomodoroTableViewCell" bundle:nil] forCellReuseIdentifier:kKTPomodoroTableRow];
30 |
31 | self.title = @"Pomodoro Tasks";
32 |
33 | self.activeTimerRowIndex = -1;
34 | // self.activeTaskTimer = [KTActiveActivityTimer sharedInstance];
35 | // self.activeTaskTimer.delegate = self;
36 |
37 | }
38 |
39 | - (void)didReceiveMemoryWarning {
40 | [super didReceiveMemoryWarning];
41 | // Dispose of any resources that can be recreated.
42 | }
43 |
44 | - (void)dealloc
45 | {
46 | // [self.activeTaskTimer stopTimer];
47 | }
48 |
49 | #pragma mark - UITableViewController methods
50 |
51 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
52 | return [[KTCoreDataStack sharedInstance].allTasks count];
53 | }
54 |
55 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
56 | KTPomodoroTableViewCell *cell = (KTPomodoroTableViewCell*)[tableView dequeueReusableCellWithIdentifier:kKTPomodoroTableRow forIndexPath:indexPath];
57 | if (!cell) {
58 | cell = [[NSBundle mainBundle] loadNibNamed:@"KTPomodoroTableViewCell" owner:nil options:nil][0];
59 | }
60 |
61 | KTPomodoroActivityModel *task = [KTCoreDataStack sharedInstance].allTasks[indexPath.row];
62 | cell.taskNameLabel.text = task.name;
63 | cell.descLabel.text = task.desc;
64 | cell.statusLabel.text = [task.status stringValue];
65 |
66 | if (indexPath.row == self.activeTimerRowIndex) {
67 | cell.backgroundColor = [UIColor colorWithRed:235.0f/255.0f green:231.0f/255.0f blue:231.0f/255.0f alpha:1.0];
68 |
69 | } else {
70 | cell.backgroundColor = [UIColor clearColor];
71 | }
72 |
73 | return cell;
74 | }
75 |
76 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
77 | {
78 | return kKTPomodoroTableRowHeight;
79 | }
80 |
81 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
82 | {
83 | KTPomodoroTableViewCell *cell = (KTPomodoroTableViewCell*)[self.tableView cellForRowAtIndexPath:indexPath];
84 | [cell setSelected:NO animated:YES];
85 | [self.tableView reloadData];
86 |
87 | }
88 |
89 | @end
90 |
--------------------------------------------------------------------------------
/KTPomodoro/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // KTPomodoro
4 | //
5 | // Created by Kenny Tang on 12/31/14.
6 | // Copyright (c) 2014 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "KTAppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([KTAppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/KTPomodoroTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.corgitoergosum.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/KTPomodoroTests/KTPomodoroTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // KTPomodoroTests.m
3 | // KTPomodoroTests
4 | //
5 | // Created by Kenny Tang on 12/31/14.
6 | // Copyright (c) 2014 Kenny Tang. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface KTPomodoroTests : XCTestCase
13 |
14 | @end
15 |
16 | @implementation KTPomodoroTests
17 |
18 | - (void)setUp {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown {
24 | // Put teardown code here. This method is called after the invocation of each test method in the class.
25 | [super tearDown];
26 | }
27 |
28 | - (void)testExample {
29 | // This is an example of a functional test case.
30 | XCTAssert(YES, @"Pass");
31 | }
32 |
33 | - (void)testPerformanceExample {
34 | // This is an example of a performance test case.
35 | [self measureBlock:^{
36 | // Put the code you want to measure the time of here.
37 | }];
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/Mockup/KTPomodoro - app.sketch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kenshin03/KTPomodoro/18d66de5d70cbd32f1f23d152d0252bb24e342b7/Mockup/KTPomodoro - app.sketch
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #KTPomodoro
2 |
3 | **KTPomodoro** is a miniscule Pomodoro Timer app designed for the Watch, written in Objective-C. It has been made obsolete by the Swift version of the same project called [Cherry](https://github.com/kenshin03/Cherry). Please head over there for latest updates.
4 |
5 |
6 |
--------------------------------------------------------------------------------