Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debug in live activity #143

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 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
11 changes: 11 additions & 0 deletions Live Activity/Assets.xcassets/AccentColor.colorset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
14 changes: 14 additions & 0 deletions Live Activity/Assets.xcassets/AppIcon.appiconset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"images" : [
{
"filename" : "icon_1024x1024.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions Live Activity/Assets.xcassets/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
11 changes: 11 additions & 0 deletions Live Activity/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.widgetkit-extension</string>
</dict>
</dict>
</plist>
158 changes: 158 additions & 0 deletions Live Activity/LiveActivity.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
//
// LiveActivity.swift
// Live Activity
//
// Created by Gabriel Jacoby-Cooper on 1/27/23.
//

import ActivityKit
import SwiftUI
import WidgetKit

@available(iOS 16.1, *)
struct DebugModeActivityAttributes: ActivityAttributes {

public struct ContentState: Codable, Hashable {
// Dynamic stateful properties about your activity go here!
var submissionStatus : Bool
var code : String
var status : String
}
// Fixed non-changing properties about your activity go here!
var busID: Int
}

@available(iOS 16.1, *)
struct LiveActivity: Widget {

var body: some WidgetConfiguration {
ActivityConfiguration(for: DebugModeActivityAttributes.self) { (context) in
// Lock screen/banner UI goes here
VStack(alignment: .leading) {
HStack {
Text("Shuttle Tracker")
.font(.headline)
.bold()
Spacer()
VStack{
Image(systemName: "bus.fill")
.resizable()
.frame(width: 30, height: 30)
.foregroundColor(.red)
}
}
HStack {
Text("A location was submitted... ")
.bold()
Spacer()
Text("Bus \(context.attributes.busID)")
.bold()
}
if context.state.submissionStatus == true {
Text("The location submission succeeded.")
.foregroundColor(.green)
}
else {
Text("The location submission failed.")
.foregroundColor(.red)
}
Text("HTTP \(context.state.code): \(context.state.status)")
.monospaced()
}
.activitySystemActionForegroundColor(Color.black)
.padding()

} dynamicIsland: { (context) in
DynamicIsland {
// Expanded UI goes here. Compose the expanded UI through
// various regions, like leading/trailing/center/bottom
DynamicIslandExpandedRegion(.leading) {
if context.state.submissionStatus == true {
Text("Submission succeeded.")
.foregroundColor(.green)
}
else {
Text("Submission failed.")
.foregroundColor(.red)
}
}
DynamicIslandExpandedRegion(.trailing) {
Text("Bus \(context.attributes.busID)")
.bold()
}
DynamicIslandExpandedRegion(.bottom) {
Text("HTTP \(context.state.code): \(context.state.status)")
.monospaced()
}
} compactLeading: {
Image(systemName: "bus.fill")
.symbolRenderingMode(.palette)
.foregroundColor(.red)

} compactTrailing: {
if context.state.submissionStatus {
Image(systemName: "checkmark.circle")
.symbolRenderingMode(.palette)
.foregroundColor(.green)
}
else {
Image(systemName: "xmark.circle")
.symbolRenderingMode(.palette)
.foregroundColor(.red)
}
} minimal: {
HStack {
if context.state.submissionStatus {
Image(systemName: "checkmark.circle")
.symbolRenderingMode(.palette)
.foregroundColor(.green)
}
else {
Image(systemName: "xmark.circle")
.symbolRenderingMode(.palette)
.foregroundColor(.red)
}
}
}
.keylineTint(Color.red)
}
}
}

@available(iOS 16.1, *)
struct LockScreenLiveActivityView : View {

let context : ActivityViewContext<DebugModeActivityAttributes>

var body: some View {
VStack {
Spacer()
Text(context.state.status)
Spacer()
}
}
}

//@available(iOS 16.1, *)
//struct LiveActivityPreviews: PreviewProvider {
//
// static let attributes = DebugModeActivityAttributes(busID: 90)
//
// static let contentState = DebugModeActivityAttributes.ContentState(status: "Text")
//
// static var previews: some View {
// self.attributes
// .previewContext(self.contentState, viewKind: .dynamicIsland(.compact))
// .previewDisplayName("Island Compact")
// self.attributes
// .previewContext(self.contentState, viewKind: .dynamicIsland(.expanded))
// .previewDisplayName("Island Expanded")
// self.attributes
// .previewContext(self.contentState, viewKind: .dynamicIsland(.minimal))
// .previewDisplayName("Minimal")
// self.attributes
// .previewContext(self.contentState, viewKind: .content)
// .previewDisplayName("Notification")
// }
//
//}
20 changes: 20 additions & 0 deletions Live Activity/LiveActivityBundle.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// LiveActivityBundle.swift
// Live Activity
//
// Created by Gabriel Jacoby-Cooper on 1/27/23.
//

import SwiftUI
import WidgetKit

@main
struct LiveActivityBundle: WidgetBundle {

var body: some Widget {
if #available(iOS 16.2, *) {
LiveActivity()
}
}

}
16 changes: 11 additions & 5 deletions Shared/API.swift
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ enum API: TargetType {
}
}

