Skip to content
Open
Show file tree
Hide file tree
Changes from all 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?.first?.title ?? "No more events"
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