Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ For devices running watchOS 5 or higher.
![Show project and targets list](Screenshots/Show_project_and_targets_list.png)
1. Select the **General** tab:
![Change bundle identifier 1](Screenshots/Change_bundle_identifier1.png)
1. For each of the 3 **targets** replece *kuglee* in the **Bundle Identifier** field with the name of your developer account. (The name of your Apple ID without the *@xxxx.com*.)
1. For each of the 3 **targets** replece *k0042n* in the **Bundle Identifier** field with the name of your developer account. (The name of your Apple ID without the *@xxxx.com*.)
![Change bundle identifier 2](Screenshots/Change_bundle_identifier2.png)
1. Change the project's team:
1. Select the **Signing & Capabilities** tab:
Expand All @@ -52,7 +52,7 @@ For devices running watchOS 5 or higher.
![Change team 2](Screenshots/Change_team2.png)
1. Manually replace bundle identifiers:
1. Select **Xcode** menu -> **Find** -> **Find and Replace in Project…**.
1. In the **Text** field type *kuglee*.
1. In the **Text** field type *k0042n*.
1. In the **With** field type the name of your developer account. (The name of your Apple ID without the @xxxx.com.)
1. Click the **Replace All** button.
![Change bundle identifier 3](Screenshots/Change_bundle_identifier3.png)
Expand Down
51 changes: 44 additions & 7 deletions TermiWatch WatchKit App/Base.lproj/Interface.storyboard
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder.WatchKit.Storyboard" version="3.0" toolsVersion="14460.31" targetRuntime="watchKit" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="AgC-eL-Hgc">
<device id="watch40" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<document type="com.apple.InterfaceBuilder.WatchKit.Storyboard" version="3.0" toolsVersion="18122" targetRuntime="watchKit" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="AgC-eL-Hgc">
<device id="watch40"/>
<dependencies>
<deployment identifier="watchOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBWatchKitPlugin" version="14460.16"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBWatchKitPlugin" version="18022"/>
</dependencies>
<customFonts key="customFonts">
<array key="SF-Mono-Regular.otf">
Expand Down Expand Up @@ -107,7 +105,36 @@
</variation>
</label>
<label alignment="left" text="--" id="SKt-9Q-acu" userLabel="Temperature Label">
<color key="textColor" red="0.99215686274509807" green="0.5607843137254902" blue="0.24705882352941178" alpha="1" colorSpace="calibratedRGB"/>
<color key="textColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<fontDescription key="font" name="SFMono-Regular" family="SF Mono" pointSize="14"/>
<variation key="device=watch38mm">
<fontDescription key="font" name="SFMono-Regular" family="SF Mono" pointSize="12"/>
</variation>
<variation key="device=watch42mm">
<fontDescription key="font" name="SFMono-Regular" family="SF Mono" pointSize="13"/>
</variation>
<variation key="device=watch44mm">
<fontDescription key="font" name="SFMono-Regular" family="SF Mono" pointSize="16"/>
</variation>
</label>
</items>
</group>
<group width="1" alignment="left" hidden="YES" spacing="0.0" id="ArV-nc-Hze" userLabel="Calendar Group">
<items>
<label alignment="left" text="[CALR]" textAlignment="left" id="lbG-IO-C71" userLabel="[CALR]">
<fontDescription key="font" name="SFMono-Regular" family="SF Mono" pointSize="14"/>
<variation key="device=watch38mm">
<fontDescription key="font" name="SFMono-Regular" family="SF Mono" pointSize="12"/>
</variation>
<variation key="device=watch42mm">
<fontDescription key="font" name="SFMono-Regular" family="SF Mono" pointSize="13"/>
</variation>
<variation key="device=watch44mm">
<fontDescription key="font" name="SFMono-Regular" family="SF Mono" pointSize="16"/>
</variation>
</label>
<label alignment="left" text="--" id="ivt-7u-6PD" userLabel="Calendar Label">
<color key="textColor" red="0.99215686270000003" green="0.56078431370000004" blue="0.2470588235" alpha="1" colorSpace="calibratedRGB"/>
<fontDescription key="font" name="SFMono-Regular" family="SF Mono" pointSize="14"/>
<variation key="device=watch38mm">
<fontDescription key="font" name="SFMono-Regular" family="SF Mono" pointSize="12"/>
Expand Down Expand Up @@ -258,14 +285,24 @@
</items>
<edgeInsets key="margins" left="1" right="1" top="0.0" bottom="0.0"/>
<connections>
<outlet property="activityGroup" destination="vaI-MQ-EJU" id="13j-Bp-v9n"/>
<outlet property="activityLabel" destination="Ffh-bh-IK7" id="yh4-nR-EXG"/>
<outlet property="batteryGroup" destination="d1R-FW-N0Q" id="Ahz-0I-g20"/>
<outlet property="batteryLabel" destination="3dH-MF-gwo" id="1uW-7r-XDy"/>
<outlet property="calendarGroup" destination="ArV-nc-Hze" id="JJX-rZ-2uX"/>
<outlet property="calendarLabel" destination="ivt-7u-6PD" id="uCt-uQ-6eA"/>
<outlet property="heartRateGroup" destination="7QQ-dm-023" id="ZF3-qv-H47"/>
<outlet property="heartRateLabel" destination="CJN-qq-25o" id="nC7-TA-ixI"/>
<outlet property="stepsGroup" destination="S8h-WK-zOs" id="eGn-OO-I6C"/>
<outlet property="stepsLabel" destination="wW6-sr-Wl2" id="yx2-fB-bIa"/>
<outlet property="temperatureGroup" destination="lYl-fG-xTG" id="0CZ-Hm-bPV"/>
<outlet property="temperatureLabel" destination="SKt-9Q-acu" id="dPq-Hc-1qI"/>
<outlet property="userHostLabel" destination="V36-NY-x0W" id="c4z-N2-WvU"/>
<outlet property="userHostLabelNow" destination="bcc-Ix-MUn" id="DgK-iu-bPl"/>
</connections>
</controller>
</objects>
<point key="canvasLocation" x="94" y="133"/>
</scene>
</scenes>
</document>
2 changes: 1 addition & 1 deletion TermiWatch WatchKit App/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>WKCompanionAppBundleIdentifier</key>
<string>com.kuglee.TermiWatch</string>
<string>com.k0042n.TermiWatch</string>
<key>WKWatchKitApp</key>
<true/>
</dict>
Expand Down
30 changes: 30 additions & 0 deletions TermiWatch WatchKit Extension/EventKitUtils.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Foundation
import EventKit
import PromiseKit