@discardableResult
func perform() async throws -> Data {
@_disfavoredOverload
func perform() async throws -> (Data, any HTTPStatusCode) {
let request = try API.provider.endpoint(self).urlRequest()
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse else {
Expand All @@ -129,7 +129,13 @@ enum API: TargetType {
guard let statusCode = HTTPStatusCodes.statusCode(httpResponse.statusCode) else {
throw APIError.invalidStatusCode
}
if let error = statusCode as? Error {
return (data, statusCode)
}

@discardableResult
func perform() async throws -> Data {
let (data, statusCode) = try await self.perform()
if let error = statusCode as? any Error {
throw error
} else {
return data
Expand All @@ -156,9 +162,9 @@ fileprivate enum APIError: Error {
get {
switch self {
case .invalidResponse:
return "The server returned an invalid response"
return "The server returned an invalid response."
case .invalidStatusCode:
return "The server returned an invalid HTTP status code"
return "The server returned an invalid HTTP status code."
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions Shared/AppStorageManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ final class AppStorageManager: ObservableObject {

static let colorBlindMode = false

static let debugMode = false

static let maximumStopDistance = 50

static let baseURL = URL(string: "https://shuttletracker.app")!
Expand All @@ -31,6 +33,9 @@ final class AppStorageManager: ObservableObject {
@AppStorage("ColorBlindMode")
var colorBlindMode = Defaults.colorBlindMode

@AppStorage("DebugMode")
var debugMode = Defaults.debugMode

@AppStorage("MaximumStopDistance")
var maximumStopDistance = Defaults.maximumStopDistance

Expand Down
46 changes: 45 additions & 1 deletion Shared/BoardBusManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
// Created by Gabriel Jacoby-Cooper on 9/18/22.
//

import Foundation
import CoreLocation
import HTTPStatus
import ActivityKit

actor BoardBusManager: ObservableObject {

Expand Down Expand Up @@ -42,12 +44,18 @@ actor BoardBusManager: ObservableObject {
Logging.withLogger(for: .boardBus) { (logger) in
logger.log("[\(#fileID):\(#line) \(#function, privacy: .public)] Activated Board Bus")
}

await MainActor.run {
self.oldUserLocationTitle = MapState.mapView?.userLocation.title
MapState.mapView?.userLocation.title = "Bus \(busID)"
self.objectWillChange.send()
MapState.mapView?.showsUserLocation.toggle()
}
if #available(iOS 16.2, *) {
await DebugMode.shared.startLiveActivity(busID: busID)
} else {
// Fallback on earlier versions
}
}

func leaveBus() async {
Expand All @@ -66,6 +74,42 @@ actor BoardBusManager: ObservableObject {
self.objectWillChange.send()
MapState.mapView?.showsUserLocation.toggle()
}

if #available(iOS 16.2, *) {
await DebugMode.shared.endSession()
} else {
// No Debug Mode
}

}

static func sendToServer(coordinate: CLLocationCoordinate2D) async {
guard let busID = await BoardBusManager.shared.busID, let locationID = await BoardBusManager.shared.locationID else {
Logging.withLogger(for: .boardBus, doUpload: true) { (logger) in
logger.log(level: .error, "[\(#fileID):\(#line) \(#function, privacy: .public)] Required bus and location IDs not found while attempting to send location to server")
}
return
}
let location = Bus.Location(
id: locationID,
date: Date(),
coordinate: coordinate.convertedToCoordinate(),
type: .user
)
do {
let (_, statusCode) = try await API.updateBus(id: busID, location: location).perform()
//await DebugMode.shared.showToast(statusCode: statusCode)
if #available(iOS 16.2, *) {
await DebugMode.shared.updateSession(statusCode: statusCode, busID: busID)
} else {
// No Debug Mode
}

} catch let error {
Logging.withLogger(for: .boardBus, doUpload: true) { (logger) in
logger.log(level: .error, "[\(#fileID):\(#line) \(#function, privacy: .public) Failed to send location to server: \(error, privacy: .public)")
}
}
}

}
2 changes: 1 addition & 1 deletion Shared/Delegates/LocationManagerDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ final class LocationManagerDelegate: NSObject, CLLocationManagerDelegate {
guard case .onBus = await BoardBusManager.shared.travelState else {
return
}
await LocationUtilities.sendToServer(coordinate: locations.last!.coordinate)
await BoardBusManager.sendToServer(coordinate: locations.last!.coordinate)
}
}
#endif // os(iOS)
Expand Down
Loading