@swiftbrowser/swift 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Package.swift +214 -0
- package/README.md +10 -2
- package/Sources/AVFoundation/AVFoundation.swift +131 -0
- package/Sources/AVFoundation/Asset.swift +487 -0
- package/Sources/AVFoundation/AudioSession.swift +144 -0
- package/Sources/AVFoundation/CMTime.swift +303 -0
- package/Sources/AVFoundation/Capture.swift +688 -0
- package/Sources/AVFoundation/Player.swift +749 -0
- package/Sources/AVFoundation/PlayerView.swift +117 -0
- package/Sources/AVKit/AVKit.swift +132 -0
- package/Sources/Accelerate/Accelerate.swift +122 -0
- package/Sources/AppIntents/AppIntents.swift +144 -0
- package/Sources/AppIntents/Parameters.swift +220 -0
- package/Sources/AppIntents/Shortcuts.swift +159 -0
- package/Sources/AudioToolbox/AudioToolbox.swift +55 -0
- package/Sources/AuthenticationServices/AuthenticationServices.swift +257 -0
- package/Sources/AuthenticationServices/Authorization.swift +251 -0
- package/Sources/Charts/Charts.swift +61 -0
- package/Sources/Combine/AnyCancellable.swift +65 -0
- package/Sources/Combine/AnyPublisher.swift +148 -0
- package/Sources/Combine/AnySubscriber.swift +230 -0
- package/Sources/Combine/Cancellable.swift +35 -0
- package/Sources/Combine/Codable.swift +29 -0
- package/Sources/Combine/CombineIdentifier.swift +45 -0
- package/Sources/Combine/Concurrency/ConcurrencyHelpers.swift +24 -0
- package/Sources/Combine/Concurrency/Future+Concurrency.swift +136 -0
- package/Sources/Combine/Concurrency/GENERATED-Publisher+Concurrency.swift +397 -0
- package/Sources/Combine/CurrentValueSubject.swift +252 -0
- package/Sources/Combine/CustomCombineIdentifierConvertible.swift +28 -0
- package/Sources/Combine/Future.swift +228 -0
- package/Sources/Combine/GENERATED-RootProtocols.swift +426 -0
- package/Sources/Combine/Helpers/ConduitBase.swift +40 -0
- package/Sources/Combine/Helpers/ConduitList.swift +59 -0
- package/Sources/Combine/Helpers/DebugHook.swift +177 -0
- package/Sources/Combine/Helpers/FilterProducer.swift +174 -0
- package/Sources/Combine/Helpers/Locking.swift +30 -0
- package/Sources/Combine/Helpers/PartialCompletion.swift +26 -0
- package/Sources/Combine/Helpers/ReduceProducer.swift +249 -0
- package/Sources/Combine/Helpers/SubjectSubscriber.swift +96 -0
- package/Sources/Combine/Helpers/SubscriberTap.swift +69 -0
- package/Sources/Combine/Helpers/SubscriptionStatus.swift +33 -0
- package/Sources/Combine/Helpers/SubscriptionTap.swift +33 -0
- package/Sources/Combine/Helpers/Utils.swift +30 -0
- package/Sources/Combine/Helpers/Violations.swift +33 -0
- package/Sources/Combine/ImmediateScheduler.swift +178 -0
- package/Sources/Combine/LICENSE +21 -0
- package/Sources/Combine/NotificationPublisher.swift +48 -0
- package/Sources/Combine/ObjectWillChange.swift +46 -0
- package/Sources/Combine/PassthroughSubject.swift +222 -0
- package/Sources/Combine/Publisher+Subscribe.swift +53 -0
- package/Sources/Combine/Publishers/Deferred.swift +48 -0
- package/Sources/Combine/Publishers/Empty.swift +54 -0
- package/Sources/Combine/Publishers/Fail.swift +42 -0
- package/Sources/Combine/Publishers/GENERATED-Publishers.Catch.swift +673 -0
- package/Sources/Combine/Publishers/GENERATED-Publishers.Encode.swift +388 -0
- package/Sources/Combine/Publishers/GENERATED-Publishers.MapKeyPath.swift +384 -0
- package/Sources/Combine/Publishers/Just.swift +313 -0
- package/Sources/Combine/Publishers/Optional.Publisher.swift +315 -0
- package/Sources/Combine/Publishers/Publishers.AllSatisfy.swift +217 -0
- package/Sources/Combine/Publishers/Publishers.AssertNoFailure.swift +158 -0
- package/Sources/Combine/Publishers/Publishers.Autoconnect.swift +193 -0
- package/Sources/Combine/Publishers/Publishers.Breakpoint.swift +231 -0
- package/Sources/Combine/Publishers/Publishers.Buffer.swift +356 -0
- package/Sources/Combine/Publishers/Publishers.Collect.swift +102 -0
- package/Sources/Combine/Publishers/Publishers.CollectByCount.swift +195 -0
- package/Sources/Combine/Publishers/Publishers.CompactMap.swift +241 -0
- package/Sources/Combine/Publishers/Publishers.Comparison.swift +371 -0
- package/Sources/Combine/Publishers/Publishers.Concatenate.swift +474 -0
- package/Sources/Combine/Publishers/Publishers.Contains.swift +293 -0
- package/Sources/Combine/Publishers/Publishers.Count.swift +87 -0
- package/Sources/Combine/Publishers/Publishers.Debounce.swift +332 -0
- package/Sources/Combine/Publishers/Publishers.Delay.swift +269 -0
- package/Sources/Combine/Publishers/Publishers.Drop.swift +155 -0
- package/Sources/Combine/Publishers/Publishers.DropUntilOutput.swift +283 -0
- package/Sources/Combine/Publishers/Publishers.DropWhile.swift +378 -0
- package/Sources/Combine/Publishers/Publishers.Filter.swift +248 -0
- package/Sources/Combine/Publishers/Publishers.First.swift +261 -0
- package/Sources/Combine/Publishers/Publishers.FlatMap.swift +533 -0
- package/Sources/Combine/Publishers/Publishers.HandleEvents.swift +260 -0
- package/Sources/Combine/Publishers/Publishers.IgnoreOutput.swift +109 -0
- package/Sources/Combine/Publishers/Publishers.Last.swift +252 -0
- package/Sources/Combine/Publishers/Publishers.MakeConnectable.swift +82 -0
- package/Sources/Combine/Publishers/Publishers.Map.swift +351 -0
- package/Sources/Combine/Publishers/Publishers.MapError.swift +140 -0
- package/Sources/Combine/Publishers/Publishers.MeasureInterval.swift +187 -0
- package/Sources/Combine/Publishers/Publishers.Multicast.swift +284 -0
- package/Sources/Combine/Publishers/Publishers.Output.swift +241 -0
- package/Sources/Combine/Publishers/Publishers.PrefixUntilOutput.swift +197 -0
- package/Sources/Combine/Publishers/Publishers.PrefixWhile.swift +176 -0
- package/Sources/Combine/Publishers/Publishers.Print.swift +206 -0
- package/Sources/Combine/Publishers/Publishers.ReceiveOn.swift +227 -0
- package/Sources/Combine/Publishers/Publishers.Reduce.swift +204 -0
- package/Sources/Combine/Publishers/Publishers.RemoveDuplicates.swift +264 -0
- package/Sources/Combine/Publishers/Publishers.ReplaceEmpty.swift +201 -0
- package/Sources/Combine/Publishers/Publishers.ReplaceError.swift +211 -0
- package/Sources/Combine/Publishers/Publishers.Retry.swift +274 -0
- package/Sources/Combine/Publishers/Publishers.Scan.swift +331 -0
- package/Sources/Combine/Publishers/Publishers.Sequence.swift +437 -0
- package/Sources/Combine/Publishers/Publishers.SetFailureType.swift +120 -0
- package/Sources/Combine/Publishers/Publishers.Share.swift +104 -0
- package/Sources/Combine/Publishers/Publishers.SubscribeOn.swift +197 -0
- package/Sources/Combine/Publishers/Publishers.SwitchToLatest.swift +444 -0
- package/Sources/Combine/Publishers/Publishers.Throttle.swift +359 -0
- package/Sources/Combine/Publishers/Publishers.Timeout.swift +301 -0
- package/Sources/Combine/Publishers/Publishers.Zip.swift +720 -0
- package/Sources/Combine/Publishers/Publishers.swift +13 -0
- package/Sources/Combine/Publishers/Record.swift +237 -0
- package/Sources/Combine/Publishers/Result.Publisher.swift +337 -0
- package/Sources/Combine/Result.swift +46 -0
- package/Sources/Combine/Scheduler.swift +89 -0
- package/Sources/Combine/Schedulers.swift +211 -0
- package/Sources/Combine/Subject+Void.swift +17 -0
- package/Sources/Combine/Subscriber+Void.swift +20 -0
- package/Sources/Combine/Subscribers/Subscribers.Assign.swift +175 -0
- package/Sources/Combine/Subscribers/Subscribers.Completion.swift +90 -0
- package/Sources/Combine/Subscribers/Subscribers.Demand.swift +476 -0
- package/Sources/Combine/Subscribers/Subscribers.Sink.swift +206 -0
- package/Sources/Combine/Subscribers/Subscribers.swift +9 -0
- package/Sources/Combine/Subscription.swift +22 -0
- package/Sources/Combine/Subscriptions.swift +42 -0
- package/Sources/Combine/SwiftUIObservation.swift +10 -0
- package/Sources/Combine/_Introspection.swift +107 -0
- package/Sources/CommonCrypto/CommonCrypto.swift +80 -0
- package/Sources/Compression/Compression.swift +365 -0
- package/Sources/Compression/Deflate.swift +407 -0
- package/Sources/Compression/Zlib.swift +179 -0
- package/Sources/CoreFoundationTypes/CoreFoundationTypes.swift +101 -0
- package/Sources/CoreGraphics/CoreGraphics.swift +411 -0
- package/Sources/CoreGraphics/ProjectionTransforms.swift +28 -0
- package/Sources/CoreHaptics/CoreHaptics.swift +399 -0
- package/Sources/CoreImage/CIColor.swift +41 -0
- package/Sources/CoreImage/CIContext.swift +31 -0
- package/Sources/CoreImage/CIDetector.swift +57 -0
- package/Sources/CoreImage/CIFilter.swift +243 -0
- package/Sources/CoreImage/CIFilterBuiltins.swift +136 -0
- package/Sources/CoreImage/CIImage.swift +162 -0
- package/Sources/CoreImage/QRCode.swift +393 -0
- package/Sources/CoreLocation/Coordinate.swift +30 -0
- package/Sources/CoreLocation/Location.swift +65 -0
- package/Sources/CoreML/Evaluation.swift +414 -0
- package/Sources/CoreML/FeatureValue.swift +266 -0
- package/Sources/CoreML/Model.swift +269 -0
- package/Sources/CoreML/MultiArray.swift +92 -0
- package/Sources/CoreML/Specification.swift +233 -0
- package/Sources/CoreText/CoreText.swift +64 -0
- package/Sources/CoreTransferable/CoreTransferable.swift +606 -0
- package/Sources/CryptoKit/ChaChaPoly.swift +258 -0
- package/Sources/CryptoKit/CryptoKit.swift +375 -0
- package/Sources/CryptoKit/Curve25519.swift +317 -0
- package/Sources/CryptoKit/P256.swift +321 -0
- package/Sources/FoundationBridge/AppStorage.swift +165 -0
- package/Sources/FoundationBridge/AssetResources.swift +90 -0
- package/Sources/FoundationBridge/AsyncBytes.swift +128 -0
- package/Sources/FoundationBridge/AsyncImage.swift +116 -0
- package/Sources/FoundationBridge/AttributedStrings.swift +16 -0
- package/Sources/FoundationBridge/Bundle.swift +119 -0
- package/Sources/FoundationBridge/CombineExports.swift +8 -0
- package/Sources/FoundationBridge/CoreFoundation.swift +77 -0
- package/Sources/FoundationBridge/Dispatch.swift +458 -0
- package/Sources/FoundationBridge/EnvironmentFoundation.swift +41 -0
- package/Sources/FoundationBridge/FileImporter.swift +128 -0
- package/Sources/FoundationBridge/FileSystem.swift +68 -0
- package/Sources/FoundationBridge/FoundationBridge.swift +29 -0
- package/Sources/FoundationBridge/HostResolution.swift +31 -0
- package/Sources/FoundationBridge/ItemProvider.swift +655 -0
- package/Sources/FoundationBridge/KeyValueObserving.swift +138 -0
- package/Sources/FoundationBridge/Links.swift +127 -0
- package/Sources/FoundationBridge/ListFormatter.swift +32 -0
- package/Sources/FoundationBridge/Locale.swift +86 -0
- package/Sources/FoundationBridge/Localization.swift +149 -0
- package/Sources/FoundationBridge/Locks.swift +50 -0
- package/Sources/FoundationBridge/Markdown.swift +527 -0
- package/Sources/FoundationBridge/MeasurementFormat.swift +95 -0
- package/Sources/FoundationBridge/NotificationCenter.swift +154 -0
- package/Sources/FoundationBridge/OpenURLHandlers.swift +60 -0
- package/Sources/FoundationBridge/Operation.swift +195 -0
- package/Sources/FoundationBridge/ProcessInfo.swift +32 -0
- package/Sources/FoundationBridge/RelativeDateTimeFormatter.swift +136 -0
- package/Sources/FoundationBridge/SceneStorage.swift +78 -0
- package/Sources/FoundationBridge/SecurityExports.swift +8 -0
- package/Sources/FoundationBridge/Selector.swift +226 -0
- package/Sources/FoundationBridge/StringComparators.swift +17 -0
- package/Sources/FoundationBridge/Table.swift +211 -0
- package/Sources/FoundationBridge/TextAttributes.swift +42 -0
- package/Sources/FoundationBridge/Timer.swift +53 -0
- package/Sources/FoundationBridge/UITextChecker.swift +30 -0
- package/Sources/FoundationBridge/URLSession.swift +718 -0
- package/Sources/FoundationBridge/UserDefaults.swift +183 -0
- package/Sources/FoundationBridge/WebAuthRedirects.swift +227 -0
- package/Sources/FoundationBridge/WebSocket.swift +187 -0
- package/Sources/FoundationModels/FoundationModels.swift +1098 -0
- package/Sources/ImageIO/GIF.swift +72 -0
- package/Sources/ImageIO/ImageIO.swift +248 -0
- package/Sources/ImageIO/ImageTypes.swift +28 -0
- package/Sources/LinkPresentation/LinkPresentation.swift +249 -0
- package/Sources/LocalAuthentication/LAContext.swift +86 -0
- package/Sources/MapKit/Geometry.swift +223 -0
- package/Sources/MapKit/Map.swift +638 -0
- package/Sources/MapKit/MapView.swift +229 -0
- package/Sources/MobileCoreServices/MobileCoreServices.swift +28 -0
- package/Sources/NaturalLanguage/LanguageIdentifier.swift +317 -0
- package/Sources/NaturalLanguage/NaturalLanguage.swift +135 -0
- package/Sources/OSLog/OSLog.swift +6 -0
- package/Sources/Photos/Photos.swift +572 -0
- package/Sources/PhotosUI/PhotosPicker.swift +248 -0
- package/Sources/PhotosUI/PhotosPickerItem.swift +261 -0
- package/Sources/QuickLook/QuickLook.swift +168 -0
- package/Sources/SafariServices/SafariServices.swift +106 -0
- package/Sources/Security/Security.swift +332 -0
- package/Sources/StoreKit/AppStore.swift +207 -0
- package/Sources/StoreKit/Products.swift +280 -0
- package/Sources/StoreKit/RequestReview.swift +28 -0
- package/Sources/StoreKit/StoreKit1.swift +486 -0
- package/Sources/StoreKit/StoreViews.swift +428 -0
- package/Sources/StoreKit/Transactions.swift +197 -0
- package/Sources/SwiftData/Macros.swift +58 -0
- package/Sources/SwiftData/ModelActor.swift +38 -0
- package/Sources/SwiftData/ModelContainer.swift +129 -0
- package/Sources/SwiftData/ModelContext.swift +451 -0
- package/Sources/SwiftData/PersistentModel.swift +238 -0
- package/Sources/SwiftData/Properties.swift +261 -0
- package/Sources/SwiftData/Query.swift +256 -0
- package/Sources/SwiftData/Schema.swift +192 -0
- package/Sources/SwiftData/Store.swift +146 -0
- package/Sources/SwiftData/StringPredicates.swift +125 -0
- package/Sources/SwiftDataMacros/EntryMacro.swift +82 -0
- package/Sources/SwiftDataMacros/GenerableMacro.swift +183 -0
- package/Sources/SwiftDataMacros/ModelActorMacro.swift +46 -0
- package/Sources/SwiftDataMacros/ModelMacro.swift +260 -0
- package/Sources/SwiftDataMacros/Plugin.swift +18 -0
- package/Sources/SwiftDataMacros/PredicateMacro.swift +1244 -0
- package/Sources/SwiftUI/API/Accessibility.swift +181 -0
- package/Sources/SwiftUI/API/AccessibilityExtras.swift +33 -0
- package/Sources/SwiftUI/API/AccessibilityFocus.swift +63 -0
- package/Sources/SwiftUI/API/Alert.swift +221 -0
- package/Sources/SwiftUI/API/AlignmentGuides.swift +65 -0
- package/Sources/SwiftUI/API/Animation.swift +285 -0
- package/Sources/SwiftUI/API/App.swift +87 -0
- package/Sources/SwiftUI/API/BindingCollections.swift +35 -0
- package/Sources/SwiftUI/API/BindingForEach.swift +27 -0
- package/Sources/SwiftUI/API/Bitmaps.swift +254 -0
- package/Sources/SwiftUI/API/ButtonStyles.swift +96 -0
- package/Sources/SwiftUI/API/Canvas.swift +337 -0
- package/Sources/SwiftUI/API/Color.swift +237 -0
- package/Sources/SwiftUI/API/ColorEffects.swift +52 -0
- package/Sources/SwiftUI/API/ColorPickerAndLabeledContent.swift +138 -0
- package/Sources/SwiftUI/API/ColorSpaces.swift +161 -0
- package/Sources/SwiftUI/API/Commands.swift +106 -0
- package/Sources/SwiftUI/API/ContainerBackground.swift +28 -0
- package/Sources/SwiftUI/API/ContentShape.swift +33 -0
- package/Sources/SwiftUI/API/ContentSizeCategory.swift +35 -0
- package/Sources/SwiftUI/API/ContentUnavailable.swift +101 -0
- package/Sources/SwiftUI/API/Controls.swift +300 -0
- package/Sources/SwiftUI/API/CustomLayout.swift +442 -0
- package/Sources/SwiftUI/API/CustomToolbarContent.swift +46 -0
- package/Sources/SwiftUI/API/Decorations.swift +92 -0
- package/Sources/SwiftUI/API/EditMode.swift +212 -0
- package/Sources/SwiftUI/API/Effects.swift +388 -0
- package/Sources/SwiftUI/API/Entry.swift +8 -0
- package/Sources/SwiftUI/API/Environment.swift +439 -0
- package/Sources/SwiftUI/API/EnvironmentSendable.swift +6 -0
- package/Sources/SwiftUI/API/Focus.swift +137 -0
- package/Sources/SwiftUI/API/Font.swift +131 -0
- package/Sources/SwiftUI/API/Gauge.swift +290 -0
- package/Sources/SwiftUI/API/Geometry.swift +89 -0
- package/Sources/SwiftUI/API/GeometryEffects.swift +232 -0
- package/Sources/SwiftUI/API/GeometryReader.swift +135 -0
- package/Sources/SwiftUI/API/GestureState.swift +65 -0
- package/Sources/SwiftUI/API/Gestures.swift +342 -0
- package/Sources/SwiftUI/API/Glass.swift +127 -0
- package/Sources/SwiftUI/API/Grid.swift +188 -0
- package/Sources/SwiftUI/API/GroupBoxAndControlGroup.swift +130 -0
- package/Sources/SwiftUI/API/KeyPress.swift +54 -0
- package/Sources/SwiftUI/API/LabelStyle.swift +124 -0
- package/Sources/SwiftUI/API/Layout.swift +220 -0
- package/Sources/SwiftUI/API/LazyStacks.swift +49 -0
- package/Sources/SwiftUI/API/LegacyAlert.swift +97 -0
- package/Sources/SwiftUI/API/Lists.swift +331 -0
- package/Sources/SwiftUI/API/Menu.swift +58 -0
- package/Sources/SwiftUI/API/Modifiers.swift +313 -0
- package/Sources/SwiftUI/API/MoreModifiers.swift +100 -0
- package/Sources/SwiftUI/API/Namespace.swift +44 -0
- package/Sources/SwiftUI/API/Navigation.swift +386 -0
- package/Sources/SwiftUI/API/NavigationDestinationBindings.swift +55 -0
- package/Sources/SwiftUI/API/ObservableObject.swift +293 -0
- package/Sources/SwiftUI/API/OnChange.swift +48 -0
- package/Sources/SwiftUI/API/Path.swift +543 -0
- package/Sources/SwiftUI/API/Phase8Controls.swift +411 -0
- package/Sources/SwiftUI/API/PhaseAnimator.swift +130 -0
- package/Sources/SwiftUI/API/Picker.swift +185 -0
- package/Sources/SwiftUI/API/PointerAndKeyboard.swift +77 -0
- package/Sources/SwiftUI/API/Popover.swift +41 -0
- package/Sources/SwiftUI/API/Preferences.swift +262 -0
- package/Sources/SwiftUI/API/Presentation.swift +122 -0
- package/Sources/SwiftUI/API/PresentationExtras.swift +60 -0
- package/Sources/SwiftUI/API/Primitives.swift +517 -0
- package/Sources/SwiftUI/API/Publishers.swift +107 -0
- package/Sources/SwiftUI/API/Redaction.swift +75 -0
- package/Sources/SwiftUI/API/RowActions.swift +84 -0
- package/Sources/SwiftUI/API/Scenes.swift +131 -0
- package/Sources/SwiftUI/API/ScrollModifiers.swift +132 -0
- package/Sources/SwiftUI/API/ScrollTargets.swift +104 -0
- package/Sources/SwiftUI/API/ScrollViewReader.swift +144 -0
- package/Sources/SwiftUI/API/SectionSupplements.swift +96 -0
- package/Sources/SwiftUI/API/Shape.swift +214 -0
- package/Sources/SwiftUI/API/ShapeStyle.swift +409 -0
- package/Sources/SwiftUI/API/ShapeTrim.swift +78 -0
- package/Sources/SwiftUI/API/Sharing.swift +193 -0
- package/Sources/SwiftUI/API/StackLayouts.swift +199 -0
- package/Sources/SwiftUI/API/State.swift +144 -0
- package/Sources/SwiftUI/API/StatusGaps.swift +121 -0
- package/Sources/SwiftUI/API/StrokeStyle.swift +30 -0
- package/Sources/SwiftUI/API/SymbolEffects.swift +203 -0
- package/Sources/SwiftUI/API/TabContent.swift +841 -0
- package/Sources/SwiftUI/API/Table.swift +382 -0
- package/Sources/SwiftUI/API/Tabs.swift +263 -0
- package/Sources/SwiftUI/API/Tasks.swift +35 -0
- package/Sources/SwiftUI/API/Text.swift +386 -0
- package/Sources/SwiftUI/API/TextDates.swift +61 -0
- package/Sources/SwiftUI/API/TextDecorations.swift +52 -0
- package/Sources/SwiftUI/API/TextFieldAxis.swift +103 -0
- package/Sources/SwiftUI/API/TextFieldCommit.swift +52 -0
- package/Sources/SwiftUI/API/Timeline.swift +212 -0
- package/Sources/SwiftUI/API/Toolbar.swift +251 -0
- package/Sources/SwiftUI/API/Transfer.swift +145 -0
- package/Sources/SwiftUI/API/UnevenRoundedRectangle.swift +66 -0
- package/Sources/SwiftUI/API/Video.swift +64 -0
- package/Sources/SwiftUI/API/View.swift +215 -0
- package/Sources/SwiftUI/API/ViewModifier.swift +43 -0
- package/Sources/SwiftUI/API/VisualEffect.swift +155 -0
- package/Sources/SwiftUI/API/Windows.swift +25 -0
- package/Sources/SwiftUI/Charts/Axis.swift +325 -0
- package/Sources/SwiftUI/Charts/AxisFormatsAndRanges.swift +68 -0
- package/Sources/SwiftUI/Charts/Chart.swift +660 -0
- package/Sources/SwiftUI/Charts/ChartContent.swift +376 -0
- package/Sources/SwiftUI/Charts/ChartProxy.swift +57 -0
- package/Sources/SwiftUI/Charts/Marks.swift +204 -0
- package/Sources/SwiftUI/Charts/Plottable.swift +99 -0
- package/Sources/SwiftUI/Charts/Scales.swift +326 -0
- package/Sources/SwiftUI/Localization/Localization.swift +498 -0
- package/Sources/SwiftUI/Localization/PluralRules.swift +127 -0
- package/Sources/SwiftUI/Runtime/Executor.swift +85 -0
- package/Sources/SwiftUI/Runtime/Exports.swift +101 -0
- package/Sources/SwiftUI/Runtime/ImageSource.swift +310 -0
- package/Sources/SwiftUI/Runtime/JSON.swift +143 -0
- package/Sources/SwiftUI/Runtime/JSONParser.swift +443 -0
- package/Sources/SwiftUI/Runtime/LazyRows.swift +99 -0
- package/Sources/SwiftUI/Runtime/Measurements.swift +140 -0
- package/Sources/SwiftUI/Runtime/Ops.swift +152 -0
- package/Sources/SwiftUI/Runtime/Reconciler.swift +219 -0
- package/Sources/SwiftUI/Runtime/Replay.swift +382 -0
- package/Sources/SwiftUI/Runtime/Runtime.swift +2146 -0
- package/Sources/SwiftUI/Runtime/Sameness.swift +152 -0
- package/Sources/SwiftUI/Runtime/ViewPath.swift +89 -0
- package/Sources/SwiftUI/Runtime/ViewTraits.swift +175 -0
- package/Sources/SwiftUI/Runtime/WebAuthHeadless.swift +49 -0
- package/Sources/Symbols/Symbols.swift +25 -0
- package/Sources/Translation/Translation.swift +423 -0
- package/Sources/UIKit/Activity.swift +213 -0
- package/Sources/UIKit/Alerts.swift +69 -0
- package/Sources/UIKit/AppDelegate.swift +222 -0
- package/Sources/UIKit/Appearance.swift +84 -0
- package/Sources/UIKit/ColorConversions.swift +70 -0
- package/Sources/UIKit/Controls.swift +225 -0
- package/Sources/UIKit/Device.swift +200 -0
- package/Sources/UIKit/Feedback.swift +65 -0
- package/Sources/UIKit/Font.swift +307 -0
- package/Sources/UIKit/Graphics.swift +204 -0
- package/Sources/UIKit/HostingController.swift +185 -0
- package/Sources/UIKit/Identity.swift +24 -0
- package/Sources/UIKit/Introspectable.swift +510 -0
- package/Sources/UIKit/Pasteboard.swift +363 -0
- package/Sources/UIKit/PhotoAlbum.swift +81 -0
- package/Sources/UIKit/RemoteNotifications.swift +15 -0
- package/Sources/UIKit/Representable.swift +288 -0
- package/Sources/UIKit/SafeArea.swift +12 -0
- package/Sources/UIKit/SceneDelegates.swift +132 -0
- package/Sources/UIKit/Scenes.swift +40 -0
- package/Sources/UIKit/ScrollView.swift +157 -0
- package/Sources/UIKit/ShortcutItems.swift +67 -0
- package/Sources/UIKit/SymbolConfiguration.swift +124 -0
- package/Sources/UIKit/TargetAction.swift +123 -0
- package/Sources/UIKit/TextPaste.swift +161 -0
- package/Sources/UIKit/TextView.swift +538 -0
- package/Sources/UIKit/UIKit.swift +292 -0
- package/Sources/UIKit/UIView.swift +855 -0
- package/Sources/UIKit/ViewTranslation.swift +311 -0
- package/Sources/UniformTypeIdentifiers/UTType.swift +196 -0
- package/Sources/UserNotifications/Content.swift +370 -0
- package/Sources/UserNotifications/NotificationCenter.swift +309 -0
- package/Sources/WeatherKit/WeatherKit.swift +228 -0
- package/Sources/WebKit/WebKit.swift +245 -0
- package/Sources/os/os.swift +376 -0
- package/Sources/zlib/zlib.swift +6 -0
- package/index.d.ts +2 -0
- package/index.mjs +16 -0
- package/manifest.d.mts +2 -0
- package/manifest.mjs +39 -0
- package/package.json +30 -4
- package/sync-sources.mjs +33 -0
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
// Assets: a URL and what the page can tell about it. `AVAsset` reads nothing
|
|
2
|
+
// itself; a `load` asks the page to open the media's metadata (a `media`
|
|
3
|
+
// probe: duration and video size) once per asset, as `AsyncImage` asks for an
|
|
4
|
+
// image's size. A file URL is first handed to the page as a blob.
|
|
5
|
+
|
|
6
|
+
import Foundation
|
|
7
|
+
import FoundationBridge
|
|
8
|
+
import SwiftUI
|
|
9
|
+
import struct SwiftUI.CGSize
|
|
10
|
+
import struct SwiftUI.CGRect
|
|
11
|
+
import UIKit
|
|
12
|
+
|
|
13
|
+
/// What the page read from a media file's metadata.
|
|
14
|
+
struct _AVMediaInfo: Sendable, Equatable {
|
|
15
|
+
/// Seconds; nil for a live stream or a length the file does not state.
|
|
16
|
+
var duration: Double?
|
|
17
|
+
/// The video's size in pixels; 0 × 0 for audio.
|
|
18
|
+
var width: Double
|
|
19
|
+
var height: Double
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/// The page's side of media: blobs for files, metadata probes. Tests replace `perform`.
|
|
23
|
+
@MainActor
|
|
24
|
+
enum _AVMediaHost {
|
|
25
|
+
static var perform: @MainActor (_JSON) async throws -> _JSON = { params in
|
|
26
|
+
try await _Runtime.shared._hostRequest(kind: "media", params: params)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/// A URL the page can load for `url`: remote, data and blob URLs as they
|
|
30
|
+
/// are; a file's bytes as a blob URL (made once per file URL).
|
|
31
|
+
static func pageURL(for url: URL) async throws -> String {
|
|
32
|
+
guard url.isFileURL else { return url.absoluteString }
|
|
33
|
+
if let known = blobs[url] { return known }
|
|
34
|
+
let data: Data
|
|
35
|
+
do {
|
|
36
|
+
data = try Data(contentsOf: url)
|
|
37
|
+
} catch {
|
|
38
|
+
throw AVError(.contentIsUnavailable, message: "cannot read \(url.path): \(error)")
|
|
39
|
+
}
|
|
40
|
+
let answer = try await perform(.object([
|
|
41
|
+
"action": .string("file"),
|
|
42
|
+
"name": .string(url.lastPathComponent),
|
|
43
|
+
"type": .string(_mimeType(forPathExtension: url.pathExtension)),
|
|
44
|
+
"data": .string(_base64(Array(data))),
|
|
45
|
+
]))
|
|
46
|
+
guard case .object(let fields) = answer, case .string(let pageURL)? = fields["url"] else {
|
|
47
|
+
throw AVError(.unknown, message: "the page made no URL for \(url.lastPathComponent)")
|
|
48
|
+
}
|
|
49
|
+
blobs[url] = pageURL
|
|
50
|
+
return pageURL
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private static var blobs: [URL: String] = [:]
|
|
54
|
+
|
|
55
|
+
/// The metadata of the media at `url`.
|
|
56
|
+
static func probe(_ url: URL) async throws -> _AVMediaInfo {
|
|
57
|
+
let pageURL = try await pageURL(for: url)
|
|
58
|
+
let answer: _JSON
|
|
59
|
+
do {
|
|
60
|
+
answer = try await perform(.object(["action": .string("probe"), "url": .string(pageURL)]))
|
|
61
|
+
} catch {
|
|
62
|
+
throw AVError(.failedToLoadMediaData, message: "\(error)")
|
|
63
|
+
}
|
|
64
|
+
guard case .object(let fields) = answer else { throw AVError(.fileFormatNotRecognized) }
|
|
65
|
+
func number(_ key: String) -> Double? {
|
|
66
|
+
if case .number(let value)? = fields[key], value.isFinite { return value }
|
|
67
|
+
return nil
|
|
68
|
+
}
|
|
69
|
+
return _AVMediaInfo(duration: number("duration"), width: number("width") ?? 0, height: number("height") ?? 0)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// MARK: - Assets
|
|
74
|
+
|
|
75
|
+
/// The state of a value an asset loads (`statusOfValue(forKey:error:)`).
|
|
76
|
+
public enum AVKeyValueStatus: Int, Sendable {
|
|
77
|
+
case unknown, loading, loaded, failed, cancelled
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/// A timed media resource. Make one with `AVURLAsset(url:)` (or `AVAsset(url:)`).
|
|
81
|
+
open class AVAsset: @unchecked Sendable {
|
|
82
|
+
/// The resource; nil only for subclasses that have none.
|
|
83
|
+
let _url: URL?
|
|
84
|
+
private var info: _AVMediaInfo?
|
|
85
|
+
private var loadError: (any Error)?
|
|
86
|
+
private var probing: Task<_AVMediaInfo, any Error>?
|
|
87
|
+
|
|
88
|
+
public init(url URL: URL) {
|
|
89
|
+
_url = URL
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
init(_noURL: Void) {
|
|
93
|
+
_url = nil
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/// The metadata, from the page (once).
|
|
97
|
+
@MainActor
|
|
98
|
+
func _info() async throws -> _AVMediaInfo {
|
|
99
|
+
if let info { return info }
|
|
100
|
+
if let loadError { throw loadError }
|
|
101
|
+
guard let url = _url else { throw AVError(.operationNotSupportedForAsset) }
|
|
102
|
+
let task = probing ?? Task { @MainActor in try await _AVMediaHost.probe(url) }
|
|
103
|
+
probing = task
|
|
104
|
+
do {
|
|
105
|
+
let value = try await task.value
|
|
106
|
+
info = value
|
|
107
|
+
return value
|
|
108
|
+
} catch {
|
|
109
|
+
loadError = error
|
|
110
|
+
throw error
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/// Metadata the player learned while playing the asset (its `ready` event).
|
|
115
|
+
func _learn(_ value: _AVMediaInfo) {
|
|
116
|
+
if info == nil { info = value }
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/// The duration, if loaded (`load(.duration)`); `.indefinite` until then
|
|
120
|
+
/// and for a live stream.
|
|
121
|
+
@available(*, deprecated, message: "Use load(.duration) instead")
|
|
122
|
+
open var duration: CMTime { _knownDuration }
|
|
123
|
+
|
|
124
|
+
var _knownDuration: CMTime { CMTime(_seconds: info?.duration) }
|
|
125
|
+
|
|
126
|
+
@available(*, deprecated, message: "Use load(.isPlayable) instead")
|
|
127
|
+
open var isPlayable: Bool { loadError == nil }
|
|
128
|
+
|
|
129
|
+
@available(*, deprecated, message: "Use load(.tracks) instead")
|
|
130
|
+
open var tracks: [AVAssetTrack] { info.map { AVAssetTrack._tracks(of: self, info: $0) } ?? [] }
|
|
131
|
+
|
|
132
|
+
open var preferredRate: Float { 1 }
|
|
133
|
+
open var preferredVolume: Float { 1 }
|
|
134
|
+
open var preferredTransform: CGAffineTransform { .identity }
|
|
135
|
+
open var providesPreciseDurationAndTiming: Bool { false }
|
|
136
|
+
|
|
137
|
+
/// Loads the values for `keys` ("duration", "playable", "tracks"), then calls `handler`.
|
|
138
|
+
open func loadValuesAsynchronously(forKeys keys: [String], completionHandler handler: (@Sendable () -> Void)? = nil) {
|
|
139
|
+
Task { @MainActor in
|
|
140
|
+
_ = try? await self._info()
|
|
141
|
+
handler?()
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
open func statusOfValue(forKey key: String, error outError: UnsafeMutablePointer<NSError?>?) -> AVKeyValueStatus {
|
|
146
|
+
if info != nil { return .loaded }
|
|
147
|
+
if let loadError {
|
|
148
|
+
outError?.pointee = NSError(domain: AVFoundationErrorDomain, code: (loadError as? AVError)?.code.rawValue ?? AVError.Code.unknown.rawValue,
|
|
149
|
+
userInfo: [NSLocalizedDescriptionKey: "\(loadError)"])
|
|
150
|
+
return .failed
|
|
151
|
+
}
|
|
152
|
+
return probing == nil ? .unknown : .loading
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
open func cancelLoading() {}
|
|
156
|
+
|
|
157
|
+
/// Loads one value (`AVAsyncProperty`'s key).
|
|
158
|
+
@MainActor
|
|
159
|
+
func _load(_ key: String) async throws -> any Sendable {
|
|
160
|
+
switch key {
|
|
161
|
+
case "isPlayable":
|
|
162
|
+
return (try? await _info()) != nil
|
|
163
|
+
case "duration":
|
|
164
|
+
return CMTime(_seconds: try await _info().duration)
|
|
165
|
+
case "tracks":
|
|
166
|
+
return AVAssetTrack._tracks(of: self, info: try await _info())
|
|
167
|
+
case "preferredRate", "preferredVolume":
|
|
168
|
+
return Float(1)
|
|
169
|
+
case "preferredTransform":
|
|
170
|
+
return CGAffineTransform.identity
|
|
171
|
+
case "isExportable", "isReadable":
|
|
172
|
+
return _url?.isFileURL == true
|
|
173
|
+
case "metadata", "commonMetadata":
|
|
174
|
+
return [AVMetadataItem]()
|
|
175
|
+
default:
|
|
176
|
+
throw AVError(.operationNotSupportedForAsset, message: "cannot load \(key)")
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/// An asset at a URL: a remote file or stream, a data URL, or a file of the
|
|
182
|
+
/// app's (bundle, home, temporary directory).
|
|
183
|
+
open class AVURLAsset: AVAsset, @unchecked Sendable {
|
|
184
|
+
public let url: URL
|
|
185
|
+
|
|
186
|
+
/// `options` (precise timing, HTTP headers…) are kept and not applied:
|
|
187
|
+
/// the browser loads the media with its own requests.
|
|
188
|
+
public init(url URL: URL, options: [String: Any]? = nil) {
|
|
189
|
+
url = URL
|
|
190
|
+
super.init(url: URL)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
public static func audiovisualTypes() -> [AVFileType] { [.mp4, .mov, .m4v, .m4a, .mp3, .wav] }
|
|
194
|
+
public static func audiovisualMIMETypes() -> [String] { ["video/mp4", "video/quicktime", "video/webm", "audio/mpeg", "audio/mp4", "audio/wav"] }
|
|
195
|
+
public static func isPlayableExtendedMIMEType(_ extendedMIMEType: String) -> Bool {
|
|
196
|
+
let type = extendedMIMEType.lowercased()
|
|
197
|
+
return type.hasPrefix("video/") || type.hasPrefix("audio/")
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
public let AVURLAssetPreferPreciseDurationAndTimingKey = "AVURLAssetPreferPreciseDurationAndTimingKey"
|
|
202
|
+
public let AVURLAssetHTTPHeaderFieldsKey = "AVURLAssetHTTPHeaderFieldsKey"
|
|
203
|
+
public let AVURLAssetAllowsCellularAccessKey = "AVURLAssetAllowsCellularAccessKey"
|
|
204
|
+
|
|
205
|
+
/// A metadata item; assets report none (the page reads no tags).
|
|
206
|
+
open class AVMetadataItem: @unchecked Sendable {
|
|
207
|
+
open var identifier: String? { nil }
|
|
208
|
+
open var stringValue: String? { nil }
|
|
209
|
+
open var value: (any Sendable)? { nil }
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/// A track of an asset. The page reports a video's size, so an asset with a
|
|
213
|
+
/// picture has one video track; audio tracks are not reported.
|
|
214
|
+
open class AVAssetTrack: @unchecked Sendable {
|
|
215
|
+
public private(set) weak var asset: AVAsset?
|
|
216
|
+
public let trackID: Int32
|
|
217
|
+
public let mediaType: AVMediaType
|
|
218
|
+
public let naturalSize: CGSize
|
|
219
|
+
open var preferredTransform: CGAffineTransform { .identity }
|
|
220
|
+
open var nominalFrameRate: Float { 0 }
|
|
221
|
+
open var isPlayable: Bool { true }
|
|
222
|
+
open var timeRange: CMTimeRange { CMTimeRange(start: .zero, duration: asset?._knownDuration ?? .indefinite) }
|
|
223
|
+
|
|
224
|
+
init(asset: AVAsset, trackID: Int32, mediaType: AVMediaType, naturalSize: CGSize) {
|
|
225
|
+
self.asset = asset
|
|
226
|
+
self.trackID = trackID
|
|
227
|
+
self.mediaType = mediaType
|
|
228
|
+
self.naturalSize = naturalSize
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
static func _tracks(of asset: AVAsset, info: _AVMediaInfo) -> [AVAssetTrack] {
|
|
232
|
+
guard info.width > 0, info.height > 0 else { return [] }
|
|
233
|
+
return [AVAssetTrack(asset: asset, trackID: 1, mediaType: .video, naturalSize: CGSize(width: info.width, height: info.height))]
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
open func hasMediaCharacteristic(_ characteristic: String) -> Bool { false }
|
|
237
|
+
|
|
238
|
+
@MainActor
|
|
239
|
+
func _load(_ key: String) async throws -> any Sendable {
|
|
240
|
+
switch key {
|
|
241
|
+
case "naturalSize": return naturalSize
|
|
242
|
+
case "preferredTransform": return CGAffineTransform.identity
|
|
243
|
+
case "mediaType": return mediaType
|
|
244
|
+
case "nominalFrameRate": return Float(0)
|
|
245
|
+
case "timeRange": return CMTimeRange(start: .zero, duration: try await asset?._load("duration") as? CMTime ?? .indefinite)
|
|
246
|
+
case "isPlayable": return true
|
|
247
|
+
default: throw AVError(.operationNotSupportedForAsset, message: "cannot load \(key)")
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
extension CMTime {
|
|
253
|
+
/// Seconds from the page, at a timescale of 600 (Core Media's video
|
|
254
|
+
/// default); nil is `.indefinite`.
|
|
255
|
+
init(_seconds seconds: Double?) {
|
|
256
|
+
guard let seconds, seconds.isFinite else {
|
|
257
|
+
self = seconds == .infinity ? .positiveInfinity : .indefinite
|
|
258
|
+
return
|
|
259
|
+
}
|
|
260
|
+
self.init(seconds: seconds, preferredTimescale: 600)
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// MARK: - Loading values
|
|
265
|
+
|
|
266
|
+
/// A value of `Root` that loads asynchronously (`asset.load(.duration)`).
|
|
267
|
+
public class AVPartialAsyncProperty<Root>: @unchecked Sendable {
|
|
268
|
+
let key: String
|
|
269
|
+
init(key: String) { self.key = key }
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
public final class AVAsyncProperty<Root, Value>: AVPartialAsyncProperty<Root>, @unchecked Sendable {
|
|
273
|
+
/// Whether a value has loaded (`status(of:)`).
|
|
274
|
+
public enum Status: @unchecked Sendable {
|
|
275
|
+
case notYetLoaded, loading, loaded(Value), failed(any Error)
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
extension AVAsyncProperty where Root: AVAsset, Value == CMTime {
|
|
280
|
+
public static var duration: AVAsyncProperty<Root, CMTime> { .init(key: "duration") }
|
|
281
|
+
}
|
|
282
|
+
extension AVAsyncProperty where Root: AVAsset, Value == Bool {
|
|
283
|
+
public static var isPlayable: AVAsyncProperty<Root, Bool> { .init(key: "isPlayable") }
|
|
284
|
+
public static var isExportable: AVAsyncProperty<Root, Bool> { .init(key: "isExportable") }
|
|
285
|
+
public static var isReadable: AVAsyncProperty<Root, Bool> { .init(key: "isReadable") }
|
|
286
|
+
}
|
|
287
|
+
extension AVAsyncProperty where Root: AVAsset, Value == [AVAssetTrack] {
|
|
288
|
+
public static var tracks: AVAsyncProperty<Root, [AVAssetTrack]> { .init(key: "tracks") }
|
|
289
|
+
}
|
|
290
|
+
extension AVAsyncProperty where Root: AVAsset, Value == Float {
|
|
291
|
+
public static var preferredRate: AVAsyncProperty<Root, Float> { .init(key: "preferredRate") }
|
|
292
|
+
public static var preferredVolume: AVAsyncProperty<Root, Float> { .init(key: "preferredVolume") }
|
|
293
|
+
}
|
|
294
|
+
extension AVAsyncProperty where Root: AVAsset, Value == CGAffineTransform {
|
|
295
|
+
public static var preferredTransform: AVAsyncProperty<Root, CGAffineTransform> { .init(key: "preferredTransform") }
|
|
296
|
+
}
|
|
297
|
+
extension AVAsyncProperty where Root: AVAsset, Value == [AVMetadataItem] {
|
|
298
|
+
public static var metadata: AVAsyncProperty<Root, [AVMetadataItem]> { .init(key: "metadata") }
|
|
299
|
+
public static var commonMetadata: AVAsyncProperty<Root, [AVMetadataItem]> { .init(key: "commonMetadata") }
|
|
300
|
+
}
|
|
301
|
+
extension AVAsyncProperty where Root: AVAssetTrack, Value == CGSize {
|
|
302
|
+
public static var naturalSize: AVAsyncProperty<Root, CGSize> { .init(key: "naturalSize") }
|
|
303
|
+
}
|
|
304
|
+
extension AVAsyncProperty where Root: AVAssetTrack, Value == CGAffineTransform {
|
|
305
|
+
public static var preferredTransform: AVAsyncProperty<Root, CGAffineTransform> { .init(key: "preferredTransform") }
|
|
306
|
+
}
|
|
307
|
+
extension AVAsyncProperty where Root: AVAssetTrack, Value == Float {
|
|
308
|
+
public static var nominalFrameRate: AVAsyncProperty<Root, Float> { .init(key: "nominalFrameRate") }
|
|
309
|
+
}
|
|
310
|
+
extension AVAsyncProperty where Root: AVAssetTrack, Value == CMTimeRange {
|
|
311
|
+
public static var timeRange: AVAsyncProperty<Root, CMTimeRange> { .init(key: "timeRange") }
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/// Types whose values load asynchronously: assets and their tracks.
|
|
315
|
+
public protocol AVAsynchronousKeyValueLoading {}
|
|
316
|
+
extension AVAsset: AVAsynchronousKeyValueLoading {}
|
|
317
|
+
extension AVAssetTrack: AVAsynchronousKeyValueLoading {}
|
|
318
|
+
|
|
319
|
+
extension AVAsynchronousKeyValueLoading where Self: AVAsset {
|
|
320
|
+
public func load<T>(_ property: AVAsyncProperty<Self, T>) async throws -> T {
|
|
321
|
+
try await _cast(_load(property.key))
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
public func load<A, B>(_ a: AVAsyncProperty<Self, A>, _ b: AVAsyncProperty<Self, B>) async throws -> (A, B) {
|
|
325
|
+
(try await load(a), try await load(b))
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
public func load<A, B, C>(_ a: AVAsyncProperty<Self, A>, _ b: AVAsyncProperty<Self, B>, _ c: AVAsyncProperty<Self, C>) async throws -> (A, B, C) {
|
|
329
|
+
(try await load(a), try await load(b), try await load(c))
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/// The video (or other) tracks, once the metadata has loaded.
|
|
333
|
+
public func loadTracks(withMediaType mediaType: AVMediaType) async throws -> [AVAssetTrack] {
|
|
334
|
+
try await load(.tracks).filter { $0.mediaType == mediaType }
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
public func loadTracks(withMediaType mediaType: AVMediaType, completionHandler: @escaping @Sendable ([AVAssetTrack]?, (any Error)?) -> Void) {
|
|
338
|
+
Task {
|
|
339
|
+
do { completionHandler(try await loadTracks(withMediaType: mediaType), nil) } catch { completionHandler(nil, error) }
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
extension AVAsynchronousKeyValueLoading where Self: AVAssetTrack {
|
|
345
|
+
public func load<T>(_ property: AVAsyncProperty<Self, T>) async throws -> T {
|
|
346
|
+
try await _cast(_load(property.key))
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
public func load<A, B>(_ a: AVAsyncProperty<Self, A>, _ b: AVAsyncProperty<Self, B>) async throws -> (A, B) {
|
|
350
|
+
(try await load(a), try await load(b))
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
private func _cast<T>(_ value: any Sendable) throws -> T {
|
|
355
|
+
guard let typed = value as? T else { throw AVError(.unknown, message: "unexpected value \(value)") }
|
|
356
|
+
return typed
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// MARK: - Images and exports
|
|
360
|
+
|
|
361
|
+
/// Frames of a video as images. Swift holds no decoded frames (the page
|
|
362
|
+
/// decodes video), so every request fails with `operationNotSupportedForAsset`.
|
|
363
|
+
open class AVAssetImageGenerator: @unchecked Sendable {
|
|
364
|
+
public let asset: AVAsset
|
|
365
|
+
open var appliesPreferredTrackTransform = false
|
|
366
|
+
open var maximumSize: CGSize = .zero
|
|
367
|
+
open var requestedTimeToleranceBefore: CMTime = .positiveInfinity
|
|
368
|
+
open var requestedTimeToleranceAfter: CMTime = .positiveInfinity
|
|
369
|
+
open var apertureMode: String?
|
|
370
|
+
|
|
371
|
+
public enum Result: Int, Sendable {
|
|
372
|
+
case succeeded, failed, cancelled
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
public init(asset: AVAsset) {
|
|
376
|
+
self.asset = asset
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
private var unsupported: AVError {
|
|
380
|
+
AVError(.operationNotSupportedForAsset, message: "the browser build cannot draw a video frame as an image")
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
open func copyCGImage(at requestedTime: CMTime, actualTime: UnsafeMutablePointer<CMTime>?) throws -> CGImage {
|
|
384
|
+
throw unsupported
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
open func image(at time: CMTime) async throws -> (image: CGImage, actualTime: CMTime) {
|
|
388
|
+
throw unsupported
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
open func generateCGImageAsynchronously(for requestedTime: CMTime,
|
|
392
|
+
completionHandler handler: @escaping @Sendable (CGImage?, CMTime, (any Error)?) -> Void) {
|
|
393
|
+
let error = unsupported
|
|
394
|
+
Task { handler(nil, .zero, error) }
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
open func generateCGImagesAsynchronously(forTimes requestedTimes: [NSValue],
|
|
398
|
+
completionHandler handler: @escaping @Sendable (CMTime, CGImage?, CMTime, Result, (any Error)?) -> Void) {
|
|
399
|
+
let error = unsupported
|
|
400
|
+
let count = requestedTimes.count
|
|
401
|
+
Task { for _ in 0..<count { handler(.zero, nil, .zero, .failed, error) } }
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
open func cancelAllCGImageGeneration() {}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
public let AVAssetExportPresetPassthrough = "AVAssetExportPresetPassthrough"
|
|
408
|
+
public let AVAssetExportPresetLowQuality = "AVAssetExportPresetLowQuality"
|
|
409
|
+
public let AVAssetExportPresetMediumQuality = "AVAssetExportPresetMediumQuality"
|
|
410
|
+
public let AVAssetExportPresetHighestQuality = "AVAssetExportPresetHighestQuality"
|
|
411
|
+
public let AVAssetExportPresetHEVCHighestQuality = "AVAssetExportPresetHEVCHighestQuality"
|
|
412
|
+
public let AVAssetExportPreset640x480 = "AVAssetExportPreset640x480"
|
|
413
|
+
public let AVAssetExportPreset960x540 = "AVAssetExportPreset960x540"
|
|
414
|
+
public let AVAssetExportPreset1280x720 = "AVAssetExportPreset1280x720"
|
|
415
|
+
public let AVAssetExportPreset1920x1080 = "AVAssetExportPreset1920x1080"
|
|
416
|
+
public let AVAssetExportPreset3840x2160 = "AVAssetExportPreset3840x2160"
|
|
417
|
+
public let AVAssetExportPresetAppleM4A = "AVAssetExportPresetAppleM4A"
|
|
418
|
+
|
|
419
|
+
/// Writes an asset to a file. The browser build has no encoder, so every
|
|
420
|
+
/// preset exports as `AVAssetExportPresetPassthrough` does: the file is copied
|
|
421
|
+
/// as it is (a file asset only; a remote one fails), and `outputFileType` is
|
|
422
|
+
/// recorded, not converted to.
|
|
423
|
+
open class AVAssetExportSession: @unchecked Sendable {
|
|
424
|
+
public enum Status: Int, Sendable {
|
|
425
|
+
case unknown, waiting, exporting, completed, failed, cancelled
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
public let asset: AVAsset
|
|
429
|
+
public let presetName: String
|
|
430
|
+
open var outputURL: URL?
|
|
431
|
+
open var outputFileType: AVFileType?
|
|
432
|
+
open var shouldOptimizeForNetworkUse = false
|
|
433
|
+
open var timeRange: CMTimeRange = CMTimeRange(start: .zero, duration: .positiveInfinity)
|
|
434
|
+
open var fileLengthLimit: Int64 = 0
|
|
435
|
+
open var metadata: [AVMetadataItem]?
|
|
436
|
+
open private(set) var status: Status = .unknown
|
|
437
|
+
open private(set) var error: (any Error)?
|
|
438
|
+
open private(set) var progress: Float = 0
|
|
439
|
+
open var supportedFileTypes: [AVFileType] { [.mp4, .mov, .m4v, .m4a] }
|
|
440
|
+
|
|
441
|
+
public init?(asset: AVAsset, presetName: String) {
|
|
442
|
+
self.asset = asset
|
|
443
|
+
self.presetName = presetName
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
public static func allExportPresets() -> [String] {
|
|
447
|
+
[AVAssetExportPresetPassthrough, AVAssetExportPresetLowQuality, AVAssetExportPresetMediumQuality,
|
|
448
|
+
AVAssetExportPresetHighestQuality, AVAssetExportPreset640x480, AVAssetExportPreset960x540,
|
|
449
|
+
AVAssetExportPreset1280x720, AVAssetExportPreset1920x1080]
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/// Copies the asset's file to `url`.
|
|
453
|
+
public func export(to url: URL, as fileType: AVFileType) async throws {
|
|
454
|
+
outputURL = url
|
|
455
|
+
outputFileType = fileType
|
|
456
|
+
try performCopy()
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
open func exportAsynchronously(completionHandler handler: @escaping @Sendable () -> Void) {
|
|
460
|
+
Task {
|
|
461
|
+
try? self.performCopy()
|
|
462
|
+
handler()
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
open func cancelExport() {
|
|
467
|
+
if status != .completed { status = .cancelled }
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
private func performCopy() throws {
|
|
471
|
+
status = .exporting
|
|
472
|
+
do {
|
|
473
|
+
guard let destination = outputURL else { throw AVError(.exportFailed, message: "no outputURL") }
|
|
474
|
+
guard let source = asset._url, source.isFileURL else {
|
|
475
|
+
throw AVError(.operationNotSupportedForAsset, message: "only a file can be exported in the browser")
|
|
476
|
+
}
|
|
477
|
+
let data = try Data(contentsOf: source)
|
|
478
|
+
try data.write(to: destination)
|
|
479
|
+
progress = 1
|
|
480
|
+
status = .completed
|
|
481
|
+
} catch {
|
|
482
|
+
self.error = error
|
|
483
|
+
status = .failed
|
|
484
|
+
throw error
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// `AVAudioSession`: how the app's audio mixes with other apps'. The browser
|
|
2
|
+
// mixes a page's audio with everything else on its own terms, so the session
|
|
3
|
+
// keeps the category, mode and options the app sets, every call succeeds,
|
|
4
|
+
// and nothing changes in what plays. Recording is not available: the record
|
|
5
|
+
// permission is denied.
|
|
6
|
+
|
|
7
|
+
import Foundation
|
|
8
|
+
|
|
9
|
+
public final class AVAudioSession: @unchecked Sendable {
|
|
10
|
+
private static let shared = AVAudioSession()
|
|
11
|
+
|
|
12
|
+
public static func sharedInstance() -> AVAudioSession { shared }
|
|
13
|
+
|
|
14
|
+
public struct Category: RawRepresentable, Hashable, Sendable {
|
|
15
|
+
public let rawValue: String
|
|
16
|
+
public init(rawValue: String) { self.rawValue = rawValue }
|
|
17
|
+
public static let ambient = Category(rawValue: "AVAudioSessionCategoryAmbient")
|
|
18
|
+
public static let soloAmbient = Category(rawValue: "AVAudioSessionCategorySoloAmbient")
|
|
19
|
+
public static let playback = Category(rawValue: "AVAudioSessionCategoryPlayback")
|
|
20
|
+
public static let record = Category(rawValue: "AVAudioSessionCategoryRecord")
|
|
21
|
+
public static let playAndRecord = Category(rawValue: "AVAudioSessionCategoryPlayAndRecord")
|
|
22
|
+
public static let multiRoute = Category(rawValue: "AVAudioSessionCategoryMultiRoute")
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public struct Mode: RawRepresentable, Hashable, Sendable {
|
|
26
|
+
public let rawValue: String
|
|
27
|
+
public init(rawValue: String) { self.rawValue = rawValue }
|
|
28
|
+
public static let `default` = Mode(rawValue: "AVAudioSessionModeDefault")
|
|
29
|
+
public static let moviePlayback = Mode(rawValue: "AVAudioSessionModeMoviePlayback")
|
|
30
|
+
public static let spokenAudio = Mode(rawValue: "AVAudioSessionModeSpokenAudio")
|
|
31
|
+
public static let voiceChat = Mode(rawValue: "AVAudioSessionModeVoiceChat")
|
|
32
|
+
public static let videoChat = Mode(rawValue: "AVAudioSessionModeVideoChat")
|
|
33
|
+
public static let videoRecording = Mode(rawValue: "AVAudioSessionModeVideoRecording")
|
|
34
|
+
public static let measurement = Mode(rawValue: "AVAudioSessionModeMeasurement")
|
|
35
|
+
public static let gameChat = Mode(rawValue: "AVAudioSessionModeGameChat")
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public enum RouteSharingPolicy: UInt, Sendable {
|
|
39
|
+
case `default` = 0, longFormAudio, independent, longFormVideo
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public struct CategoryOptions: OptionSet, Hashable, Sendable {
|
|
43
|
+
public let rawValue: UInt
|
|
44
|
+
public init(rawValue: UInt) { self.rawValue = rawValue }
|
|
45
|
+
public static let mixWithOthers = CategoryOptions(rawValue: 0x1)
|
|
46
|
+
public static let duckOthers = CategoryOptions(rawValue: 0x2)
|
|
47
|
+
public static let allowBluetooth = CategoryOptions(rawValue: 0x4)
|
|
48
|
+
public static let defaultToSpeaker = CategoryOptions(rawValue: 0x8)
|
|
49
|
+
public static let interruptSpokenAudioAndMixWithOthers = CategoryOptions(rawValue: 0x11)
|
|
50
|
+
public static let allowBluetoothA2DP = CategoryOptions(rawValue: 0x20)
|
|
51
|
+
public static let allowAirPlay = CategoryOptions(rawValue: 0x40)
|
|
52
|
+
public static let overrideMutedMicrophoneInterruption = CategoryOptions(rawValue: 0x80)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public struct SetActiveOptions: OptionSet, Hashable, Sendable {
|
|
56
|
+
public let rawValue: UInt
|
|
57
|
+
public init(rawValue: UInt) { self.rawValue = rawValue }
|
|
58
|
+
public static let notifyOthersOnDeactivation = SetActiveOptions(rawValue: 1)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public enum RecordPermission: UInt, Sendable {
|
|
62
|
+
case undetermined = 1970168948, denied = 1684369017, granted = 1735552628
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public enum InterruptionType: UInt, Sendable {
|
|
66
|
+
case began = 1, ended = 0
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public struct InterruptionOptions: OptionSet, Sendable {
|
|
70
|
+
public let rawValue: UInt
|
|
71
|
+
public init(rawValue: UInt) { self.rawValue = rawValue }
|
|
72
|
+
public static let shouldResume = InterruptionOptions(rawValue: 1)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public enum RouteChangeReason: UInt, Sendable {
|
|
76
|
+
case unknown = 0, newDeviceAvailable, oldDeviceUnavailable, categoryChange, override,
|
|
77
|
+
wakeFromSleep = 6, noSuitableRouteForCategory, routeConfigurationChange
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public private(set) var category: Category = .soloAmbient
|
|
81
|
+
public private(set) var mode: Mode = .default
|
|
82
|
+
public private(set) var categoryOptions: CategoryOptions = []
|
|
83
|
+
public private(set) var routeSharingPolicy: RouteSharingPolicy = .default
|
|
84
|
+
/// Whether the app made its session active (kept; nothing else changes).
|
|
85
|
+
public private(set) var _isActive = false
|
|
86
|
+
|
|
87
|
+
public var outputVolume: Float { 1 }
|
|
88
|
+
public var isOtherAudioPlaying: Bool { false }
|
|
89
|
+
public var secondaryAudioShouldBeSilencedHint: Bool { false }
|
|
90
|
+
public var sampleRate: Double { 48_000 }
|
|
91
|
+
public var outputLatency: TimeInterval { 0 }
|
|
92
|
+
public var ioBufferDuration: TimeInterval { 0.005 }
|
|
93
|
+
public var recordPermission: RecordPermission { .denied }
|
|
94
|
+
public var isInputAvailable: Bool { false }
|
|
95
|
+
public var availableCategories: [Category] { [.ambient, .soloAmbient, .playback, .record, .playAndRecord, .multiRoute] }
|
|
96
|
+
|
|
97
|
+
public func setCategory(_ category: Category) throws {
|
|
98
|
+
self.category = category
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public func setCategory(_ category: Category, options: CategoryOptions) throws {
|
|
102
|
+
self.category = category
|
|
103
|
+
categoryOptions = options
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
public func setCategory(_ category: Category, mode: Mode, options: CategoryOptions) throws {
|
|
107
|
+
self.category = category
|
|
108
|
+
self.mode = mode
|
|
109
|
+
categoryOptions = options
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
public func setCategory(_ category: Category, mode: Mode, policy: RouteSharingPolicy, options: CategoryOptions) throws {
|
|
113
|
+
self.category = category
|
|
114
|
+
self.mode = mode
|
|
115
|
+
routeSharingPolicy = policy
|
|
116
|
+
categoryOptions = options
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
public func setMode(_ mode: Mode) throws {
|
|
120
|
+
self.mode = mode
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
public func setActive(_ active: Bool, options: SetActiveOptions = []) throws {
|
|
124
|
+
_isActive = active
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
public func setPreferredSampleRate(_ sampleRate: Double) throws {}
|
|
128
|
+
public func setPreferredIOBufferDuration(_ duration: TimeInterval) throws {}
|
|
129
|
+
|
|
130
|
+
/// Recording is not available in the browser build: the answer is no.
|
|
131
|
+
public func requestRecordPermission(_ response: @escaping @Sendable (Bool) -> Void) {
|
|
132
|
+
response(false)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
public static let interruptionNotification = Notification.Name("AVAudioSessionInterruptionNotification")
|
|
136
|
+
public static let routeChangeNotification = Notification.Name("AVAudioSessionRouteChangeNotification")
|
|
137
|
+
public static let mediaServicesWereLostNotification = Notification.Name("AVAudioSessionMediaServicesWereLostNotification")
|
|
138
|
+
public static let mediaServicesWereResetNotification = Notification.Name("AVAudioSessionMediaServicesWereResetNotification")
|
|
139
|
+
public static let silenceSecondaryAudioHintNotification = Notification.Name("AVAudioSessionSilenceSecondaryAudioHintNotification")
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
public let AVAudioSessionInterruptionTypeKey = "AVAudioSessionInterruptionTypeKey"
|
|
143
|
+
public let AVAudioSessionInterruptionOptionKey = "AVAudioSessionInterruptionOptionKey"
|
|
144
|
+
public let AVAudioSessionRouteChangeReasonKey = "AVAudioSessionRouteChangeReasonKey"
|