Post

Replies

Boosts

Views

Activity

Reply to NSAttributedString doesn't format HTML tables properly on Sonoma
I have developed a workaround. Basically, you can copy each cell, using the first table object found for a given set of table cells. It's ugly, but does seem to work. Including some code below to show how you can do it. class ViewController: NSViewController { @IBOutlet var textView: NSTextView! override func viewDidAppear() { super.viewDidAppear() let html = """ <html> <head> <title>Testing Tables</title> <style> td { border: 1px solid; padding: 10px; } </style> </head> <body> <table> <tr> <td>Cell 1</td> <td>Cell 2</td> </tr> <tr> <td>Cell 3</td> <td>Cell 4</td> </tr> </table> </body> </html> """ let data = html.data(using: .utf8)! let string = NSMutableAttributedString(html: data, documentAttributes: nil)! let wholeRange = NSMakeRange(0, string.length) var table: NSTextTable? string.enumerateAttribute(.paragraphStyle, in: wholeRange) { value, range, _ in guard let paragraphStyle = value as? NSParagraphStyle else { return } let tableBlocks = paragraphStyle.textBlocks.compactMap { $0 as? NSTextTableBlock } for block in tableBlocks { if table == nil { table = block.table } // Keep first table found let newBlock = block.copy(for: table!) let newStyle = paragraphStyle.mutableCopy() as! NSMutableParagraphStyle newStyle.textBlocks = [newBlock] string.addAttribute(.paragraphStyle, value: newStyle, range: range) } if tableBlocks.isEmpty { table = nil } } textView.textStorage!.setAttributedString(string) } } extension NSTextTableBlock { func copy(for table: NSTextTable) -> NSTextTableBlock { let newBlock = NSTextTableBlock(table: table, startingRow: startingRow, rowSpan: rowSpan, startingColumn: startingColumn, columnSpan: columnSpan) newBlock.backgroundColor = backgroundColor newBlock.verticalAlignment = verticalAlignment for edge: NSRectEdge in [.minX, .minY, .maxX, .maxY] { for layer: NSTextBlock.Layer in [.border, .margin, .padding] { let width = width(for: layer, edge: edge) let valueType = widthValueType(for: layer, edge: edge) newBlock.setWidth(width, type: valueType, for: layer, edge: edge) } newBlock.setBorderColor(borderColor(for: edge), for: edge) } for dimension: NSTextBlock.Dimension in [.height, .maximumHeight, .maximumWidth, .minimumHeight, .minimumWidth, .width] { let value = value(for: dimension) let valueType = valueType(for: dimension) newBlock.setValue(value, type: valueType, for: dimension) } return newBlock } }
Topic: Safari & Web SubTopic: General Tags:
Nov ’23
Reply to NSAttributedString doesn't format HTML tables properly on Sonoma
We are seeing this too. What seems to be happening is that the NSTextTableBlock objects representing each cell have different table pointers. In other words, each cell gets put into its own table, leading them to appear under one another. Interestingly, if you convert this attributed string to RTF, and back again, you get something else. You still get separate tables for each cell you input, but it creates empty cells so that the original cells at least have the correct column index, like this... Conclusion: the HTML input seems to generate a new table object for each cell, instead of a single table object for all cells. Submitted this a while back under FB13254682. Have added above FB to that.
Topic: Safari & Web SubTopic: General Tags:
Nov ’23
Reply to Sign In With Apple Button stretches to occupy entire window
Seeing same issue in a AppKit app, so unrelated to SwiftUI. Seems the view is correctly positioned, but there is a sublayer of the control that is completely messed up, filling the entire window. Clicking in the place that the button should be does actually sign you in, but the visuals are completely off. Has to be a bug on Apple's side I would guess.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’23
Reply to Catalyst Developer ID support for Shared with You
We are seeing the same thing in an AppKit macOS app that is distributed outside the Mac App Store. We sign with the Developer ID, but it says that Shared with You is not in the provisioning profile. I saw this a few years ago too, only that was with Sign in with Apple. Apple later confirmed that indeed Sign in with Apple is not supported outside the Mac App Store, and the provisioning portal just strips that entitlement out for non-MAS provisioning profiles. I am seeing this very same behavior with Shared with You. My conclusion is that Shared with You only works with Mac App Store apps, and that you will be able to get it working by distributing it via TestFlight. If anyone from Apple can confirm that indeed Shared with You is not supported outside the Mac App Store, it would be appreciated. (This sort of thing should be documented; it would have saved me weeks last time).
Topic: App & System Services SubTopic: General Tags:
Sep ’22
Reply to "No options were provided for this parameter" in Edit Widget menu
I wasted too much time on this problem, because I missed one very important step. In case it saves someone else some pain, when you provide your widget with dynamic options, you must do that in a separate Intent target in your app. I had just added the IntentHandler straight to the widget extension target, and couldn't figure out why it wasn't working. Dumb mistake, but also one that leads to the above behavior.
Topic: App & System Services SubTopic: Core OS Tags:
Jun ’22
Reply to Cannot build app on Catalyst after updating to Xcode 15.4 RC
Getting same issue in Xcode 16 beta too
Replies
Boosts
Views
Activity
Jun ’24
Reply to XCode Cloud 15.2 visionOS build error
Got same problem. Seems Xcode doesn't have the write target destination for vision. Not sure if there is something we can do about it, or if this is something Apple has messed up.
Replies
Boosts
Views
Activity
Jan ’24
Reply to SwiftUI Preview incorrectly tries to build conditional dependency from another platform.
Got same thing. Any ideas?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jan ’24
Reply to Is there a `isiOSAppOnVision` flag to check iOS app on Vision Pro at runtime?
Can't you just check for the OS using #available? Seems to work for me. extension UIDevice { /// True if running on vision pro var isVisionPro: Bool { if #available(visionOS 1.0, *) { return true } else { return false } } } Update: Realized this won't work. Will also be true on any non-vision OS.
Topic: App & System Services SubTopic: Core OS Tags:
Replies
Boosts
Views
Activity
Jan ’24
Reply to Files shared for "open-in-place" editing not working correctly in iOS 17
No, not yet.
Topic: App & System Services SubTopic: Core OS Tags:
Replies
Boosts
Views
Activity
Nov ’23
Reply to SharePlay and Multiple Apps
if I recall, this was a bug and Apple fixed it. We did ship this feature with different bundle ids. They do share a group id.
Topic: App & System Services SubTopic: General Tags:
Replies
Boosts
Views
Activity
Nov ’23
Reply to NSAttributedString doesn't format HTML tables properly on Sonoma
I have developed a workaround. Basically, you can copy each cell, using the first table object found for a given set of table cells. It's ugly, but does seem to work. Including some code below to show how you can do it. class ViewController: NSViewController { @IBOutlet var textView: NSTextView! override func viewDidAppear() { super.viewDidAppear() let html = """ <html> <head> <title>Testing Tables</title> <style> td { border: 1px solid; padding: 10px; } </style> </head> <body> <table> <tr> <td>Cell 1</td> <td>Cell 2</td> </tr> <tr> <td>Cell 3</td> <td>Cell 4</td> </tr> </table> </body> </html> """ let data = html.data(using: .utf8)! let string = NSMutableAttributedString(html: data, documentAttributes: nil)! let wholeRange = NSMakeRange(0, string.length) var table: NSTextTable? string.enumerateAttribute(.paragraphStyle, in: wholeRange) { value, range, _ in guard let paragraphStyle = value as? NSParagraphStyle else { return } let tableBlocks = paragraphStyle.textBlocks.compactMap { $0 as? NSTextTableBlock } for block in tableBlocks { if table == nil { table = block.table } // Keep first table found let newBlock = block.copy(for: table!) let newStyle = paragraphStyle.mutableCopy() as! NSMutableParagraphStyle newStyle.textBlocks = [newBlock] string.addAttribute(.paragraphStyle, value: newStyle, range: range) } if tableBlocks.isEmpty { table = nil } } textView.textStorage!.setAttributedString(string) } } extension NSTextTableBlock { func copy(for table: NSTextTable) -> NSTextTableBlock { let newBlock = NSTextTableBlock(table: table, startingRow: startingRow, rowSpan: rowSpan, startingColumn: startingColumn, columnSpan: columnSpan) newBlock.backgroundColor = backgroundColor newBlock.verticalAlignment = verticalAlignment for edge: NSRectEdge in [.minX, .minY, .maxX, .maxY] { for layer: NSTextBlock.Layer in [.border, .margin, .padding] { let width = width(for: layer, edge: edge) let valueType = widthValueType(for: layer, edge: edge) newBlock.setWidth(width, type: valueType, for: layer, edge: edge) } newBlock.setBorderColor(borderColor(for: edge), for: edge) } for dimension: NSTextBlock.Dimension in [.height, .maximumHeight, .maximumWidth, .minimumHeight, .minimumWidth, .width] { let value = value(for: dimension) let valueType = valueType(for: dimension) newBlock.setValue(value, type: valueType, for: dimension) } return newBlock } }
Topic: Safari & Web SubTopic: General Tags:
Replies
Boosts
Views
Activity
Nov ’23
Reply to NSAttributedString doesn't format HTML tables properly on Sonoma
We are seeing this too. What seems to be happening is that the NSTextTableBlock objects representing each cell have different table pointers. In other words, each cell gets put into its own table, leading them to appear under one another. Interestingly, if you convert this attributed string to RTF, and back again, you get something else. You still get separate tables for each cell you input, but it creates empty cells so that the original cells at least have the correct column index, like this... Conclusion: the HTML input seems to generate a new table object for each cell, instead of a single table object for all cells. Submitted this a while back under FB13254682. Have added above FB to that.
Topic: Safari & Web SubTopic: General Tags:
Replies
Boosts
Views
Activity
Nov ’23
Reply to Sign In With Apple Button stretches to occupy entire window
Seeing same issue in a AppKit app, so unrelated to SwiftUI. Seems the view is correctly positioned, but there is a sublayer of the control that is completely messed up, filling the entire window. Clicking in the place that the button should be does actually sign you in, but the visuals are completely off. Has to be a bug on Apple's side I would guess.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’23
Reply to Catalyst Developer ID support for Shared with You
We are seeing the same thing in an AppKit macOS app that is distributed outside the Mac App Store. We sign with the Developer ID, but it says that Shared with You is not in the provisioning profile. I saw this a few years ago too, only that was with Sign in with Apple. Apple later confirmed that indeed Sign in with Apple is not supported outside the Mac App Store, and the provisioning portal just strips that entitlement out for non-MAS provisioning profiles. I am seeing this very same behavior with Shared with You. My conclusion is that Shared with You only works with Mac App Store apps, and that you will be able to get it working by distributing it via TestFlight. If anyone from Apple can confirm that indeed Shared with You is not supported outside the Mac App Store, it would be appreciated. (This sort of thing should be documented; it would have saved me weeks last time).
Topic: App & System Services SubTopic: General Tags:
Replies
Boosts
Views
Activity
Sep ’22
Reply to SWCollaborationMetadata does not appear in Messages
Thanks for the response. I have done as suggested, and the Feedback ID is FB10681825
Topic: App & System Services SubTopic: General Tags:
Replies
Boosts
Views
Activity
Jul ’22
Reply to "No options were provided for this parameter" in Edit Widget menu
I wasted too much time on this problem, because I missed one very important step. In case it saves someone else some pain, when you provide your widget with dynamic options, you must do that in a separate Intent target in your app. I had just added the IntentHandler straight to the widget extension target, and couldn't figure out why it wasn't working. Dumb mistake, but also one that leads to the above behavior.
Topic: App & System Services SubTopic: Core OS Tags:
Replies
Boosts
Views
Activity
Jun ’22