Skip to content

Commit

Permalink
Support relative links for images and audio files in activities.
Browse files Browse the repository at this point in the history
  • Loading branch information
RDMurray committed Feb 28, 2024
1 parent 06ee3b0 commit 21b4a13
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ extension AuthoredActivityContent {
///
/// - Parameter gpx: A parsed GPX file
/// - Returns: An ``AuthoredActivityContent``, or `nil` if parsing failed or required properties were missing. Currently, waypoints or POIs may be skipped if they lack coordinate data.
static func parse(gpx: GPXRoot) -> AuthoredActivityContent? {
static func parse(gpx: GPXRoot, baseURL: URL) -> AuthoredActivityContent? {
guard let metadata = gpx.metadata else {
return nil
}
Expand All @@ -206,15 +206,15 @@ extension AuthoredActivityContent {

var imageURL: URL?
if let image = metadata.links.first, image.mimetype?.hasPrefix("image") != nil, let href = image.href {
imageURL = URL(string: href)
imageURL = URL(string: href, relativeTo: baseURL)
}

// Parse the waypoints and POIs based on the file version
switch ext.version ?? "1" {
case "1":
// Version 1 just uses all the top-level waypoints `<wpt></wpt>` defined in the GPX, in order

let wpts: [ActivityWaypoint] = waypoints(from: gpx.waypoints)
let wpts: [ActivityWaypoint] = waypoints(from: gpx.waypoints, baseURL: baseURL)

// For waypoints in this experience, require names, descriptions, and street addresses
guard !wpts.isEmpty, !wpts.contains(where: { $0.name == nil }) else {
Expand Down Expand Up @@ -242,7 +242,7 @@ extension AuthoredActivityContent {
}

// Waypoints are strict about requiring names and locations
let wpts: [ActivityWaypoint] = waypoints(from: route.points)
let wpts: [ActivityWaypoint] = waypoints(from: route.points, baseURL: baseURL)

// For waypoints in this experience, require names, descriptions, and street addresses
guard !wpts.isEmpty, !wpts.contains(where: { $0.name == nil }) else {
Expand Down Expand Up @@ -279,7 +279,7 @@ extension AuthoredActivityContent {
///
/// - Parameter waypoints: an array of ``GPXWaypoint``s
/// - Returns: an array of ``ActivityWaypoint``s including annotation data (if applicable)
private static func waypoints(from waypoints: [GPXWaypoint]) -> [ActivityWaypoint] {
private static func waypoints(from waypoints: [GPXWaypoint], baseURL: URL) -> [ActivityWaypoint] {
let imageMimeTypes = Set(["image/jpeg", "image/jpg", "image/png"])
let audioMimeTypes = Set(["audio/mpeg", "audio/x-m4a"])

Expand All @@ -291,7 +291,7 @@ extension AuthoredActivityContent {

let parsedImages: [ActivityWaypointImage] = links.compactMap { link in
guard let href = link.href,
let url = URL(string: href) else {
let url = URL(string: href, relativeTo: baseURL) else {
return nil
}

Expand All @@ -300,7 +300,7 @@ extension AuthoredActivityContent {

let parsedAudioClips: [ActivityWaypointAudioClip] = links.compactMap { link in
guard let href = link.href,
let url = URL(string: href) else {
let url = URL(string: href, relativeTo: baseURL) else {
return nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,15 @@ class AuthoredActivityLoader {
return nil
}

guard let index = knownActivities.events.firstIndex(where: { activityID == $0.id }),
let baseURL = knownActivities.events[index].downloadPath else {
GDLogAppError("Unable to find download path for activity with ID: \(activityID)")
return nil
}


// Parse the GPX file and validate its contents
return AuthoredActivityContent.parse(gpx: gpx)
return AuthoredActivityContent.parse(gpx: gpx, baseURL: baseURL)
}

func add(_ activityID: String, linkVersion: UniversalLinkVersion) async throws {
Expand Down Expand Up @@ -296,8 +303,8 @@ class AuthoredActivityLoader {
throw ActivityLoaderError.unableToLoadContent
}

guard let content = AuthoredActivityContent.parse(gpx: gpx) else {
GDLogWarn(.routeGuidance, "Unable to parse activity content from GPX for \(id)")
guard let content = AuthoredActivityContent.parse(gpx: gpx, baseURL: metadata.downloadPath!) else {
GDLogWarn(.routeGuidance, "Unable to parse activity content from GPX for \(id), URL = \(metadata.downloadPath)")

NotificationCenter.default.post(name: .didTryActivityUpdate, object: self, userInfo: [
Keys.updateSuccess: false,
Expand Down

0 comments on commit 21b4a13

Please sign in to comment.