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 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
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>
137 changes: 137 additions & 0 deletions Live Activity/LiveActivity.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
//
// 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 {
var submissionStatus : Bool
var code : String
var status : String
}
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 {
Text("The location submission succeeded.")
.foregroundColor(.green)
}
else {
Text("The location submission failed.")
.foregroundColor(.red)
}
Text("HTTP \(context.state.code): \(context.state.status)")
.monospaced()
}
.padding()

} dynamicIsland: { (context) in
DynamicIsland {
DynamicIslandExpandedRegion(.leading) {
if context.state.submissionStatus {
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: {
Image(systemName: context.state.submissionStatus ? "checkmark.circle" : "xmark.circle")
.symbolRenderingMode(.palette)
.foregroundColor(context.state.submissionStatus ? .green : .red)

} minimal: {
Image(systemName: context.state.submissionStatus ? "checkmark.circle" : "xmark.circle")
.symbolRenderingMode(.palette)
.foregroundColor(context.state.submissionStatus ? .green : .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()
}
}

}
8 changes: 4 additions & 4 deletions Shared/API.swift
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ enum API: TargetType {
}
}

@discardableResult
@_disfavoredOverload
func perform() async throws -> Data {
let request = try API.provider.endpoint(self).urlRequest()
let (data, response) = try await URLSession.shared.data(for: request)
Expand All @@ -151,13 +151,13 @@ enum API: TargetType {
as responseType: ResponseType.Type,
onMainActor: Bool = false
) async throws -> ResponseType where ResponseType: Sendable & Decodable {
let data = try await self.perform()
let data = try await self.perform()
if onMainActor {
return try await MainActor.run {
return try decoder.decode(responseType, from: data)
return try decoder.decode(responseType, from: data)
}
} else {
return try decoder.decode(responseType, from: data)
return try decoder.decode(responseType, from: data)
}
}

Expand Down
5 changes: 5 additions & 0 deletions Shared/AppStorageManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ final class AppStorageManager: ObservableObject, LoggingConfigurationProvider {

static let colorBlindMode = false

static let debugMode = false

static let maximumStopDistance = 50

static let boardBusCount = 0
Expand Down Expand Up @@ -47,6 +49,9 @@ final class AppStorageManager: ObservableObject, LoggingConfigurationProvider {
@AppStorage("ColorBlindMode")
var colorBlindMode = Defaults.colorBlindMode

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

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

Expand Down
69 changes: 38 additions & 31 deletions Shared/BoardBusManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import CoreLocation
import STLogging
import StoreKit
import UIKit

import HTTPStatus
import ActivityKit
@preconcurrency
import UserNotifications

Expand Down Expand Up @@ -85,6 +86,7 @@ actor BoardBusManager: ObservableObject {
await self.sendBoardBusNotification(type: .boardBus)
}
}

await MainActor.run {
ViewState.shared.statusText = .locationData
ViewState.shared.handles.tripCount?.increment()
Expand All @@ -93,6 +95,9 @@ actor BoardBusManager: ObservableObject {
self.objectWillChange.send()
MapState.mapView?.showsUserLocation.toggle()
}
if #available(iOS 16.2, *) {
await DebugMode.shared.startLiveActivity(busID: busID)
}
}

func leaveBus(manual: Bool = true) async {
Expand Down Expand Up @@ -134,37 +139,39 @@ actor BoardBusManager: ObservableObject {
self.objectWillChange.send()
MapState.mapView?.showsUserLocation.toggle()
}

if manual {
Task { @MainActor in // Dispatch a child task because we don’t need to await the result
// TODO: Switch to SwiftUI’s requestReview environment value when we drop support for iOS 15
// Request a review on the App Store
// This logic uses the legacy SKStoreReviewController class because the newer SwiftUI requestReview environment value requires iOS 16 or newer, and stored properties can’t be gated on OS version.
let windowScenes = UIApplication.shared.connectedScenes
.filter { (scene) in
return scene.activationState == .foregroundActive
}
.compactMap { (scene) in
return scene as? UIWindowScene
}
if let windowScene = windowScenes.first {
SKStoreReviewController.requestReview(in: windowScene)
}

do {
if #available(iOS 16, *) {
try await Task.sleep(for: .seconds(5))
} else {
try await Task.sleep(nanoseconds: 5_000_000_000)
}
} catch {
#log(system: Logging.system, level: .error, doUpload: true, "Task sleep failed: \(error, privacy: .public)")
}
ViewState.shared.statusText = .mapRefresh
}
}
if #available(iOS 16.2, *) {
await DebugMode.shared.endSession()
}
if manual {
Task { @MainActor in // Dispatch a child task because we don’t need to await the result
// TODO: Switch to SwiftUI’s requestReview environment value when we drop support for iOS 15
// Request a review on the App Store
// This logic uses the legacy SKStoreReviewController class because the newer SwiftUI requestReview environment value requires iOS 16 or newer, and stored properties can’t be gated on OS version.
let windowScenes = UIApplication.shared.connectedScenes
.filter { (scene) in
return scene.activationState == .foregroundActive
}
.compactMap { (scene) in
return scene as? UIWindowScene
}
if let windowScene = windowScenes.first {
SKStoreReviewController.requestReview(in: windowScene)
}

do {
if #available(iOS 16, *) {
try await Task.sleep(for: .seconds(5))
} else {
try await Task.sleep(nanoseconds: 5_000_000_000)
}
} catch {
#log(system: Logging.system, level: .error, doUpload: true, "Task sleep failed: \(error, privacy: .public)")
}
ViewState.shared.statusText = .mapRefresh
}
}
}

func updateBusID(with bus: Bus) {
if let busID = self.busID, busID < 0 {
self.busID = bus.id
Expand Down
1 change: 1 addition & 0 deletions Shared/Delegates/LocationManagerDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ final class LocationManagerDelegate: NSObject, CLLocationManagerDelegate {
// The Core Location documentation promises that the array of locations will contain at least one element.
await LocationUtilities.sendToServer(coordinate: locations.last!.coordinate)
}
// await BoardBusManager.sendToServer(coordinate: locations.last!.coordinate)
#endif
}
}
Expand Down
Loading