Skip to content
This repository has been archived by the owner on Dec 15, 2020. It is now read-only.

Add formatter for a11y string #51

Open
wants to merge 1 commit into
base: master
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
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,23 @@ extension DateComponentsFormatter {
return formatter
}

/// Returns an accessible string based on the given time interval, appending any available
/// fractional seconds as milliseconds using a NSCalendar.Unit.spellOut unitsStyle.
///
/// - Parameters:
/// - ti: The time interval, measured in seconds. The value must be a finite number.
/// Negative numbers are treated as positive numbers when creating the string.
/// - fractional: The fractional seconds available on the time interval.
/// If this equals 0, milliseconds will not be appended to the string.
/// - Returns: A formatted string representing the specified time interval.
func string(from ti: TimeInterval, appending fractional: Int64) -> String {
guard let duration = TimeInterval.accessibleIntervalFormatter.string(from: ti) else {
return ""
}
if fractional > 0 {
return duration + " \(fractional) " + String.timeIntervalMilliseconds
}
return duration
}

}
15 changes: 12 additions & 3 deletions ScienceJournal/Extensions/TimeInterval+ScienceJournal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,19 @@ extension TimeInterval {
}

/// Returns the time interval as an accessible string in component format with hours, minutes and
/// seconds without abbreviation.
/// Example: "One hour 46 minutes 11 seconds"
/// seconds without abbreviation. When there are fractional seconds present on the time interval,
/// this will include them as milliseconds.
/// Example: "One hour 46 minutes 11 seconds" and "One second 250 milliseconds".
var accessibleDurationString: String {
return TimeInterval.accessibleIntervalFormatter.string(from: self) ?? ""
return TimeInterval.accessibleIntervalFormatter.string(from: self, appending: fractional)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're currently discussing this path because of a few issues:

  1. In an ideal world, we'd use our existing DateComponentsFormatter to simply use milliseconds since it does the localization for us including locale ordering, etc. But obviously DCF doesn't support anything smaller than seconds.
  2. The issue with appending this formatted string onto the end of the existing a11y string is that, in some locales, this might not be correct. We're not entirely sure, but given the history of how locales work it's entirely possible there's a locale in which milliseconds come first, perhaps.
  3. We don't have a good solution to present instead 😅

We'll discuss a bit more internally and circle back to you on this. Greatly appreciate your PR and your patience. Thanks!

}

/// The fractional seconds available on the time interval.
/// Example: 250 when the time interval equals 1.250, and 0 when the time interval equals 3.0.
private var fractional: Int64 {
let remainder = truncatingRemainder(dividingBy: 1)
guard remainder > 0.0 else { return 0 }
return Int64(remainder * 1000)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -1381,6 +1381,9 @@
/* Accessibility hint for a graphic representing an in-progress recording, telling a user that interacting with it will show the observe tab [CHAR_LIMIT=NONE] */
"throbber_content_details" = "Double tap to switch to the observe tab in the tool drawer";

/* Name for milliseconds in a TimeInterval object */
"time_interval_milliseconds" = "milliseconds";

/* Title for activity that handles sensor settings [CHAR_LIMIT=40] */
"title_activity_sensor_settings" = "Sensor settings";

Expand Down
1 change: 1 addition & 0 deletions ScienceJournal/Strings/ScienceJournalStrings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ extension String {
static public var textNoteAddedContentDescription: String { return "text_note_added_content_description".localized }
static public var throbberContentDescription: String { return "throbber_content_description".localized }
static public var throbberContentDetails: String { return "throbber_content_details".localized }
static public var timeIntervalMilliseconds: String { return "time_interval_milliseconds".localized }
static public var titleActivitySensorSettings: String { return "title_activity_sensor_settings".localized }
static public var toExperimentContentDescription: String { return "to_experiment_content_description".localized }
static public var toRunContentDescription: String { return "to_run_content_description".localized }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,9 @@ class TimeInterval_ScienceJournalTest: XCTestCase {
XCTAssertEqual(interval.accessibleDurationString, "one hour, three minutes, twelve seconds")
}

func testAccessibleDurationStringWithFractionalSeconds() {
let interval: TimeInterval = 1.250
XCTAssertEqual(interval.accessibleDurationString, "one second 250 milliseconds")
}

}