Contents

tvOS 18 Release Notes

Update your apps to use new features, and test your apps against API changes.

Overview

The tvOS 18 SDK provides support to develop tvOS apps for Apple TV devices running tvOS 18. The SDK comes bundled with Xcode 16, available from the Mac App Store. For information on the compatibility requirements for Xcode 16, see Xcode 16 Release Notes.

App Intents

Resolved Issues

  • Fixed: Parameterless @Parameter and @Property wrappers might cause protocol conformance failures. (130219933)

App Store

New Features

  • On-demand resources limits were increased for iOS 18, iPadOS 18, tvOS 18 and visionOS 2. See On-demand resources size limits for more information. (122163236)

CFNetwork

Resolved Issues

  • Fixed: CFNetworkExecuteProxyAutoConfigurationScript and CFNetworkExecuteProxyAutoConfigurationURL have always returned a +1 retained CF type object, but the function declarations were not decorated with the CF_RETURNS_RETAINED attribute until iOS 18, macOS 15, tvOS 18, and visionOS 2.

    For C-based languages, the clang static analyzer might note if the object is leaked. No source code changes are required, but they are encouraged to fix the leak.

    For Swift, this changes the return type of these functions from Unmanaged<> to the actual CF type returned, which will require a source change to fix when compiling with newer SDKs. However, Swift programs compiled with older SDKs will continue to work on the new OSes, though the returned CF type object will continue to leak as it did prior to this change. (126154509)

Fitness

Resolved Issues

  • Fixed: If a user with multiple devices signs out of the Fitness app or connection times out, the Devices list might appear empty when attempting to reconnect a device and clicking the Play/Pause button to show other device options. (131489055)

Foundation

New Features

  • JSONEncoder.OutputFormatting.sortedKeys will now sort keys with a different ordering. Previously, keys were sorted using a numeric, case-insensitive, or localized ordering. Beginning in beta 4, keys are sorted lexicographically based on the keys’ UTF-8 contents. (126874437)

Resolved Issues

  • Fixed: Date.ComponentsFormatStyle was incorrectly producing strings like "1m" with the Date.ComponentsFormatStyle.Style.condensedAbbreviated style and strings like "1min" with the .narrow style instead of the other way around. The behavior was corrected to match the behavior of Duration.UnitsFormatStyle.UnitWidth. (125790342)

Maps

Resolved Issues

  • Fixed: In searches that use MKLocalSearch.Request, the result type option physicalFeature is ignored. (128961972)

Networking

Resolved Issues

  • Fixed: For apps linked on macOS 15 / iOS 18 or newer, the default User-Agent request header field value generated by URLSession now includes the unlocalized bundle name instead of the localized bundle name. (117380285)

Platform

New Features

  • The firmware image for iBoot will be made available in cleartext in the PCC image. To reduce the overhead imposed by firmware encryption and align policies where appropriate, firmware encryption has been disabled for iBoot on iOS, macOS, watchOS, tvOS, and visionOS. See Private Cloud Compute for more details. (125171074)

Screensaver

Known Issues

  • Portrait Screensaver displays text “Processing your photos for this screen saver. Check back later.” for multiple days, while iCloud syncs and photos get processed. (129876578)

Sign In

Resolved Issues

  • Fixed: Adding a new user to Apple TV using an iPhone or iPad (running iOS 17.x or earlier) might result in a failure when signed into separate Apple Accounts for iCloud, iTunes, and / or Game Center. (129012991)

StoreKit

New Features

  • The SubscriptionStoreView now supports custom control styles. To create a custom control style, declare a type that conforms to SubscriptionStoreControlStyle and implement makeBody(configuration:) method. (106819454)

  • Use types such as SubscriptionOptionGroup and SubscriptionPeriodGroupSet to declare a hierarchical structure for your SubscriptionStoreView. You can use the subscriptionStoreOptionGroupStyle(_:) to choose between presenting groups as a tab view or as navigation links. (110429924) (FB12264937)

  • The subscription status RenewalInfo object now supports new properties renewalPrice and currency to indicate the price at which the subscription will renew, and its currency. There is also a new offer property containing the information of the offer that will be applied to the next renewal, if there is any. This includes the offer ID, the offer type, and the payment mode. (114217892)

  • Finished consumables can now be included when using the Transaction APIs. Users can enable this feature by setting SKInAppPurchaseHistoryIncludesConsumables to true in app’s Info.plist. (115079880)

  • When configuring the control style for a SubscriptionStoreView, users can specify a placement for the controls using the subscriptionStoreControlStyle(_:placement:) view modifier. For tvOS, by default SubscriptionStoreView will place the controls trailing the marketing content. (115319543)

  • Users can now use APIs like monthly or yearly to get common Product.SubscriptionPeriod values when comparing subscription periods. (122684230)

