Skip to content

Commit

Permalink
Updated docs
Browse files Browse the repository at this point in the history
  • Loading branch information
orchetect committed Oct 24, 2024
1 parent 831978f commit 9511cab
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ Primitive storage type for timecode component values.
- ``isWithinValidDigitCounts(at:base:)``
- ``validRange(of:using:)``
- ``validRange(of:at:base:limit:)``
- ``ComponentRanges``
92 changes: 79 additions & 13 deletions Sources/TimecodeKitCore/Documentation.docc/Timecode-Encoding.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,22 +61,42 @@ struct TimecodeListView: View {
// Provide default properties in case only a timecode string is present,
// which could be the case if the user copies a plain-text timecode string
// from another application. If the timecode data on the pasteboard was
// originally created using Timecode's itemProviders() method, then
// these properties will be ignored, as the pasteboard will contain lossless
// data with which to decode to the new Timecode instance.
let properties = Timecode.Properties(rate: .fps24)
// originally created using Timecode's `itemProviders()` method or its
// `Transferable` representation, then these properties will be ignored,
// as the pasteboard will contain lossless data with which to decode to
// the new Timecode instance.
let properties = model.last?.properties
?? Timecode.Properties(rate: .fps24)
let timecode = try await Timecode(
from: itemProviders,
propertiesForString: properties
)

// Timecode's default Identifiable implementation uses self

// Here is where you can validate pasted timecode before accepting it.
// See the `validate()` method inline help or Encoding section in the
// documentation for details.
let validatedTimecode = TimecodeField.validate(pastedTimecode: timecode, ... )

// Finally, accept the pasted timecode
// Timecode's default `Identifiable` implementation uses self
// which means we cannot have two identical timecodes in a SwiftUI array
if !model.contains(timecode) { model.append(timecode) }
if !model.contains(validatedTimecode) {
model.append(validatedTimecode)
}
}
}
```

See the <doc:#Pasted-Timecode-Validation-Against-Local-Context> section on how to validate pasted timecode.

> Important:
>
> If SwiftUI view modifiers using `NSItemProviders` are invoked without exporting `Timecode`'s UT Type, this error will be thrown:
>
> `Type "com.orchetect.TimecodeKit.timecode" was expected to be declared and exported in the Info.plist of MyApp.app, but it was not found.`
>
> See the <doc:#UT-Types> section for information on how to export this type in your app.
## Transferable

``Timecode`` conforms to the [`Transferable`](https://developer.apple.com/documentation/coretransferable/transferable) protocol which allows instances to be dragged & dropped or copied to/from the clipboard using declarative SwiftUI syntax.
Expand Down Expand Up @@ -105,22 +125,68 @@ struct TimecodeListView: View {
}

func add(items: [Timecode]) {
// Timecode's default Identifiable implementation uses self
// which means we cannot have two identical timecodes in a SwiftUI array
items.forEach {
if !model.contains($0) { model.append($0) }
for item in items {
// Here is where you can validate pasted timecode before accepting it.
// See the `validate()` method inline help or Encoding section in the
// documentation for details.
let validatedTimecode = TimecodeField.validate(pastedTimecode: item, ... )

// Timecode's default `Identifiable` implementation uses self
// which means we cannot have two identical timecodes in a SwiftUI array
if !model.contains(validatedTimecode) { model.append(validatedTimecode) }
}
}
}
```

See the <doc:#Pasted-Timecode-Validation-Against-Local-Context> section on how to validate pasted timecode.

> Important:
>
> If SwiftUI methods using the [`Transferable`](https://developer.apple.com/documentation/coretransferable/transferable) protocol are invoked without exporting this UT Type, this error will be thrown:
> If SwiftUI view modifiers using the [`Transferable`](https://developer.apple.com/documentation/coretransferable/transferable) protocol are invoked without exporting `Timecode`'s UT Type, this error will be thrown:
>
> `Type "com.orchetect.TimecodeKit.timecode" was expected to be declared and exported in the Info.plist of MyApp.app, but it was not found.`
>
> See UT Types section above for information on how to export this type in your app.
> See the <doc:#UT-Types> section for information on how to export this type in your app.
## Pasted Timecode Validation Against Local Context

When accepting timecode pasted from the clipboard, it is common to validate it against a local context.

For example, you may want to constrain pasted timecode to a certain frame rate, subframes base and upper limit.

`TimecodeKitUI` offers static API to perform this validation by supplying policies to validate against.

```swift
@TimecodeState private var timecode: Timecode

// pass in the `Timecode` instance received from the pasteboard
// from the `pasteDestination()` or `onPasteCommand()` view modifiers:
func validate(pastedTimecode: Timecode) {
guard let newTimecode = TimecodeField.validate(
pastedTimecode: pastedTimecode,
localTimecodeProperties: timecode.properties,
pastePolicy: .preserveLocalProperties,
validationPolicy: .enforceValid
) else { return }

timecode = newTimecode
}
```

> Note:
>
> This method is offered on `TimecodeField` since it is the same API the field uses internally when handling its own paste events.
>
> Because `TimecodeField` implements copy and paste functionality under the hood, calling the `validate` method is unnecessary as it is already being called internally on user paste events.
>
> Instead, use the corresponding view modifiers to specify the policies on your `TimecodeField` instance:
>
> - `timecodeFieldPastePolicy(_:)`
> - `timecodeFieldValidationPolicy(_:)`
> - `timecodeFieldInputStyle(_:)`
>
> See `TimecodeField` documentation in the `TimecodeKitUI` module for more information, or try out the **Timecode UI** example project located in the **Examples** folder within this repo.
## Topics

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import TimecodeKitCore
/// ```swift
/// TimecodeField(timecode: $timecode)
/// // appearance
/// .font(.title) // font size and family may be set as usual
/// .foregroundColor(.primary) // default text color
/// .timecodeFormat([.showSubFrames]) // enable subframes component
/// .timecodeSeparatorStyle(.secondary) // colorize separators
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import TimecodeKitCore
///
/// ```swift
/// TimecodeText(timecode)
/// .font(.title) // font size and family may be set as usual
/// .foregroundColor(.primary) // default text color
/// .timecodeFormat([.showSubFrames]) // enable subframes component
/// .timecodeSeparatorStyle(.secondary) // colorize separators
Expand Down

0 comments on commit 9511cab

Please sign in to comment.