Overview

Post

Replies

Boosts

Views

Activity

Launching iMessage App
Hello, I am new to app development. I am trying to make an iMessage app. I created it and then added a SwiftUI view. It builds just fine and the view is visible on the storyboard, but the app is not present in iMessage on Simulator or on an actual device. What's wrong? Thanks for any help. import UIKit import Messages import SwiftUI class MessagesViewController: MSMessagesAppViewController { var hostingController: UIHostingController<CalendarView>? override func viewDidLoad() { super.viewDidLoad() } override func willBecomeActive(with conversation: MSConversation) { super.willBecomeActive(with: conversation) let swiftUIView = CalendarView() let hostingController = UIHostingController(rootView: swiftUIView) addChild(hostingController) view.addSubview(hostingController.view) hostingController.view.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([hostingController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), hostingController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), hostingController.view.topAnchor.constraint(equalTo: view.topAnchor), hostingController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor)]) hostingController.didMove(toParent: self) self.hostingController = hostingController } override func didResignActive(with conversation: MSConversation) {} override func didReceive(_ message: MSMessage, conversation: MSConversation) {} override func didStartSending(_ message: MSMessage, conversation: MSConversation) {} override func didCancelSending(_ message: MSMessage, conversation: MSConversation) {} override func willTransition(to presentationStyle: MSMessagesAppPresentationStyle) {} override func didTransition(to presentationStyle: MSMessagesAppPresentationStyle) {} }
1
0
373
Mar ’24
The base messages extension template builds but won't install or load
I am on a fresh install of Xcode 15.3 on macOS 14.4 (23E214). I created an iMessage App template and signed it with my personal team's certificate. When I click the run button, it successfully builds and opens the simulator to the Messages app but does not open the compact extension view (or install the extension such that it shows up in the More messages extension list). This reproduces on my older laptop (same version of Xcode) as well as my friend's (also same version of Xcode). Of note: The IceCreamBuilder app installs and runs correctly with no modifications I have not provided any icons for the messages extension The iMessage App template comes with an empty main app that does not install on the home screen The only console output that seems to differ from when I run the IceCreamBuilder is this message, which appears after a couple seconds of running the project: unhandled process MobileSMS Type: Error | Timestamp: 2024-03-09 00:41:07.763631-05:00 | Process: MobileSMS | Library: CoreParsec | Subsystem: com.apple.parsec | Category: CoreParsec | TID: 0xff097
7
1
799
Mar ’24
Infinite loop getting "_dismiss changed"
I'm working on a NavigationStack based app. Somewhere I'm using: @Environment(\.dismiss) private var dismiss and when trying to navigate to that view it gets stuck. I used Self._printChanges() and discovered the environment variable dismiss is changing repeatedly. Obviously I am not changing that variable explicitly. I wasn't able to reproduce this in a small project so far, but does anybody have any idea what kind of thing I could be doing that might be causing this issue? iOS 17.0.3
6
2
820
Oct ’23
SwiftUI: View is not rendered properly
Problem: When clicking on an item, it will be (un-)completed. When it's completed then ChildView should show GroupsView. However, that's not the case. The logs are like this: init, group Fruits - items not completed false - showItems false body, group Fruits - items not completed false - showItems true init, group Fruits - items not completed false - showItems false init, group Fruits - items not completed false - showItems false import SwiftUI import SwiftData @main struct MainApp: App { var body: some Scene { WindowGroup { SomeView() } .modelContainer(appContainer) } } struct SomeView: View { @Query private var items: [AItem] var body: some View { ParentView(items: items) } } struct ParentView: View { private var groupedItems: [GroupedAItems] = [] init(items: [AItem]) { Dictionary(grouping: items) { $0.categoryName } .forEach { let groupedItems = GroupedAItems(categoryName: $0.key, items: $0.value) self.groupedItems.append(groupedItems) } } var body: some View { ScrollView { VStack(spacing: 15) { ForEach(groupedItems, id: \.self.categoryName) { groupedItems in ChildView(groupedItems) } } } } } struct ChildView: View { public var groupedItems: GroupedAItems @State private var showItems: Bool init(_ groupedItems: GroupedAItems) { self.groupedItems = groupedItems self._showItems = State(initialValue: !groupedItems.completed) print("init, group \(groupedItems.categoryName) - items not completed \(!groupedItems.completed) - showItems \(showItems)") } var body: some View { print("body, group \(groupedItems.categoryName) - items not completed \(!groupedItems.completed) - showItems \(showItems)") if showItems { return AnyView(ItemsSampleView(items: groupedItems.items, onClick: { showItems = false })) } else { return AnyView(GroupsView(groupedItems: groupedItems, onClick: { showItems = true })) } } } struct ItemsSampleView: View { public var items: [AItem] public var onClick: () -> Void private let gridColumns = [GridItem(.adaptive(minimum: CGFloat(70)))] var body: some View { VStack { Button { onClick() } label: { Image(systemName: "chevron.down") } Spacer() LazyVGrid(columns: gridColumns) { ForEach(items.sorted(by: {$0.name < $1.name})) { item in Button { item.completed.toggle() } label: { Text(item.name) } } } } } } struct GroupsView: View { public var groupedItems: GroupedAItems public var onClick: () -> Void var body: some View { VStack { Button { onClick() } label: { Image(systemName: "chevron.down") } Spacer() Text(groupedItems.categoryName) } } } @Model final class AItem: Identifiable { @Attribute(.unique) public var id: String public var name: String public var categoryName: String public var completed = false internal init(name: String, categoryName: String) { self.id = UUID().uuidString self.name = name self.categoryName = categoryName } } struct GroupedAItems { var categoryName: String var items: [AItem] var completed: Bool { items.filter { !$0.completed }.isEmpty } } @MainActor let appContainer: ModelContainer = { do { let container = try ModelContainer(for: AItem.self) // Make sure the persistent store is empty. If it's not, return the non-empty container. var itemFetchDescriptor = FetchDescriptor<AItem>() itemFetchDescriptor.fetchLimit = 1 guard try container.mainContext.fetch(itemFetchDescriptor).count == 0 else { return container } container.mainContext.insert(AItem(name: "Apple", categoryName: "Fruits")) return container } catch { fatalError("Failed to create container") } }()
1
0
59
1d
RealityKit Subdivide
In the Discover RealityKit APIs for iOS, macOS, and visionOS presentation, there was a slide at the end highlighting new features not covered in the video. One of them was surface subdivision, but I have not been able to find any documentation or APIs that support this feature. Does anyone have any further details or how this works in RealityKit?
1
1
123
1w
VisionOS GroupActivities WatchTogether
I have an application that is meant to be a "watch together" GroupActivity using SharePlay that coordinates video playback using AVPlayerPlaybackCoordinator. In the current implementation, the activity begins before opening the AVPlayer, however when clicking the back button within the AVPlayer view, the user is prompted to "End Activity for Everyone" or "End Activity for just me". There is not an option to continue the group activity. My goal is to retain the same GroupSession, even if a user exits the AVPlayer view. Is there a way to avoid ending the session when coordinating playback using the AVPlayerPlaybackCoordinator? private func startObservingSessions() async { sessionInfo = .init() // Await new sessions to watch video together. for await session in MyActivity.sessions() { // Clean up the old session, if it exists. cleanUpSession(groupSession) #if os(visionOS) // Retrieve the new session's system coordinator object to update its configuration. guard let systemCoordinator = await session.systemCoordinator else { continue } // Create a new configuration that enables all participants to share the same immersive space. var configuration = SystemCoordinator.Configuration() // Sets up spatial persona configuration configuration.spatialTemplatePreference = .sideBySide configuration.supportsGroupImmersiveSpace = true // Update the coordinator's configuration. systemCoordinator.configuration = configuration #endif // Set the app's active group session before joining. groupSession = session // Store session for use in sending messages sessionInfo?.session = session let stateListener = Task { await self.handleStateChanges(groupSession: session) } subscriptions.insert(.init { stateListener.cancel() }) // Observe when the local user or a remote participant changes the activity on the GroupSession let activityListener = Task { await self.handleActivityChanges(groupSession: session) } subscriptions.insert(.init { activityListener.cancel() }) // Join the session to participate in playback coordination. session.join() } } /// An implementation of `AVPlayerPlaybackCoordinatorDelegate` that determines how /// the playback coordinator identifies local and remote media. private class CoordinatorDelegate: NSObject, AVPlayerPlaybackCoordinatorDelegate { var video: Video? // Adopting this delegate method is required when playing local media, // or any time you need a custom strategy for identifying media. Without // implementing this method, coordinated playback won't function correctly. func playbackCoordinator(_ coordinator: AVPlayerPlaybackCoordinator, identifierFor playerItem: AVPlayerItem) -> String { // Return the video id as the player item identifier. "\(video?.id ?? -1)" } } /// /// Initializes the playback coordinator for synchronizing video playback func initPlaybackCoordinator(playbackCoordinator: AVPlayerPlaybackCoordinator) async { self.playbackCoordinator = playbackCoordinator if let coordinator = self.playbackCoordinator { coordinator.delegate = coordinatorDelegate } if let activeSession = groupSession { // Set the group session on the AVPlayer instances's playback coordinator // so it can synchronize playback with other devices. playbackCoordinator.coordinateWithSession(activeSession) } } /// A coordinator that acts as the player view controller's delegate object. final class PlayerViewControllerDelegate: NSObject, AVPlayerViewControllerDelegate { let player: PlayerModel init(player: PlayerModel) { self.player = player } #if os(visionOS) // The app adopts this method to reset the state of the player model when a user // taps the back button in the visionOS player UI. func playerViewController(_ playerViewController: AVPlayerViewController, willEndFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) { Task { @MainActor in // Calling reset dismisses the full-window player. player.reset() } } #endif }
0
0
38
10h
Apple Pay - Payment Processing Certificate
Hey there, I have a question about the Payment Processing Certificate. Does this certificate need to be in an account that is only using Push Provisioning in the apps? We don't have any payments being made in app. Do the Wallet app use this certificate to make the payments? Or only stores uses it to make in-app payments? The final question is: can we remove this certificate?
0
0
38
11h
RTL flow in SwiftUI
I have a problem in dealing with RTL language (Arabic) in SwiftUI with List and Searchable flow, also when long pressed on the search bar to prompt the options menu it is also flipped. I added the environment parameter to support right to left layout direction for the list, but when I clicks on the search bar to do the search flow the list is flipped again, Thanks in advance. var body: some View { NavigationStack { List { Section { Text("مرحبا") } } .environment(\.layoutDirection, .rightToLeft) .flipsForRightToLeftLayoutDirection(true) .navigationTitle(" جديد") .toolbar(content: { Button("اغلاق") { self.dismiss() } }) } .tint(Color.blue) .searchable(text: self.$searchText, placement: .navigationBarDrawer(displayMode: .always)) .interactiveDismissDisabled() }
1
0
68
1d
TipKit: explicit vs. implicit iCloud sync
With iOS 18, TipKit got explicit support for syncing tip state via iCloud. However, before that, TipKit already did iCloud syncing implicitly, as far as I know. How does the new explicit syncing relate to the previous mechanism? Do we have to enable iCloud syncing manually now to retain the functionality in iOS 18? Is there a way to sync with the state that was already stored by TipKit in iCloud on iOS 17?
1
0
197
3w
Progress bar in NSTableCellView changes to other cell when scrolling
Hello, I'm not I00% sure how to ask this, so I apologize if I word it wrong. This is Obj-C from an older project I have. My app has a NSTableView and each cell has a button to perform and action and shows a progress bar in each cell. The issue I'm running in to is when I scroll down while a task is running the running progress bar shows running on a different cell. So if its he 2nd from the bottom and a scroll an even number of row its equivalent is now showing the progress bar. How do I target just that one cell; making it unique?
0
0
41
11h
ControlWidget in iOS 18 Beta not showing and the widget created prior to iOS18 Beta not showing too.
I tried creating a ControlWidget following this Apple document - https://developer.apple.com/documentation/widgetkit/creating-controls-to-perform-actions-across-the-system, but for some reason the Control is not showing while I am trying to add and on top of that the widget which we created prior to iOS18 is also not showing, while trying to add. Here is the gist of code : struct WidgetLauncher{ static func main() { if #available(iOSApplicationExtension 18.0, *) { appWidgetsFor18.main() } else { appWidgets.main() } struct apptWorkWidgets: WidgetBundle { var body: some Widget { WidgetPriorToiOS18() } } @available(iOSApplicationExtension 18.0, *) struct appWidgetsFor18: WidgetBundle { var body: some Widget { WidgetPriorToiOS18() PerformActionButton() //This from the apple's document. } } @available(iOSApplicationExtension 18.0, *) struct PerformActionButton: ControlWidget { var body: some ControlWidgetConfiguration { StaticControlConfiguration( kind: "com.example.myApp.performActionButton" ) { ControlWidgetButton(action: PerformAction()) { Label("Perform Action", systemImage: "checkmark.circle") } } .displayName("Perform Action") .description("An example control that performs an action.") } } struct PerformAction: AppIntent { static let title: LocalizedStringResource = "Perform action" func perform() async throws -> some IntentResult { // Code that performs the action... return .result() } }
0
0
36
12h