Resolved Issues

  • Fixed: VoiceOver does not read a product’s title and description in ProductView and StoreView. (124254957) (FB13679318)

Deprecations

  • The Original API for In-App Purchase is now deprecated, including: SKStoreReviewController, SKProduct, SKReceiptRefreshRequest, SKStorefront, SKPayment, SKRequest, SKProductsRequest, and SKProductDiscount. Please upgrade to StoreKit 2 for current APIs and future enhancements. (116600524)

Swift Charts

New Features

  • Plot math functions using LinePlot and AreaPlot. (117186178)

  • Visualize large datasets more efficiently using vectorized plot APIs such as PointPlot and RectanglePlot. (117469419)

Resolved Issues

  • Fixed: Rotated axis labels stretch to incorrect sizes. (106013386)

  • Fixed: Blur and shadow effects on marks might disappear during animation. (125493885)

  • Fixed: Glitches when animating a connected scatter plot made of LineMark. (127196185)

  • Fixed: Stroke styles can now be animated. (127465359)

  • Fixed: For function plots, the Y domain cannot be inferred automatically. (128877906)

SwiftUI

New Features

  • When using a TabView, tapping on the current tab now pops any embedded navigation stack. (50924017)

  • For ObservableObject subclasses used with @EnvironmentObject, @ObservedObject, and @StateObject, SwiftUI will now only call objectWillChange once per property per object instance. If you use @Published and the default ObservableObjectPublisher, you do not need to change anything. If you override objectWillChange, ensure the lifetime of the publisher you return matches the lifetime of its enclosing ObservableObject. (116197689)

  • Types conforming to the View protocol, and other similar SwiftUI protocols, are now isolated to the @MainActor by default. SwiftUI’s runtime behavior with respect to actor isolation has not changed: SwiftUI views and similar types have always been evaluated on the main actor at runtime; this change improves compile-time diagnostics for potential data-race safety issues. To opt out of the new default main actor isolation and restore the previous default isolation, add the nonisolated keyword to methods and properties as needed, or move the protocol conformance to an extension to opt out the entire type. (120815051)

  • Text(_:format:) now automatically injects FormatStyle known to SwiftUI with the TimeZone and Calendar from the environment. (123662780)

  • @Entry macro can now be used to simplify declarations of custom EnvironmentValues, FocusedValues, Transaction, and ContainerValues properties. (125568810)

  • Added the ability to give a gesture a name, which gets surfaced to UIGestureRecognizers when establishing dependencies. (126527559)

  • NavigationSplitView on tvOS provides a floating sidebar presentation by default. The prior collapsed stack behavior can be obtained by using the .balanced NavigationSplitViewStyle. (128565845)