func eventRequestAccess(eventStore: EKEventStore) {
eventStore.requestAccess(to: .event) { granted, error in
// Handle the response to the request.
}
}

func fetchTopEvent(eventStore: EKEventStore, calendar: Calendar) -> String {
// Create the start date components
let now = Date()

// Create the end date components.
let tomorrow = Date().addingTimeInterval(60 * 60 * 24)

// Create the predicate from the event store's instance method.
var predicate: NSPredicate? = nil
predicate = eventStore.predicateForEvents(withStart: now, end: tomorrow, calendars: nil)

// Fetch all events that match the predicate.
var events: [EKEvent]? = nil
if let aPredicate = predicate {
events = eventStore.events(matching: aPredicate)
}

let topEventTitle = events?[0].title ?? "No more events"
Comment thread
hykelvinlee42 marked this conversation as resolved.
Outdated
return topEventTitle
}
4 changes: 3 additions & 1 deletion TermiWatch WatchKit Extension/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<key>NSExtensionAttributes</key>
<dict>
<key>WKAppBundleIdentifier</key>
<string>com.kuglee.TermiWatch.watchkitapp</string>
<string>com.k0042n.TermiWatch.watchkitapp</string>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.watchkit</string>
Expand All @@ -34,6 +34,8 @@
<string>Your health records will be used to display activity data.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Your location data will be used to display weather data. </string>
<key>NSCalendarsUsageDescription</key>
<string>Your calendar data will be used to display event</string>
<key>OpenWeatherMapAPIKey</key>
<string>8d30dae09830ab2917caface6d6cf1c5</string>
<key>WKExtensionDelegateClassName</key>
Expand Down
71 changes: 70 additions & 1 deletion TermiWatch WatchKit Extension/InterfaceController.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import Foundation
import HealthKit
import EventKit
import PMKCoreLocation
import PMKHealthKit
import PromiseKit
import Swizzle
import WatchKit
import WatchConnectivity

// MARK: - UIKit stubs

Expand Down Expand Up @@ -172,14 +174,28 @@ func batteryIndicatorString(percent: UInt) -> String {
}

