Skip to content

Commit 9511cab

Browse files
committed
Updated docs
1 parent 831978f commit 9511cab

File tree

4 files changed

+82
-13
lines changed

4 files changed

+82
-13
lines changed

Sources/TimecodeKitCore/Documentation.docc/Timecode-Components.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,4 @@ Primitive storage type for timecode component values.
3838
- ``isWithinValidDigitCounts(at:base:)``
3939
- ``validRange(of:using:)``
4040
- ``validRange(of:at:base:limit:)``
41+
- ``ComponentRanges``

Sources/TimecodeKitCore/Documentation.docc/Timecode-Encoding.md

Lines changed: 79 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,22 +61,42 @@ struct TimecodeListView: View {
6161
// Provide default properties in case only a timecode string is present,
6262
// which could be the case if the user copies a plain-text timecode string
6363
// from another application. If the timecode data on the pasteboard was
64-
// originally created using Timecode's itemProviders() method, then
65-
// these properties will be ignored, as the pasteboard will contain lossless
66-
// data with which to decode to the new Timecode instance.
67-
let properties = Timecode.Properties(rate: .fps24)
64+
// originally created using Timecode's `itemProviders()` method or its
65+
// `Transferable` representation, then these properties will be ignored,
66+
// as the pasteboard will contain lossless data with which to decode to
67+
// the new Timecode instance.
68+
let properties = model.last?.properties
69+
?? Timecode.Properties(rate: .fps24)
6870
let timecode = try await Timecode(
6971
from: itemProviders,
7072
propertiesForString: properties
7173
)
72-
73-
// Timecode's default Identifiable implementation uses self
74+
75+
// Here is where you can validate pasted timecode before accepting it.
76+
// See the `validate()` method inline help or Encoding section in the
77+
// documentation for details.
78+
let validatedTimecode = TimecodeField.validate(pastedTimecode: timecode, ... )
79+
80+
// Finally, accept the pasted timecode
81+
// Timecode's default `Identifiable` implementation uses self
7482
// which means we cannot have two identical timecodes in a SwiftUI array
75-
if !model.contains(timecode) { model.append(timecode) }
83+
if !model.contains(validatedTimecode) {
84+
model.append(validatedTimecode)
85+
}
7686
}
7787
}
7888
```
7989

90+
See the <doc:#Pasted-Timecode-Validation-Against-Local-Context> section on how to validate pasted timecode.
91+
92+
> Important:
93+
>
94+
> If SwiftUI view modifiers using `NSItemProviders` are invoked without exporting `Timecode`'s UT Type, this error will be thrown:
95+
>
96+
> `Type "com.orchetect.TimecodeKit.timecode" was expected to be declared and exported in the Info.plist of MyApp.app, but it was not found.`
97+
>
98+
> See the <doc:#UT-Types> section for information on how to export this type in your app.
99+
80100
## Transferable
81101

82102
``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.
@@ -105,22 +125,68 @@ struct TimecodeListView: View {
105125
}
106126

107127
func add(items: [Timecode]) {
108-
// Timecode's default Identifiable implementation uses self
109-
// which means we cannot have two identical timecodes in a SwiftUI array
110-
items.forEach {
111-
if !model.contains($0) { model.append($0) }
128+
for item in items {
129+
// Here is where you can validate pasted timecode before accepting it.
130+
// See the `validate()` method inline help or Encoding section in the
131+
// documentation for details.
132+
let validatedTimecode = TimecodeField.validate(pastedTimecode: item, ... )
133+
134+
// Timecode's default `Identifiable` implementation uses self
135+
// which means we cannot have two identical timecodes in a SwiftUI array
136+
if !model.contains(validatedTimecode) { model.append(validatedTimecode) }
112137
}
113138
}
114139
}
115140
```
116141

142+
See the <doc:#Pasted-Timecode-Validation-Against-Local-Context> section on how to validate pasted timecode.
143+
117144
> Important:
118145
>
119-
> 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:
146+
> 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:
120147
>
121148
> `Type "com.orchetect.TimecodeKit.timecode" was expected to be declared and exported in the Info.plist of MyApp.app, but it was not found.`
122149
>
123-
> See UT Types section above for information on how to export this type in your app.
150+
> See the <doc:#UT-Types> section for information on how to export this type in your app.
151+
152+
## Pasted Timecode Validation Against Local Context
153+
154+
When accepting timecode pasted from the clipboard, it is common to validate it against a local context.
155+
156+
For example, you may want to constrain pasted timecode to a certain frame rate, subframes base and upper limit.
157+
158+
`TimecodeKitUI` offers static API to perform this validation by supplying policies to validate against.
159+
160+
```swift
161+
@TimecodeState private var timecode: Timecode
162+
163+
// pass in the `Timecode` instance received from the pasteboard
164+
// from the `pasteDestination()` or `onPasteCommand()` view modifiers:
165+
func validate(pastedTimecode: Timecode) {
166+
guard let newTimecode = TimecodeField.validate(
167+
pastedTimecode: pastedTimecode,
168+
localTimecodeProperties: timecode.properties,
169+
pastePolicy: .preserveLocalProperties,
170+
validationPolicy: .enforceValid
171+
) else { return }
172+
173+
timecode = newTimecode
174+
}
175+
```
176+
177+
> Note:
178+
>
179+
> This method is offered on `TimecodeField` since it is the same API the field uses internally when handling its own paste events.
180+
>
181+
> 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.
182+
>
183+
> Instead, use the corresponding view modifiers to specify the policies on your `TimecodeField` instance:
184+
>
185+
> - `timecodeFieldPastePolicy(_:)`
186+
> - `timecodeFieldValidationPolicy(_:)`
187+
> - `timecodeFieldInputStyle(_:)`
188+
>
189+
> 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.
124190
125191
## Topics
126192

Sources/TimecodeKitUI/SwiftUI/TimecodeField/TimecodeField.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import TimecodeKitCore
5353
/// ```swift
5454
/// TimecodeField(timecode: $timecode)
5555
/// // appearance
56+
/// .font(.title) // font size and family may be set as usual
5657
/// .foregroundColor(.primary) // default text color
5758
/// .timecodeFormat([.showSubFrames]) // enable subframes component
5859
/// .timecodeSeparatorStyle(.secondary) // colorize separators

Sources/TimecodeKitUI/SwiftUI/TimecodeText/TimecodeText.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import TimecodeKitCore
4848
///
4949
/// ```swift
5050
/// TimecodeText(timecode)
51+
/// .font(.title) // font size and family may be set as usual
5152
/// .foregroundColor(.primary) // default text color
5253
/// .timecodeFormat([.showSubFrames]) // enable subframes component
5354
/// .timecodeSeparatorStyle(.secondary) // colorize separators

0 commit comments

Comments
 (0)