Resolved Issues

  • Fixed: ForEach is now able to reclaim persistent state of unused child views. @State values created by views inside ForEach elements might be destroyed earlier than previously observed. (90667238)

  • Fixed: A DismissAction captured in the content or detail column of a NavigationSplitView now pops the implicit stack.

    For apps linked on or after iOS 18 and aligned releases, the button in the example below will now clear any selection in the sidebar List. Previously, this would fail silently on iOS, and close the window on macOS.

     NavigationSplitView {
       List()
     } detail: {
       DetailView()
     }
     
     struct DetailView: View {
       @Environment(\.dismiss) private var dismiss
     
       var body: some View { 
         Button("Pop") { dismiss() }
       }
     }

    To retain the previous behavior, capture the DismissAction from the environment above the NavigationSplitView. (92522613)

  • Fixed: View._printChanges now outputs key path of mutated observable properties instead of “@dependencies”. (111392797)

  • Fixed: SwiftUI will now assert that types conforming to the App protocol are value types. (113634782)

  • Fixed: Automatically updating Text created via Text(_:style:) or Text(timerInterval:pauseTime:countsDown:showsHours:) was causing increased battery drain when used in long running Live Activities. They now no longer animate changes in digits that signal the seconds value, keeping the power impact to a minimum. (115906895)

  • Fixed: .navigationDestination(for:destination) modifiers inside of lazy containers are no longer evaluated. .navigationDestination(isPresented:destination:) and navigationDestination(item:destination) will log warning when used in lazy containers. Lazy containers in this context include: List, LazyVGrid, LazyHGrid, LazyHStack, LazyVStack Table, and TabView. If using navigationDestinations in lazy containers, users will see logged errors at runtime. Lift the modifiers higher up in the view hierarchy so they are outside of the lazy containers. Allowing navigation destination modifiers in lazy containers had two significant costs: (1) app navigation state could be undefined if a navigationDestination had been scrolled off screen (2) The navigation system had to explore all list contents to ensure navigation destinations remained up to date. Only allowing these modifiers outside of lazy containers improves app navigation reliability and performance. (117998693)

  • Fixed: The order of ShapeStyle compositing modifiers is now honored with respect to shadows. Previously in fill(style.blendMode(…).shadow(…)) the added blend mode would also apply to the shadow, that is no longer the case. The blend mode modifier must be added after the shadow modifier to affect it. As a consequence, the fill and any shadows added can now use different blend modes. Similar rules apply to ShapeStyle.opacity() except that outer opacity() modifiers multiply with inner modifiers, e.g. in fill(style.opacity(0.5).shadow(…).opacity(0.5)) the shadow is drawn with 50% opacity (of whatever style draws) and style itself draws with 25% opacity. (119738072)

  • Fixed: The meaning of the boolean value passed to the ContentTransition.numericText(countsDown:) function has been flipped for apps deployed prior to iOS 18 aligned releases. (120561508)

  • Fixed: Gestures might not pick up a modified content shape, such as when increasing the tappable area of a button. (120938385)

  • Fixed an issue when a sheet modifier is removed from a view hierarchy. This can happen if the sheet modifier is in one branch of an if statement and the statement’s condition changes. For apps linked on or after iOS 18 and aligned releases, when a sheet modifier is completely removed from the hierarchy, the binding associated with the sheet will not be reset. (123742063)

  • Fixed: ForEach child views are no longer re-evaluated unconditionally, only when a parameter of the ForEach view might have changed. (123902210)

  • Fixed: Elements along a NavigationPath or the data structure passed to the path parameter of NavigationStack(path:root:) are now compared more efficiently. Any side-effects from setting a path equal to itself are no longer reliable and likely will not occur. (125093883)

  • Fixed: The state of the root view of UIHostingConfiguration is now reset before the associated cell is displayed. (125100960)

  • Fixed: SceneBuilder, WidgetBundleBuilder, TableColumnBuilder, TableRowBuilder, CommandsBuilder, and ToolbarContentBuilder now diagnose unsupported if #available conditions at compile time instead of crashing at run time. (125379937)

  • Fixed: UIViewRepresentable, NSViewRepresentable and their view controller variants no longer create a layer with allowsGroupOpacity set to true. (125561916)

  • Fixed: In certain scenarios, Text(_:style:) produced suboptimal output, such as choosing an unnecessarily small calendar unit, showing zero values for large calendar units instead of omitting them, or showing seconds in Always On Display. (125885307)

  • Fixed: Text(timerInterval:pauseTime:countsDown:showsHours:) was redacting the seconds value even when the timer was paused, had not started yet, or had already reached its end. (125885429)

  • Fixed: Resolved an issue where scroll views would not receive touches if placed near a tappable control. When rebuilt with the newer SDK, make sure that small buttons and tap targets are correctly enlarged. You can use the contentShape modifier. (126232279)

  • Fixed: In the Swift 6 language mode, the @Entry macro now works with non-Sendable types if the type of the entry is declared explicitly. (129073803)

See Also

tvOS 18