@swiftbrowser/swift 0.1.0 → 0.3.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 +200 -9
- package/README.md +7 -9
- 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 +0 -4
- 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/{_FoundationCommon → FoundationBridge}/Bundle.swift +41 -4
- 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 +24 -72
- 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/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 +6 -1
- package/Sources/FoundationBridge/URLSession.swift +718 -0
- package/Sources/{_FoundationCommon → FoundationBridge}/UserDefaults.swift +17 -4
- 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 +55 -6
- package/Sources/SwiftUI/API/AccessibilityExtras.swift +33 -0
- package/Sources/SwiftUI/API/AccessibilityFocus.swift +63 -0
- package/Sources/SwiftUI/API/Alert.swift +1 -1
- package/Sources/SwiftUI/API/AlignmentGuides.swift +68 -0
- package/Sources/SwiftUI/API/Animation.swift +37 -5
- package/Sources/SwiftUI/API/App.swift +31 -1
- 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 +104 -28
- 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 +59 -27
- package/Sources/SwiftUI/API/CustomLayout.swift +49 -10
- package/Sources/SwiftUI/API/CustomToolbarContent.swift +46 -0
- package/Sources/SwiftUI/API/Decorations.swift +1 -1
- package/Sources/SwiftUI/API/EditMode.swift +25 -82
- package/Sources/SwiftUI/API/Effects.swift +125 -10
- package/Sources/SwiftUI/API/Entry.swift +8 -0
- package/Sources/SwiftUI/API/Environment.swift +100 -9
- package/Sources/SwiftUI/API/EnvironmentSendable.swift +6 -0
- package/Sources/SwiftUI/API/Focus.swift +11 -3
- package/Sources/SwiftUI/API/Gauge.swift +26 -10
- package/Sources/SwiftUI/API/GeometryEffects.swift +232 -0
- package/Sources/SwiftUI/API/GeometryReader.swift +13 -2
- package/Sources/SwiftUI/API/GestureState.swift +65 -0
- package/Sources/SwiftUI/API/Gestures.swift +1 -1
- package/Sources/SwiftUI/API/Glass.swift +127 -0
- package/Sources/SwiftUI/API/Grid.swift +1 -1
- package/Sources/SwiftUI/API/GroupBoxAndControlGroup.swift +130 -0
- package/Sources/SwiftUI/API/KeyPress.swift +54 -0
- package/Sources/SwiftUI/API/LabelStyle.swift +13 -6
- package/Sources/SwiftUI/API/Layout.swift +71 -12
- package/Sources/SwiftUI/API/LazyStacks.swift +49 -0
- package/Sources/SwiftUI/API/LegacyAlert.swift +97 -0
- package/Sources/SwiftUI/API/Lists.swift +61 -6
- package/Sources/SwiftUI/API/Menu.swift +8 -1
- package/Sources/SwiftUI/API/Modifiers.swift +88 -12
- package/Sources/SwiftUI/API/MoreModifiers.swift +100 -0
- package/Sources/SwiftUI/API/Namespace.swift +44 -0
- package/Sources/SwiftUI/API/Navigation.swift +24 -9
- package/Sources/SwiftUI/API/NavigationDestinationBindings.swift +55 -0
- package/Sources/SwiftUI/API/ObservableObject.swift +16 -2
- package/Sources/SwiftUI/API/Path.swift +543 -0
- package/Sources/SwiftUI/API/Phase8Controls.swift +48 -31
- package/Sources/SwiftUI/API/PhaseAnimator.swift +130 -0
- package/Sources/SwiftUI/API/Picker.swift +14 -4
- 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 +17 -4
- package/Sources/SwiftUI/API/PresentationExtras.swift +60 -0
- package/Sources/SwiftUI/API/Primitives.swift +168 -39
- package/Sources/SwiftUI/API/Publishers.swift +4 -4
- package/Sources/SwiftUI/API/Redaction.swift +75 -0
- package/Sources/SwiftUI/API/RowActions.swift +3 -2
- package/Sources/SwiftUI/API/Scenes.swift +131 -0
- package/Sources/SwiftUI/API/ScrollModifiers.swift +132 -0
- package/Sources/SwiftUI/API/ScrollTargets.swift +3 -3
- package/Sources/SwiftUI/API/ScrollViewReader.swift +144 -0
- package/Sources/SwiftUI/API/SectionSupplements.swift +86 -0
- package/Sources/SwiftUI/API/Shape.swift +214 -0
- package/Sources/SwiftUI/API/ShapeStyle.swift +187 -8
- 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 +18 -1
- package/Sources/SwiftUI/API/StatusGaps.swift +121 -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 +148 -4
- package/Sources/SwiftUI/API/Tasks.swift +2 -2
- 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/Toolbar.swift +52 -16
- 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 +46 -2
- package/Sources/SwiftUI/API/ViewModifier.swift +4 -1
- package/Sources/SwiftUI/API/VisualEffect.swift +74 -1
- package/Sources/SwiftUI/API/Windows.swift +25 -0
- package/Sources/SwiftUI/Charts/Axis.swift +7 -1
- package/Sources/SwiftUI/Charts/AxisFormatsAndRanges.swift +68 -0
- package/Sources/SwiftUI/Charts/Chart.swift +17 -3
- package/Sources/SwiftUI/Charts/ChartProxy.swift +57 -0
- package/Sources/SwiftUI/Localization/Localization.swift +524 -0
- package/Sources/SwiftUI/Localization/PluralRules.swift +127 -0
- package/Sources/SwiftUI/Runtime/Executor.swift +2 -0
- package/Sources/SwiftUI/Runtime/Exports.swift +37 -1
- package/Sources/SwiftUI/Runtime/ImageSource.swift +310 -0
- package/Sources/SwiftUI/Runtime/JSON.swift +76 -4
- package/Sources/SwiftUI/Runtime/LazyRows.swift +99 -0
- package/Sources/SwiftUI/Runtime/Measurements.swift +140 -0
- package/Sources/SwiftUI/Runtime/Ops.swift +58 -12
- package/Sources/SwiftUI/Runtime/Reconciler.swift +10 -1
- package/Sources/SwiftUI/Runtime/Replay.swift +382 -0
- package/Sources/SwiftUI/Runtime/Runtime.swift +977 -198
- 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 +1 -1
- package/index.mjs +2 -2
- package/manifest.d.mts +2 -0
- package/manifest.mjs +41 -0
- package/package.json +5 -3
- package/sync-sources.mjs +21 -7
- package/Sources/FoundationLite/Common.swift +0 -3
- package/Sources/FoundationLite/FoundationLite.swift +0 -171
- package/Sources/FoundationLite/Interaction.swift +0 -146
- package/Sources/FoundationLite/Timer.swift +0 -48
- package/Sources/_FoundationCommon/_FoundationCommon.swift +0 -10
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
// StoreKit's SwiftUI views and modifiers (iOS 17): `StoreView`,
|
|
2
|
+
// `SubscriptionStoreView` and `ProductView`, their styles, and the sheets
|
|
3
|
+
// and purchase callbacks. The browser has no App Store to load products
|
|
4
|
+
// from, so each view shows what StoreKit shows when its products cannot be
|
|
5
|
+
// loaded: the subscription store keeps its marketing content and says
|
|
6
|
+
// subscriptions are unavailable, and a product view is in its
|
|
7
|
+
// `.unavailable` state (which a custom `ProductViewStyle` draws). The sheets
|
|
8
|
+
// (manage subscriptions, redeem an offer code, request a refund) cannot be
|
|
9
|
+
// shown: presenting one sets its binding back to false, as dismissing it
|
|
10
|
+
// would, and the purchase callbacks never run.
|
|
11
|
+
|
|
12
|
+
import SwiftUI
|
|
13
|
+
|
|
14
|
+
/// The note the store views show in place of products.
|
|
15
|
+
struct _StoreUnavailableNote: View {
|
|
16
|
+
let text: String
|
|
17
|
+
var body: some View {
|
|
18
|
+
Text(text)
|
|
19
|
+
.font(.footnote)
|
|
20
|
+
.foregroundStyle(.secondary)
|
|
21
|
+
.multilineTextAlignment(.center)
|
|
22
|
+
.padding()
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// MARK: - StoreView
|
|
27
|
+
|
|
28
|
+
/// A store of in-app products. In the browser there are none to show.
|
|
29
|
+
public struct StoreView<Icon: View, PlaceholderIcon: View>: View {
|
|
30
|
+
let productIDs: [Product.ID]
|
|
31
|
+
|
|
32
|
+
public init(ids: some Collection<Product.ID>, prefersPromotionalIcon: Bool = false, @ViewBuilder icon: @escaping (Product) -> Icon, @ViewBuilder placeholderIcon: () -> PlaceholderIcon) {
|
|
33
|
+
productIDs = Array(ids)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public var body: some View {
|
|
37
|
+
_StoreUnavailableNote(text: "In-app purchases are not available in the browser.")
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
extension StoreView where PlaceholderIcon == EmptyView {
|
|
42
|
+
public init(products: some Collection<Product>, prefersPromotionalIcon: Bool = false, @ViewBuilder icon: @escaping (Product) -> Icon) {
|
|
43
|
+
productIDs = products.map(\.id)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
extension StoreView where Icon == EmptyView, PlaceholderIcon == EmptyView {
|
|
48
|
+
public init(ids: some Collection<Product.ID>, prefersPromotionalIcon: Bool = false) {
|
|
49
|
+
productIDs = Array(ids)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public init(products: some Collection<Product>, prefersPromotionalIcon: Bool = false) {
|
|
53
|
+
productIDs = products.map(\.id)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// MARK: - SubscriptionStoreView
|
|
58
|
+
|
|
59
|
+
/// A store of auto-renewable subscriptions: its marketing content, and a
|
|
60
|
+
/// note that subscriptions are not available in the browser.
|
|
61
|
+
public struct SubscriptionStoreView<Content: View>: View {
|
|
62
|
+
let content: Content
|
|
63
|
+
|
|
64
|
+
public init(productIDs: some Collection<Product.ID>, @ViewBuilder marketingContent: () -> Content) {
|
|
65
|
+
content = marketingContent()
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public init(groupID: String, @ViewBuilder marketingContent: () -> Content) {
|
|
69
|
+
content = marketingContent()
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/// The group's subscriptions that relate to the current one as
|
|
73
|
+
/// `visibleRelationships` says; there is no current one in the browser.
|
|
74
|
+
public init(groupID: String, visibleRelationships: Product.SubscriptionRelationship, @ViewBuilder marketingContent: () -> Content) {
|
|
75
|
+
content = marketingContent()
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
public init(subscriptions: some Collection<Product>, @ViewBuilder marketingContent: () -> Content) {
|
|
79
|
+
content = marketingContent()
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public var body: some View {
|
|
83
|
+
VStack(spacing: 16) {
|
|
84
|
+
content
|
|
85
|
+
_StoreUnavailableNote(text: "Subscriptions are not available in the browser.")
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/// The marketing content StoreKit makes from the App Store's metadata: none
|
|
91
|
+
/// in the browser.
|
|
92
|
+
public struct AutomaticSubscriptionStoreMarketingContent: View {
|
|
93
|
+
public var body: some View { EmptyView() }
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
extension SubscriptionStoreView where Content == AutomaticSubscriptionStoreMarketingContent {
|
|
97
|
+
public init(productIDs: some Collection<Product.ID>) {
|
|
98
|
+
content = AutomaticSubscriptionStoreMarketingContent()
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public init(groupID: String) {
|
|
102
|
+
content = AutomaticSubscriptionStoreMarketingContent()
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
public init(groupID: String, visibleRelationships: Product.SubscriptionRelationship) {
|
|
106
|
+
content = AutomaticSubscriptionStoreMarketingContent()
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
public init(subscriptions: some Collection<Product>) {
|
|
110
|
+
content = AutomaticSubscriptionStoreMarketingContent()
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/// Content of a subscription store (iOS 18): the groups of subscription
|
|
115
|
+
/// options StoreKit would list. There are none to list in the browser.
|
|
116
|
+
public protocol StoreContent {}
|
|
117
|
+
|
|
118
|
+
@resultBuilder
|
|
119
|
+
public enum StoreContentBuilder {
|
|
120
|
+
public static func buildBlock() -> _EmptyStoreContent { _EmptyStoreContent() }
|
|
121
|
+
public static func buildBlock<C: StoreContent>(_ content: C) -> C { content }
|
|
122
|
+
public static func buildBlock<each C: StoreContent>(_ content: repeat each C) -> _TupleStoreContent<repeat each C> { _TupleStoreContent(repeat each content) }
|
|
123
|
+
public static func buildExpression<C: StoreContent>(_ content: C) -> C { content }
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
public struct _EmptyStoreContent: StoreContent {}
|
|
127
|
+
|
|
128
|
+
public struct _TupleStoreContent<each C: StoreContent>: StoreContent {
|
|
129
|
+
let content: (repeat each C)
|
|
130
|
+
init(_ content: repeat each C) { self.content = (repeat each content) }
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/// A subscription store's content, as a view.
|
|
134
|
+
public struct SubscriptionStoreContentView<C: StoreContent>: View {
|
|
135
|
+
let content: C
|
|
136
|
+
public var body: some View { EmptyView() }
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
extension SubscriptionStoreView {
|
|
140
|
+
public init<C: StoreContent>(productIDs: some Collection<Product.ID>, @StoreContentBuilder content: () -> C) where Content == SubscriptionStoreContentView<C> {
|
|
141
|
+
self.content = SubscriptionStoreContentView(content: content())
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
public init<C: StoreContent>(groupID: String, @StoreContentBuilder content: () -> C) where Content == SubscriptionStoreContentView<C> {
|
|
145
|
+
self.content = SubscriptionStoreContentView(content: content())
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/// Where a background goes in a subscription store.
|
|
150
|
+
extension ContainerBackgroundPlacement {
|
|
151
|
+
public static let subscriptionStore = ContainerBackgroundPlacement(_name: "subscriptionStore")
|
|
152
|
+
public static let subscriptionStoreFullHeight = ContainerBackgroundPlacement(_name: "subscriptionStoreFullHeight")
|
|
153
|
+
public static let subscriptionStoreHeader = ContainerBackgroundPlacement(_name: "subscriptionStoreHeader")
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/// How a subscription store labels its subscribe button.
|
|
157
|
+
public struct SubscriptionStoreButtonLabel: Hashable, Sendable {
|
|
158
|
+
let name: String
|
|
159
|
+
public static let automatic = SubscriptionStoreButtonLabel(name: "automatic")
|
|
160
|
+
public static let multiline = SubscriptionStoreButtonLabel(name: "multiline")
|
|
161
|
+
public static let singleLine = SubscriptionStoreButtonLabel(name: "singleLine")
|
|
162
|
+
public static let action = SubscriptionStoreButtonLabel(name: "action")
|
|
163
|
+
public static let displayName = SubscriptionStoreButtonLabel(name: "displayName")
|
|
164
|
+
public static let price = SubscriptionStoreButtonLabel(name: "price")
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// MARK: - ProductView
|
|
168
|
+
|
|
169
|
+
/// What a product view style draws: in the browser, always a product that
|
|
170
|
+
/// could not be loaded.
|
|
171
|
+
public struct ProductViewStyleConfiguration {
|
|
172
|
+
public enum State {
|
|
173
|
+
case loading
|
|
174
|
+
case unavailable
|
|
175
|
+
case success(Product)
|
|
176
|
+
case failure(any Error)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
public struct Icon: View {
|
|
180
|
+
public var body: some View { EmptyView() }
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
public let productID: Product.ID
|
|
184
|
+
public let state: State
|
|
185
|
+
public let icon = Icon()
|
|
186
|
+
public var product: Product? {
|
|
187
|
+
if case .success(let product) = state { return product }
|
|
188
|
+
return nil
|
|
189
|
+
}
|
|
190
|
+
public var hasCurrentEntitlement: Bool { false }
|
|
191
|
+
|
|
192
|
+
/// Nothing to buy: does nothing.
|
|
193
|
+
public func purchase() {}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/// How a `ProductView` draws its product.
|
|
197
|
+
public protocol ProductViewStyle {
|
|
198
|
+
associatedtype Body: View
|
|
199
|
+
typealias Configuration = ProductViewStyleConfiguration
|
|
200
|
+
@ViewBuilder @MainActor func makeBody(configuration: Configuration) -> Body
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/// The standard look: in the browser, the unavailable note.
|
|
204
|
+
public struct AutomaticProductViewStyle: ProductViewStyle {
|
|
205
|
+
public init() {}
|
|
206
|
+
public func makeBody(configuration: Configuration) -> some View {
|
|
207
|
+
_StoreUnavailableNote(text: "This item is not available in the browser.")
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
extension ProductViewStyle where Self == AutomaticProductViewStyle {
|
|
212
|
+
public static var automatic: AutomaticProductViewStyle { AutomaticProductViewStyle() }
|
|
213
|
+
public static var compact: AutomaticProductViewStyle { AutomaticProductViewStyle() }
|
|
214
|
+
public static var regular: AutomaticProductViewStyle { AutomaticProductViewStyle() }
|
|
215
|
+
public static var large: AutomaticProductViewStyle { AutomaticProductViewStyle() }
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
struct _AnyProductViewStyle {
|
|
219
|
+
let make: @MainActor (ProductViewStyleConfiguration) -> any View
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
private struct _ProductViewStyleKey: EnvironmentKey {
|
|
223
|
+
static var defaultValue: _AnyProductViewStyle? { nil }
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
extension EnvironmentValues {
|
|
227
|
+
var _productViewStyle: _AnyProductViewStyle? {
|
|
228
|
+
get { self[_ProductViewStyleKey.self] }
|
|
229
|
+
set { self[_ProductViewStyleKey.self] = newValue }
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/// One in-app product. In the browser it cannot be loaded: the view's style
|
|
234
|
+
/// draws the `.unavailable` state.
|
|
235
|
+
public struct ProductView<Icon: View, PlaceholderIcon: View>: View {
|
|
236
|
+
let productID: Product.ID
|
|
237
|
+
/// `ProductView(configuration)` inside a style draws the standard look.
|
|
238
|
+
let standard: Bool
|
|
239
|
+
@Environment(\._productViewStyle) private var style
|
|
240
|
+
|
|
241
|
+
public init(id: Product.ID, prefersPromotionalIcon: Bool = false, @ViewBuilder icon: () -> Icon, @ViewBuilder placeholderIcon: () -> PlaceholderIcon) {
|
|
242
|
+
productID = id
|
|
243
|
+
standard = false
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
public var body: some View {
|
|
247
|
+
let configuration = ProductViewStyleConfiguration(productID: productID, state: .unavailable)
|
|
248
|
+
if !standard, let style {
|
|
249
|
+
AnyView(style.make(configuration))
|
|
250
|
+
} else {
|
|
251
|
+
AutomaticProductViewStyle().makeBody(configuration: configuration)
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
extension ProductView where PlaceholderIcon == EmptyView {
|
|
257
|
+
public init(_ product: Product, prefersPromotionalIcon: Bool = false, @ViewBuilder icon: () -> Icon) {
|
|
258
|
+
productID = product.id
|
|
259
|
+
standard = false
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
public init(id: Product.ID, prefersPromotionalIcon: Bool = false, @ViewBuilder icon: () -> Icon) {
|
|
263
|
+
productID = id
|
|
264
|
+
standard = false
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
extension ProductView where Icon == EmptyView, PlaceholderIcon == EmptyView {
|
|
269
|
+
public init(id: Product.ID, prefersPromotionalIcon: Bool = false) {
|
|
270
|
+
productID = id
|
|
271
|
+
standard = false
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
public init(_ product: Product, prefersPromotionalIcon: Bool = false) {
|
|
275
|
+
productID = product.id
|
|
276
|
+
standard = false
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
extension ProductView where Icon == ProductViewStyleConfiguration.Icon, PlaceholderIcon == EmptyView {
|
|
281
|
+
/// The standard look of a style's configuration.
|
|
282
|
+
public init(_ configuration: ProductViewStyleConfiguration) {
|
|
283
|
+
productID = configuration.productID
|
|
284
|
+
standard = true
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// MARK: - Modifiers
|
|
289
|
+
|
|
290
|
+
nonisolated extension View {
|
|
291
|
+
@MainActor
|
|
292
|
+
public func productViewStyle<S: ProductViewStyle>(_ style: S) -> some View {
|
|
293
|
+
environment(\._productViewStyle, _AnyProductViewStyle(make: { style.makeBody(configuration: $0) }))
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/// Accepted; the browser's subscription store has no button to label.
|
|
297
|
+
public func subscriptionStoreButtonLabel(_ label: SubscriptionStoreButtonLabel) -> some View { self }
|
|
298
|
+
|
|
299
|
+
/// Accepted; the browser's subscription store has no options to put on a background.
|
|
300
|
+
public func subscriptionStorePickerItemBackground<S: ShapeStyle>(_ style: S) -> some View { self }
|
|
301
|
+
|
|
302
|
+
/// Accepted; the browser's subscription store has no options to put on a background.
|
|
303
|
+
public func subscriptionStorePickerItemBackground<S: ShapeStyle, B: Shape>(_ style: S, in shape: B) -> some View { self }
|
|
304
|
+
|
|
305
|
+
/// Never called: nothing can be bought in the browser.
|
|
306
|
+
public func onInAppPurchaseStart(perform action: ((Product) async -> Void)?) -> some View { self }
|
|
307
|
+
|
|
308
|
+
/// Never called: nothing can be bought in the browser.
|
|
309
|
+
public func onInAppPurchaseCompletion(perform action: ((Product, Result<Product.PurchaseResult, any Error>) async -> Void)?) -> some View { self }
|
|
310
|
+
|
|
311
|
+
/// The manage-subscriptions sheet cannot be shown: presenting it sets
|
|
312
|
+
/// `isPresented` back to false.
|
|
313
|
+
@MainActor
|
|
314
|
+
public func manageSubscriptionsSheet(isPresented: Binding<Bool>) -> some View {
|
|
315
|
+
_dismissingAtOnce(isPresented)
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
@MainActor
|
|
319
|
+
public func manageSubscriptionsSheet(isPresented: Binding<Bool>, subscriptionGroupID: String) -> some View {
|
|
320
|
+
_dismissingAtOnce(isPresented)
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/// The offer-code sheet cannot be shown: presenting it sets `isPresented`
|
|
324
|
+
/// back to false and reports `StoreKitError.unsupported`.
|
|
325
|
+
@MainActor
|
|
326
|
+
public func offerCodeRedemption(isPresented: Binding<Bool>, onCompletion: @escaping (Result<Void, any Error>) -> Void = { _ in }) -> some View {
|
|
327
|
+
onChange(of: isPresented.wrappedValue) { _, presented in
|
|
328
|
+
guard presented else { return }
|
|
329
|
+
isPresented.wrappedValue = false
|
|
330
|
+
onCompletion(.failure(StoreKitError.unsupported))
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/// The refund sheet cannot be shown: presenting it sets `isPresented`
|
|
335
|
+
/// back to false and reports `RefundRequestError.failed`.
|
|
336
|
+
@MainActor
|
|
337
|
+
public func refundRequestSheet(for transactionID: UInt64, isPresented: Binding<Bool>, onDismiss: ((Result<Transaction.RefundRequestStatus, Transaction.RefundRequestError>) -> Void)? = nil) -> some View {
|
|
338
|
+
onChange(of: isPresented.wrappedValue) { _, presented in
|
|
339
|
+
guard presented else { return }
|
|
340
|
+
isPresented.wrappedValue = false
|
|
341
|
+
onDismiss?(.failure(.failed))
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/// Runs `action` once with the (empty) subscription statuses of the group.
|
|
346
|
+
@MainActor
|
|
347
|
+
public func subscriptionStatusTask(for groupID: String, priority: TaskPriority = .medium, action: @escaping (EntitlementTaskState<[Product.SubscriptionInfo.Status]>) async -> Void) -> some View {
|
|
348
|
+
task { await action(.success([])) }
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/// Runs `action` once with no entitlement.
|
|
352
|
+
@MainActor
|
|
353
|
+
public func currentEntitlementTask(for productID: String, priority: TaskPriority = .medium, action: @escaping (EntitlementTaskState<VerificationResult<Transaction>?>) async -> Void) -> some View {
|
|
354
|
+
task { await action(.success(nil)) }
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
@MainActor
|
|
358
|
+
func _dismissingAtOnce(_ isPresented: Binding<Bool>) -> some View {
|
|
359
|
+
onChange(of: isPresented.wrappedValue) { _, presented in
|
|
360
|
+
if presented { isPresented.wrappedValue = false }
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/// What an entitlement task found.
|
|
366
|
+
public enum EntitlementTaskState<Value> {
|
|
367
|
+
case loading
|
|
368
|
+
case failure(any Error)
|
|
369
|
+
case success(Value)
|
|
370
|
+
|
|
371
|
+
public var transaction: Value? {
|
|
372
|
+
if case .success(let value) = self { return value }
|
|
373
|
+
return nil
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/// The value the task found, if it succeeded.
|
|
377
|
+
public var value: Value? {
|
|
378
|
+
if case .success(let value) = self { return value }
|
|
379
|
+
return nil
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/// The state with a found value transformed; a transform that throws
|
|
383
|
+
/// makes it a failure.
|
|
384
|
+
public func map<T>(_ transform: (Value) async throws -> T) async -> EntitlementTaskState<T> {
|
|
385
|
+
switch self {
|
|
386
|
+
case .loading: return .loading
|
|
387
|
+
case .failure(let error): return .failure(error)
|
|
388
|
+
case .success(let value):
|
|
389
|
+
do { return .success(try await transform(value)) } catch { return .failure(error) }
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// MARK: - Subscription relationships and store buttons
|
|
395
|
+
|
|
396
|
+
extension Product {
|
|
397
|
+
/// Which of a group's subscriptions a store shows, relative to the
|
|
398
|
+
/// customer's current one (iOS 17).
|
|
399
|
+
public struct SubscriptionRelationship: OptionSet, Hashable, Sendable {
|
|
400
|
+
public let rawValue: Int
|
|
401
|
+
public init(rawValue: Int) { self.rawValue = rawValue }
|
|
402
|
+
public static let upgrade = SubscriptionRelationship(rawValue: 1)
|
|
403
|
+
public static let downgrade = SubscriptionRelationship(rawValue: 2)
|
|
404
|
+
public static let crossgrade = SubscriptionRelationship(rawValue: 4)
|
|
405
|
+
public static let current = SubscriptionRelationship(rawValue: 8)
|
|
406
|
+
public static let all: SubscriptionRelationship = [.upgrade, .downgrade, .crossgrade, .current]
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/// The buttons a store view can show besides its products.
|
|
411
|
+
public struct StoreButtonKind: Hashable, Sendable {
|
|
412
|
+
let name: String
|
|
413
|
+
public static let cancellation = StoreButtonKind(name: "cancellation")
|
|
414
|
+
public static let restorePurchases = StoreButtonKind(name: "restorePurchases")
|
|
415
|
+
public static let redeemCode = StoreButtonKind(name: "redeemCode")
|
|
416
|
+
public static let signIn = StoreButtonKind(name: "signIn")
|
|
417
|
+
public static let policies = StoreButtonKind(name: "policies")
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
nonisolated extension View {
|
|
421
|
+
/// Accepted; the browser's store views show none of these buttons.
|
|
422
|
+
public func storeButton(_ visibility: Visibility, for buttonKinds: StoreButtonKind...) -> some View { self }
|
|
423
|
+
|
|
424
|
+
/// Accepted; the browser's subscription store lists no subscriptions to give an icon.
|
|
425
|
+
public func subscriptionStoreControlIcon<V: View>(
|
|
426
|
+
@ViewBuilder icon: @escaping (Product, Product.SubscriptionInfo) -> V
|
|
427
|
+
) -> some View { self }
|
|
428
|
+
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
// StoreKit 2's transactions, as code that reads them is written: the types,
|
|
2
|
+
// their properties and the sequences of them. A web app sells nothing through
|
|
3
|
+
// the App Store, so there are never any: `Transaction.updates`,
|
|
4
|
+
// `currentEntitlements`, `all` and `unfinished` end at once, and
|
|
5
|
+
// `latest(for:)` answers nil. Analytics and paywall packages (TelemetryDeck,
|
|
6
|
+
// RevenueCat) compile, and see no purchases.
|
|
7
|
+
|
|
8
|
+
@_exported import Foundation
|
|
9
|
+
|
|
10
|
+
/// A StoreKit result whose signature has been checked.
|
|
11
|
+
public enum VerificationResult<SignedType: Sendable>: Sendable {
|
|
12
|
+
case unverified(SignedType, VerificationError)
|
|
13
|
+
case verified(SignedType)
|
|
14
|
+
|
|
15
|
+
public enum VerificationError: Error, Hashable, Sendable {
|
|
16
|
+
case revokedCertificate, invalidCertificateChain, invalidDeviceVerification, invalidEncoding, invalidSignature, missingRequiredProperties
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public var unsafePayloadValue: SignedType {
|
|
20
|
+
switch self {
|
|
21
|
+
case .unverified(let value, _), .verified(let value): value
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public var payloadValue: SignedType {
|
|
26
|
+
get throws {
|
|
27
|
+
switch self {
|
|
28
|
+
case .verified(let value): value
|
|
29
|
+
case .unverified(_, let error): throw error
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public var jwsRepresentation: String { "" }
|
|
35
|
+
public var headerData: Data { Data() }
|
|
36
|
+
public var payloadData: Data { Data() }
|
|
37
|
+
public var signatureData: Data { Data() }
|
|
38
|
+
public var signedData: Data { Data() }
|
|
39
|
+
public var signedDate: Date { Date(timeIntervalSince1970: 0) }
|
|
40
|
+
public var deviceVerification: Data { Data() }
|
|
41
|
+
public var deviceVerificationNonce: UUID { UUID(uuid: (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) }
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/// A purchase. There are none in the browser; the type is here for the code that reads them.
|
|
45
|
+
public struct Transaction: Identifiable, Hashable, Sendable {
|
|
46
|
+
public struct OwnershipType: Hashable, Sendable, RawRepresentable {
|
|
47
|
+
public let rawValue: String
|
|
48
|
+
public init(rawValue: String) { self.rawValue = rawValue }
|
|
49
|
+
public static let purchased = OwnershipType(rawValue: "PURCHASED")
|
|
50
|
+
public static let familyShared = OwnershipType(rawValue: "FAMILY_SHARED")
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public struct RevocationReason: Hashable, Sendable, RawRepresentable {
|
|
54
|
+
public let rawValue: Int
|
|
55
|
+
public init(rawValue: Int) { self.rawValue = rawValue }
|
|
56
|
+
public static let developerIssue = RevocationReason(rawValue: 1)
|
|
57
|
+
public static let other = RevocationReason(rawValue: 0)
|
|
58
|
+
public var localizedDescription: String { "\(rawValue)" }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/// Why the transaction happened (iOS 17): a purchase or a renewal.
|
|
62
|
+
public struct Reason: Hashable, Sendable, RawRepresentable {
|
|
63
|
+
public let rawValue: String
|
|
64
|
+
public init(rawValue: String) { self.rawValue = rawValue }
|
|
65
|
+
public static let purchase = Reason(rawValue: "PURCHASE")
|
|
66
|
+
public static let renewal = Reason(rawValue: "RENEWAL")
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/// The kind of offer a transaction used.
|
|
70
|
+
public struct OfferType: Hashable, Sendable, RawRepresentable {
|
|
71
|
+
public let rawValue: Int
|
|
72
|
+
public init(rawValue: Int) { self.rawValue = rawValue }
|
|
73
|
+
public static let introductory = OfferType(rawValue: 1)
|
|
74
|
+
public static let promotional = OfferType(rawValue: 2)
|
|
75
|
+
public static let code = OfferType(rawValue: 3)
|
|
76
|
+
public static let winBack = OfferType(rawValue: 4)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public struct Offer: Hashable, Sendable {
|
|
80
|
+
public struct PaymentMode: Hashable, Sendable, RawRepresentable {
|
|
81
|
+
public let rawValue: String
|
|
82
|
+
public init(rawValue: String) { self.rawValue = rawValue }
|
|
83
|
+
public static let freeTrial = PaymentMode(rawValue: "FREE_TRIAL")
|
|
84
|
+
public static let payAsYouGo = PaymentMode(rawValue: "PAY_AS_YOU_GO")
|
|
85
|
+
public static let payUpFront = PaymentMode(rawValue: "PAY_UP_FRONT")
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
public let id: String?
|
|
89
|
+
public let type: OfferType
|
|
90
|
+
public let paymentMode: PaymentMode?
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/// How a refund request ended.
|
|
94
|
+
public enum RefundRequestStatus: Hashable, Sendable {
|
|
95
|
+
case success, userCancelled
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
public enum RefundRequestError: Error, Hashable, Sendable {
|
|
99
|
+
case duplicateRequest, failed, ineligible
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public let id: UInt64
|
|
103
|
+
public let originalID: UInt64
|
|
104
|
+
public let webOrderLineItemID: String?
|
|
105
|
+
public let productID: String
|
|
106
|
+
public let productType: Product.ProductType
|
|
107
|
+
public let appBundleID: String
|
|
108
|
+
public let purchaseDate: Date
|
|
109
|
+
public let originalPurchaseDate: Date
|
|
110
|
+
public let expirationDate: Date?
|
|
111
|
+
public let revocationDate: Date?
|
|
112
|
+
public let revocationReason: RevocationReason?
|
|
113
|
+
public let isUpgraded: Bool
|
|
114
|
+
public let offer: Offer?
|
|
115
|
+
public let price: Decimal?
|
|
116
|
+
public let currency: Locale.Currency?
|
|
117
|
+
public let storefront: Storefront
|
|
118
|
+
public let environment: AppStore.Environment
|
|
119
|
+
public let ownershipType: OwnershipType
|
|
120
|
+
public let subscriptionGroupID: String?
|
|
121
|
+
public let purchasedQuantity: Int
|
|
122
|
+
public let appAccountToken: UUID?
|
|
123
|
+
public let signedDate: Date
|
|
124
|
+
public let reason: Reason
|
|
125
|
+
/// The billing plan the subscription was bought with (iOS 26.4).
|
|
126
|
+
public let billingPlanType: Product.SubscriptionInfo.BillingPlanType?
|
|
127
|
+
public let deviceVerification: Data
|
|
128
|
+
public let deviceVerificationNonce: UUID
|
|
129
|
+
|
|
130
|
+
public var offerType: OfferType? { offer?.type }
|
|
131
|
+
public var offerID: String? { offer?.id }
|
|
132
|
+
public var offerPaymentModeStringRepresentation: String? { offer?.paymentMode?.rawValue }
|
|
133
|
+
public var currencyCode: String? { currency?.identifier }
|
|
134
|
+
public var storefrontCountryCode: String { storefront.countryCode }
|
|
135
|
+
public var environmentStringRepresentation: String { environment.rawValue }
|
|
136
|
+
public var jsonRepresentation: Data { Data() }
|
|
137
|
+
|
|
138
|
+
public func finish() async {}
|
|
139
|
+
|
|
140
|
+
/// Transactions as they happen: none in the browser.
|
|
141
|
+
public static var updates: Transactions { Transactions() }
|
|
142
|
+
public static var all: Transactions { Transactions() }
|
|
143
|
+
public static var currentEntitlements: Transactions { Transactions() }
|
|
144
|
+
public static var unfinished: Transactions { Transactions() }
|
|
145
|
+
public static func latest(for productID: String) async -> VerificationResult<Transaction>? { nil }
|
|
146
|
+
public static func currentEntitlement(for productID: String) async -> VerificationResult<Transaction>? { nil }
|
|
147
|
+
public static func currentEntitlements(for productID: String) -> Transactions { Transactions() }
|
|
148
|
+
|
|
149
|
+
/// Never reached in the browser (there are no transactions to refund);
|
|
150
|
+
/// it fails with `RefundRequestError.failed`.
|
|
151
|
+
@MainActor public static func beginRefundRequest(for transactionID: UInt64, in scene: _StoreKitScene) async throws -> RefundRequestStatus {
|
|
152
|
+
throw RefundRequestError.failed
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
@MainActor public func beginRefundRequest(in scene: _StoreKitScene) async throws -> RefundRequestStatus {
|
|
156
|
+
throw RefundRequestError.failed
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/// A sequence of transactions; it ends at once.
|
|
160
|
+
public struct Transactions: AsyncSequence, Sendable {
|
|
161
|
+
public typealias Element = VerificationResult<Transaction>
|
|
162
|
+
public struct AsyncIterator: AsyncIteratorProtocol {
|
|
163
|
+
public mutating func next() async -> VerificationResult<Transaction>? { nil }
|
|
164
|
+
}
|
|
165
|
+
public func makeAsyncIterator() -> AsyncIterator { AsyncIterator() }
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
public static func == (lhs: Transaction, rhs: Transaction) -> Bool { lhs.id == rhs.id }
|
|
169
|
+
public func hash(into hasher: inout Hasher) { hasher.combine(id) }
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/// The app's own purchase from the App Store. A web app was not bought there:
|
|
173
|
+
/// `AppTransaction.shared` throws `StoreKitError.unsupported`.
|
|
174
|
+
public struct AppTransaction: Hashable, Sendable {
|
|
175
|
+
public let appID: UInt64?
|
|
176
|
+
public let appVersionID: UInt64?
|
|
177
|
+
public let appVersion: String
|
|
178
|
+
public let bundleID: String
|
|
179
|
+
public let environment: AppStore.Environment
|
|
180
|
+
public let originalAppVersion: String
|
|
181
|
+
public let originalPurchaseDate: Date
|
|
182
|
+
public let preorderDate: Date?
|
|
183
|
+
public let deviceVerification: Data
|
|
184
|
+
public let deviceVerificationNonce: UUID
|
|
185
|
+
public let signedDate: Date
|
|
186
|
+
public let appTransactionID: String
|
|
187
|
+
public let originalPlatform: AppStore.Platform
|
|
188
|
+
public var jsonRepresentation: Data { Data() }
|
|
189
|
+
|
|
190
|
+
public static var shared: VerificationResult<AppTransaction> {
|
|
191
|
+
get async throws { throw StoreKitError.unsupported }
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
public static func refresh() async throws -> VerificationResult<AppTransaction> {
|
|
195
|
+
throw StoreKitError.unsupported
|
|
196
|
+
}
|
|
197
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// The macros an app writes, declared as in Apple's SwiftData. Their
|
|
2
|
+
// expansions live in Sources/SwiftDataMacros.
|
|
3
|
+
|
|
4
|
+
// Re-exported, as Apple's SwiftData does: `@Model` expands to
|
|
5
|
+
// `Observation.ObservationRegistrar`, so a model file that imports only
|
|
6
|
+
// SwiftData (Hacking with SwiftUI's HotProspects) must see the module; and
|
|
7
|
+
// such a file uses `Date` and `UUID` without importing Foundation (Backyard
|
|
8
|
+
// Birds' DataGeneration).
|
|
9
|
+
@_exported import Observation
|
|
10
|
+
@_exported import Foundation
|
|
11
|
+
|
|
12
|
+
/// Makes a class a persistent model: its stored properties are saved by a
|
|
13
|
+
/// `ModelContext` and observed like an `@Observable` class's.
|
|
14
|
+
@attached(member, names: named(_$backingData), named(persistentBackingData), named(schemaMetadata), named(init), named(_$observationRegistrar))
|
|
15
|
+
@attached(memberAttribute)
|
|
16
|
+
@attached(extension, conformances: PersistentModel)
|
|
17
|
+
public macro Model() = #externalMacro(module: "SwiftDataMacros", type: "ModelMacro")
|
|
18
|
+
|
|
19
|
+
/// Added by `@Model` to each persisted property.
|
|
20
|
+
@attached(accessor, names: named(init), named(get), named(set))
|
|
21
|
+
@attached(peer, names: prefixed(_))
|
|
22
|
+
public macro _PersistedProperty() = #externalMacro(module: "SwiftDataMacros", type: "PersistedPropertyMacro")
|
|
23
|
+
|
|
24
|
+
/// Options for a persisted attribute (`.unique`, `originalName:`).
|
|
25
|
+
@attached(peer)
|
|
26
|
+
public macro Attribute(_ options: Schema.Attribute.Option..., originalName: String? = nil, hashModifier: String? = nil) = #externalMacro(module: "SwiftDataMacros", type: "MarkerMacro")
|
|
27
|
+
|
|
28
|
+
/// Options for a relationship: its delete rule and inverse.
|
|
29
|
+
@attached(peer)
|
|
30
|
+
public macro Relationship(
|
|
31
|
+
_ options: Schema.Relationship.Option...,
|
|
32
|
+
deleteRule: Schema.Relationship.DeleteRule = .nullify,
|
|
33
|
+
minimumModelCount: Int? = 0,
|
|
34
|
+
maximumModelCount: Int? = 0,
|
|
35
|
+
originalName: String? = nil,
|
|
36
|
+
inverse: AnyKeyPath? = nil,
|
|
37
|
+
hashModifier: String? = nil
|
|
38
|
+
) = #externalMacro(module: "SwiftDataMacros", type: "MarkerMacro")
|
|
39
|
+
|
|
40
|
+
/// A property of a model that is not saved. It needs an initial value.
|
|
41
|
+
@attached(peer)
|
|
42
|
+
public macro Transient() = #externalMacro(module: "SwiftDataMacros", type: "MarkerMacro")
|
|
43
|
+
|
|
44
|
+
/// Uniqueness constraints over a model's properties (iOS 18). Accepted; use
|
|
45
|
+
/// `@Attribute(.unique)` for a constraint the store enforces.
|
|
46
|
+
@freestanding(declaration)
|
|
47
|
+
public macro Unique<T>(_ constraints: [PartialKeyPath<T>]...) = #externalMacro(module: "SwiftDataMacros", type: "ConstraintMacro")
|
|
48
|
+
|
|
49
|
+
/// Indexes over a model's properties (iOS 18). Accepted and unused: the store
|
|
50
|
+
/// keeps its records in memory.
|
|
51
|
+
@freestanding(declaration)
|
|
52
|
+
public macro Index<T>(_ indices: [PartialKeyPath<T>]...) = #externalMacro(module: "SwiftDataMacros", type: "ConstraintMacro")
|
|
53
|
+
|
|
54
|
+
/// Makes an actor a `ModelActor`: it gains `modelContainer`, an executor
|
|
55
|
+
/// with a context of its own, and `init(modelContainer:)`.
|
|
56
|
+
@attached(member, names: named(modelExecutor), named(modelContainer), named(init))
|
|
57
|
+
@attached(extension, conformances: ModelActor)
|
|
58
|
+
public macro ModelActor() = #externalMacro(module: "SwiftDataMacros", type: "ModelActorMacro")
|