class InterfaceController: WKInterfaceController {
@IBOutlet weak var userHostLabelNow: WKInterfaceLabel!
@IBOutlet var batteryLabel: WKInterfaceLabel!
@IBOutlet weak var batteryGroup: WKInterfaceGroup!
@IBOutlet var activityLabel: WKInterfaceLabel!
@IBOutlet weak var activityGroup: WKInterfaceGroup!
@IBOutlet var stepsLabel: WKInterfaceLabel!
@IBOutlet weak var stepsGroup: WKInterfaceGroup!
@IBOutlet var heartRateLabel: WKInterfaceLabel!
@IBOutlet weak var heartRateGroup: WKInterfaceGroup!
@IBOutlet var temperatureLabel: WKInterfaceLabel!
@IBOutlet weak var temperatureGroup: WKInterfaceGroup!
@IBOutlet var calendarLabel: WKInterfaceLabel!
@IBOutlet weak var calendarGroup: WKInterfaceGroup!
@IBOutlet weak var userHostLabel: WKInterfaceLabel!

let session = WCSession.default

override func awake(withContext context: Any?) {
super.awake(withContext: context)

session.delegate = self
session.activate()

// MARK: - Temperature

Expand All @@ -204,7 +220,34 @@ class InterfaceController: WKInterfaceController {
}.catch {
print("Error:", $0)
}


// MARK: - Calendar

let eventStore = EKEventStore()

let ekStatus = EKEventStore.authorizationStatus(for: .event)
switch ekStatus {
case EKAuthorizationStatus.notDetermined:
eventRequestAccess(eventStore: eventStore)
self.calendarLabel.setText("notDetermined")
case EKAuthorizationStatus.authorized:
let calendar = Calendar.current
self.calendarLabel.setText(fetchTopEvent(eventStore: eventStore, calendar: calendar))
case EKAuthorizationStatus.restricted, EKAuthorizationStatus.denied:
self.calendarLabel.setText("restricted")
default:
self.calendarLabel.setText("error")
}

NotificationCenter.default.addObserver(
forName: .EKEventStoreChanged,
object: eventStore,
queue: nil
) { [weak self] notification in
let calendar = Calendar.current
self?.calendarLabel.setText(fetchTopEvent(eventStore: eventStore, calendar: calendar))
}

// MARK: - Health

let healthStore = HKHealthStore()
Expand Down Expand Up @@ -301,3 +344,29 @@ class InterfaceController: WKInterfaceController {
hideTimeOnce()
}
}

extension InterfaceController: WCSessionDelegate {
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {

}

func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
let username = message["username"] as? String ?? "user"
let hostname = message["hostname"] as? String ?? "watch"
let showTemperature = message["temperature"] as? Bool ?? true
let showBattery = message["battery"] as? Bool ?? true
let showActivity = message["activity"] as? Bool ?? true
let showSteps = message["steps"] as? Bool ?? true
let showHeartRate = message["heart-rate"] as? Bool ?? true
let showCalendar = message["calendar"] as? Bool ?? false

self.userHostLabelNow.setText(username + "@" + hostname + ":~ $ now")
self.userHostLabel.setText(username + "@" + hostname + ":~ $")
self.temperatureGroup.setHidden(!showTemperature)
self.batteryGroup.setHidden(!showBattery)
self.activityGroup.setHidden(!showActivity)
self.stepsGroup.setHidden(!showSteps)
self.heartRateGroup.setHidden(!showHeartRate)
self.calendarGroup.setHidden(!showCalendar)
}
}
26 changes: 15 additions & 11 deletions TermiWatch.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
5DD84FF8245F172E00E780A4 /* Swizzle in Frameworks */ = {isa = PBXBuildFile; productRef = 5DD84FF7245F172E00E780A4 /* Swizzle */; };
5DD84FFB245F176400E780A4 /* PMKCoreLocation in Frameworks */ = {isa = PBXBuildFile; productRef = 5DD84FFA245F176400E780A4 /* PMKCoreLocation */; };
5DD84FFD245F176800E780A4 /* PMKHealthKit in Frameworks */ = {isa = PBXBuildFile; productRef = 5DD84FFC245F176800E780A4 /* PMKHealthKit */; };
B639AD6C26BDE85200895D4F /* EventKitUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = B639AD6B26BDE85200895D4F /* EventKitUtils.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -100,6 +101,7 @@
5DD84FE4245F12D800E780A4 /* TermiWatch WatchKit Extension.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = "TermiWatch WatchKit Extension.entitlements"; sourceTree = "<group>"; };
5DD84FE8245F132B00E780A4 /* TermiWatch.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TermiWatch.entitlements; sourceTree = "<group>"; };
5DD84FE9245F134E00E780A4 /* SF-Mono-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SF-Mono-Regular.otf"; sourceTree = "<group>"; };
B639AD6B26BDE85200895D4F /* EventKitUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventKitUtils.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -185,6 +187,7 @@
5DD84FE1245F12D700E780A4 /* TemperatureNotifier.swift */,
5DD84FD1245F118500E780A4 /* Assets.xcassets */,
5DD84FD3245F118500E780A4 /* Info.plist */,
B639AD6B26BDE85200895D4F /* EventKitUtils.swift */,
);
path = "TermiWatch WatchKit Extension";
sourceTree = "<group>";
Expand Down Expand Up @@ -361,6 +364,7 @@
5DD84FE7245F12D800E780A4 /* BatteryInfoNotifier.swift in Sources */,
5DD84FE6245F12D800E780A4 /* HealthKitUtils.swift in Sources */,
5DD84FCE245F118400E780A4 /* InterfaceController.swift in Sources */,
B639AD6C26BDE85200895D4F /* EventKitUtils.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -527,14 +531,14 @@
ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication;
CODE_SIGN_ENTITLEMENTS = "TermiWatch WatchKit Extension/TermiWatch WatchKit Extension.entitlements";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = C89KNBM28S;
DEVELOPMENT_TEAM = 59BBS8YWDG;
INFOPLIST_FILE = "TermiWatch WatchKit Extension/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.kuglee.TermiWatch.watchkitapp.watchkitextension;
PRODUCT_BUNDLE_IDENTIFIER = com.k0042n.TermiWatch.watchkitapp.watchkitextension;
PRODUCT_NAME = "${TARGET_NAME}";
SDKROOT = watchos;
SKIP_INSTALL = YES;
Expand All @@ -550,14 +554,14 @@
ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication;
CODE_SIGN_ENTITLEMENTS = "TermiWatch WatchKit Extension/TermiWatch WatchKit Extension.entitlements";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = C89KNBM28S;
DEVELOPMENT_TEAM = 59BBS8YWDG;
INFOPLIST_FILE = "TermiWatch WatchKit Extension/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.kuglee.TermiWatch.watchkitapp.watchkitextension;
PRODUCT_BUNDLE_IDENTIFIER = com.k0042n.TermiWatch.watchkitapp.watchkitextension;
PRODUCT_NAME = "${TARGET_NAME}";
SDKROOT = watchos;
SKIP_INSTALL = YES;
Expand All @@ -573,10 +577,10 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = C89KNBM28S;
DEVELOPMENT_TEAM = 59BBS8YWDG;
IBSC_MODULE = TermiWatch_WatchKit_Extension;
INFOPLIST_FILE = "TermiWatch WatchKit App/Info.plist";
PRODUCT_BUNDLE_IDENTIFIER = com.kuglee.TermiWatch.watchkitapp;
PRODUCT_BUNDLE_IDENTIFIER = com.k0042n.TermiWatch.watchkitapp;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = watchos;
SKIP_INSTALL = YES;
Expand All @@ -592,10 +596,10 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = C89KNBM28S;
DEVELOPMENT_TEAM = 59BBS8YWDG;
IBSC_MODULE = TermiWatch_WatchKit_Extension;
INFOPLIST_FILE = "TermiWatch WatchKit App/Info.plist";
PRODUCT_BUNDLE_IDENTIFIER = com.kuglee.TermiWatch.watchkitapp;
PRODUCT_BUNDLE_IDENTIFIER = com.k0042n.TermiWatch.watchkitapp;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = watchos;
SKIP_INSTALL = YES;
Expand All @@ -611,14 +615,14 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = TermiWatch/TermiWatch.entitlements;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = C89KNBM28S;
DEVELOPMENT_TEAM = 59BBS8YWDG;
INFOPLIST_FILE = TermiWatch/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.kuglee.TermiWatch;
PRODUCT_BUNDLE_IDENTIFIER = com.k0042n.TermiWatch;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
Expand All @@ -638,7 +642,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.kuglee.TermiWatch;
PRODUCT_BUNDLE_IDENTIFIER = com.k0042n.TermiWatch;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
Expand Down
Loading