feedback-assistant / reports Goto Github PK
View Code? Open in Web Editor NEWOpen collection of Apple Feedback Assistant reports
Open collection of Apple Feedback Assistant reports
It's useful for both users and app developers to be able to control dark mode. Having an API for this would enable developers to make apps that, for example, toggles dark mode at a specific time or place.
Currently, it's possible to control dark mode with AppleScript*, but that does not work when sandboxed in the App Store... We need a native sandbox-compatible API for this!
* tell application "System Events" to tell appearance preferences to not dark mode
Notes:
I imagine the API could be something like this:
DarkMode.isEnabled = true
print(DarkMode.isEnabled)
DarkMode.onChange {
print("Is Dark Mode", DarkMode.isEnabled)
}
"Disk Utility" is missing a "Window" => "Zoom" menu item.
This is a violation of the macOS Human Interface Guidelines:
Provide a Window menu even if your app has only one window. Include the Minimize and Zoom menu items so people using Full Keyboard Access can invoke these functions using their keyboard. - https://developer.apple.com/design/human-interface-guidelines/macos/menus/menu-bar-menus/#window-menu
Steps to Reproduce:
Open Disk Utility and click the Window menu.
Expected Results:
Expected to see a Zoom menu item.
Actual Results:
Did not see a Zoom menu item.
macOS just hides NSStatusBarItem's if there are too many in the menu bar. I've gotten many support requests from confused users claiming that my app doesn't work, because it's hidden by macOS, because their menu bar is full. There should be a NotificationCenter event for when the NSStatusBarItem is force hidden/shown by the system and a property that can be checked at any time. This will let me either notify the user or try to reduce the width of my NSStatusBarItem. It would also be great if NSStatusBar could expose how much space is remaining, so I could adjust my NSStatusBarItem width accordingly.
There are a lot of useful menu bar apps out there, but the screen real estate on some MacBooks are limited. Would be great if macOS had the ability to manually hide certain menu bar icons. This could be a System Preferences pane. When you hide an icon it could show a <<
button on the left of the menu bar icons, that when clicked, would show them all temporarily. Then you could hide the ones you don't use often but still want available. This is in similar fashion as the third-party apps Bartender and Vanilla.
Mojave brought us some beautiful dynamic desktop wallpapers, but no way to produce our own. There is so much potential for creativity with this technology. Please give us an official API to easily generate such wallpapers from a list of NSImage
s and some metadata.
Expected Results:
I expected there to be APIs to generate and parse the special HEIC files used for dynamic desktop wallpapers.
Actual Results:
There's currently no official way to do this.
In "System Preferences" => "Desktop & Screen Saver", you can set a wallpaper for the current space. So you can switch to the space you want to change the wallpaper for and then set the wallpaper. There should be a way to do this programmatically too.
Expected Results:
I expected to be able to specify which space to set the wallpaper for with the NSWorkspace.shared.setDesktopImageURL
API.
I would suggest adding two new methods to NSScreen
. One for getting all the spaces in the screen (so you could set a wallpaper on all spaces), and one for getting the active space. Using these new APIs, you could get the space you want and then be able to specify it to NSWorkspace.shared.setDesktopImageURL
as an option.
Actual Results:
There's currently no way to do this.
Notes:
Related GitHub issue: sindresorhus/macos-wallpaper#4
I want to show a popover from a List
item when a button in that item is clicked. Unfortunately, the popover crashes the app the second time you click a button.
I have attached a test project that reproduces the issue and I'm also including it inline here as it's not much code:
import SwiftUI
// Reproduce: Click "Click me 0" and then "Click me 1" and the app crashes.
struct ContentView: View {
@State var popoverIndex = 0
@State var showPopover = false
var body: some View {
VStack {
List {
ForEach(0...5, id: \.self) { index in
Group {
Button(action: {
self.popoverIndex = index
self.showPopover = true
}) {
Text("Click me \(index)")
}
if self.popoverIndex == index {
Text("\(index)")
.popover(isPresented: self.$showPopover) {
Text("1").padding()
}
} else {
Text("\(index)")
}
}
}
}
}
.frame(width: 400, height: 400)
}
}
The crash I'm getting is:
2019-10-11 12:55:20.236464+0700 swiftui-conditional-popover-testcase[4993:6415173] [General] -[NSPopover showRelativeToRect:ofView:preferredEdge:]: view has no window. You must supply a view in a window.
2019-10-11 12:55:20.243261+0700 swiftui-conditional-popover-testcase[4993:6415173] [General] (
0 CoreFoundation 0x00007fff3a736d63 __exceptionPreprocess + 250
1 libobjc.A.dylib 0x00007fff70625bd4 objc_exception_throw + 48
2 CoreFoundation 0x00007fff3a736bb9 +[NSException raise:format:] + 189
3 AppKit 0x00007fff37bcdac0 -[NSPopover showRelativeToRect:ofView:preferredEdge:] + 231
4 SwiftUI 0x00007fff477ccd73 $s7SwiftUI13PopoverBridgeC20preferencesDidChangeyyAA14PreferenceListVF + 947
5 SwiftUI 0x00007fff47b1362d $s7SwiftUI13NSHostingViewC20preferencesDidChangeyyF + 493
6 SwiftUI 0x00007fff4768478d $s7SwiftUI9ViewGraphC13updateOutputs2atyAA4TimeV_tF + 221
7 SwiftUI 0x00007fff47ad8029 $s7SwiftUI16ViewRendererHostPAAE6render8interval17updateDisplayListySd_SbtFyyXEfU_yyXEfU_ + 1001
8 SwiftUI 0x00007fff47ad7a3a $s7SwiftUI16ViewRendererHostPAAE6render8interval17updateDisplayListySd_SbtFyyXEfU_ + 634
9 SwiftUI 0x00007fff47ad4514 $s7SwiftUI16ViewRendererHostPAAE6render8interval17updateDisplayListySd_SbtF + 436
10 SwiftUI 0x00007fff47b0dd23 $s7SwiftUI13NSHostingViewC6layoutyyFySo18NSAnimationContextCXEfU_ + 147
11 SwiftUI 0x00007fff47b15a01 $sSo18NSAnimationContextCIgg_ABIegg_TRTA + 17
12 SwiftUI 0x00007fff47b0def4 $sSo18NSAnimationContextCIegg_ABIyBy_TR + 36
13 AppKit 0x00007fff3792fe7f +[NSAnimationContext runAnimationGroup:] + 55
14 SwiftUI 0x00007fff47b0dc43 $s7SwiftUI13NSHostingViewC6layoutyyF + 259
15 SwiftUI 0x00007fff47b0df25 $s7SwiftUI13NSHostingViewC6layoutyyFTo + 21
16 AppKit 0x00007fff37987887 _NSViewLayout + 600
17 AppKit 0x00007fff37987325 -[NSView _layoutSubtreeWithOldSize:] + 388
18 AppKit 0x00007fff3798747f -[NSView _layoutSubtreeWithOldSize:] + 734
19 AppKit 0x00007fff3798747f -[NSView _layoutSubtreeWithOldSize:] + 734
20 AppKit 0x00007fff37984e14 -[NSView _layoutSubtreeIfNeededAndAllowTemporaryEngine:] + 1137
21 AppKit 0x00007fff379e38e7 -[NSView _setDefaultKeyViewLoop] + 227
22 AppKit 0x00007fff37a40e4e -[NSTableRowData _updateKeyViewLoopforRowView:] + 55
23 AppKit 0x00007fff37a38ff2 -[NSTableRowData _initializeRowView:atRow:] + 391
24 AppKit 0x00007fff37a3814e -[NSTableRowData _preparedRowViewForRow:storageHandler:] + 140
25 AppKit 0x00007fff38249a46 __65-[NSTableRowData _doAutomaticRowHeightsForInsertedAndVisibleRows]_block_invoke_2 + 147
26 Foundation 0x00007fff3ce999d5 __NSINDEXSET_IS_CALLING_OUT_TO_A_BLOCK__ + 7
27 Foundation 0x00007fff3cd9ffd4 __NSIndexSetEnumerate + 1042
28 AppKit 0x00007fff38249830 __65-[NSTableRowData _doAutomaticRowHeightsForInsertedAndVisibleRows]_block_invoke + 284
29 AppKit 0x00007fff37ac1a4b -[NSTableRowData _keepTopRowStable:andDoWorkUntilDone:] + 531
30 AppKit 0x00007fff38249704 -[NSTableRowData _doAutomaticRowHeightsForInsertedAndVisibleRows] + 210
31 AppKit 0x00007fff37ac68f0 -[NSTableRowData _updateVisibleViewsBasedOnUpdateItems] + 271
32 AppKit 0x00007fff37ac6694 -[NSTableRowData _updateVisibleViewsBasedOnUpdateItemsAnimated] + 228
33 AppKit 0x00007fff37a0eb3f -[NSTableRowData _doWorkAfterEndUpdates] + 69
34 AppKit 0x00007fff37976749 -[NSTableView _endUpdateWithTile:] + 128
35 SwiftUI 0x00007fff478350a9 $s7SwiftUI26NSTableViewListCoordinator33_F1BC09E3726CDFAB432BC839F2C003A2LLC011updateTableD0_4from2toySo0cD0C_xxtF + 1833
36 SwiftUI 0x00007fff47830d38 $s7SwiftUI9_ListCore33_F1BC09E3726CDFAB432BC839F2C003A2LLV12updateNSView_7contextyAA0cD10ScrollViewACLLC_AA0N20RepresentableContextVyADyxq_GGtF + 1048
37 SwiftUI 0x00007fff474996d1 $s7SwiftUI32PlatformViewRepresentableAdaptor33_38FE679A85C91B802D25DB73BF37B09FLLV06updateD8Provider_7contexty10NSViewTypeQz_AA0cdE7ContextVyADyxGGtF + 289
38 SwiftUI 0x00007fff47a806fd $s7SwiftUI17PlatformViewChild33_A513612C07DFA438E70B9FA90719B40DLLV6update7contexty14AttributeGraph0O7ContextVyADyxGGz_tFyyXEfU_ + 2301
39 SwiftUI 0x00007fff47a78316 $s7SwiftUI17PlatformViewChild33_A513612C07DFA438E70B9FA90719B40DLLV6update7contexty14AttributeGraph0O7ContextVyADyxGGz_tF + 310
40 SwiftUI 0x00007fff47a823a0 $s7SwiftUI17PlatformViewChild33_A513612C07DFA438E70B9FA90719B40DLLVyxG14AttributeGraph07UntypedM0AafGP7_update_5graph9attributeySv_So10AGGraphRefaSo11AGAttributeatFZTW + 32
41 AttributeGraph 0x00007fff4e299279 $sTA + 25
42 AttributeGraph 0x00007fff4e28097b _ZN2AG5Graph11UpdateStack6updateEv + 1111
43 AttributeGraph 0x00007fff4e280c39 _ZN2AG5Graph16update_attributeEjb + 377
44 AttributeGraph 0x00007fff4e285849 _ZN2AG8Subgraph6updateEj + 929
45 SwiftUI 0x00007fff47684670 $s7SwiftUI9ViewGraphC14runTransaction33_D63C4EB7F2B205694B6515509E76E98BLL2inySo10AGGraphRefa_tF + 224
46 SwiftUI 0x00007fff476843b6 $s7SwiftUI9ViewGraphC17flushTransactionsyyFySo10AGGraphRefaXEfU_ + 262
47 SwiftUI 0x00007fff47683d25 $s7SwiftUI9ViewGraphC17flushTransactionsyyF + 229
48 SwiftUI 0x00007fff47683e9f $s7SwiftUI9ViewGraphC16asyncTransaction_8mutation5styleyAA0F0V_xAA01_D14Mutation_StyleOtAA0dI0RzlFyycfU_yACXEfU_ + 15
49 SwiftUI 0x00007fff47680679 $s7SwiftUI9ViewGraphCIgg_ACytIeggr_TR03$s7a3UI9cD92C16asyncTransaction_8mutation5styleyAA0F0V_xAA01_D14Mutation_StyleOtAA0dI0RzlFyycfU_yACXEfU_Tf3nnpf_n + 9
50 SwiftUI 0x00007fff47ad5f87 $s7SwiftUI16ViewRendererHostPAAE06updateC5Graph4bodyqd__qd__AA0cG0CXE_tlF + 71
51 SwiftUI 0x00007fff47ad8df3 $s7SwiftUI13NSHostingViewCyqd__GAA0D13GraphDelegateA2aEP06updatedE04bodyqd__qd__AA0dE0CXE_tlFTW + 19
52 SwiftUI 0x00007fff47683e7a $s7SwiftUI9ViewGraphC16asyncTransaction_8mutation5styleyAA0F0V_xAA01_D14Mutation_StyleOtAA0dI0RzlFyycfU_ + 122
53 SwiftUI 0x00007fff476938ac $sIeg_ytIegr_TR + 12
54 SwiftUI 0x00007fff47b2d871 $sIeg_ytIegr_TRTA + 17
55 SwiftUI 0x00007fff47b2a827 $sSo9NSRunLoopC7SwiftUIE14flushObserversyyFZ + 119
56 SwiftUI 0x00007fff47b2d799 $sSo9NSRunLoopC7SwiftUIE11addObserveryyyycFZySo05CFRunbF3RefaSg_So0gB8ActivityVSvSgtcfU_ + 9
57 SwiftUI 0x00007fff47b2d7cb $sSo9NSRunLoopC7SwiftUIE11addObserveryyyycFZySo05CFRunbF3RefaSg_So0gB8ActivityVSvSgtcfU_To + 43
58 CoreFoundation 0x00007fff3a6e24be __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
59 CoreFoundation 0x00007fff3a6e23e4 __CFRunLoopDoObservers + 457
60 CoreFoundation 0x00007fff3a684e4e CFRunLoopRunSpecific + 558
61 HIToolbox 0x00007fff39211b2d RunCurrentEventLoopInMode + 292
62 HIToolbox 0x00007fff39211779 ReceiveNextEventCommon + 356
63 HIToolbox 0x00007fff392115f7 _BlockUntilNextEventMatchingListInModeWithFilter + 64
64 AppKit 0x00007fff378a7ac4 _DPSNextEvent + 990
65 AppKit 0x00007fff378a6834 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1352
66 AppKit 0x00007fff378a0fd4 -[NSApplication run] + 658
67 AppKit 0x00007fff37892e7d NSApplicationMain + 777
68 swiftui-conditional-popover-testcas 0x00000001000069bd main + 13
69 libdyld.dylib 0x00007fff71984405 start + 1
)
2019-10-11 12:55:20.272092+0700 swiftui-conditional-popover-testcase[4993:6415173] [General] -[NSApplication runModalForWindow:] may not be invoked inside of transaction begin/commit pair, or inside of transaction commit (usually this means it was invoked inside of a view's -drawRect: method.)
2019-10-11 12:55:20.272875+0700 swiftui-conditional-popover-testcase[4993:6415173] [General] (
0 CoreFoundation 0x00007fff3a736d63 __exceptionPreprocess + 250
1 libobjc.A.dylib 0x00007fff70625bd4 objc_exception_throw + 48
2 CoreFoundation 0x00007fff3a736bb9 +[NSException raise:format:] + 189
3 AppKit 0x00007fff3813698c _NSRunModal + 152
4 AppKit 0x00007fff37ab804c -[NSApplication runModalForWindow:] + 241
5 AppKit 0x00007fff37d11943 -[NSApplication _showException:] + 541
6 AppKit 0x00007fff37c55de8 -[NSApplication reportException:] + 951
7 AppKit 0x00007fff378a1086 -[NSApplication run] + 836
8 AppKit 0x00007fff37892e7d NSApplicationMain + 777
9 swiftui-conditional-popover-testcas 0x00000001000069bd main + 13
10 libdyld.dylib 0x00007fff71984405 start + 1
)
There is certain system information that most apps will need, but it currently requires a lot of ugly and fragile low-level code to get it. Would be nice if the most common things could be exposed as a set of coherent APIs. Maybe under a System
namespace.
I propose starting with the following system info:
MacBookPro11,3
MacBook Pro (Retina, 15-inch, Late 2013)
kIOPlatformUUIDKey
kIOPlatformSerialNumberKey
.laptop
, .desktop
, .tablet
, .phone
WKWebView currently requires the com.apple.security.network.client
entitlement to load any content. This makes sense for remote content, but not for local content. WKWebView should not require network access to load a HTML string or local file.
I take pride in making my apps privacy-focused by not including the com.apple.security.network.client
entitlement, so my users can be sure my apps cannot access the network. This now means I cannot have a web view in my apps... Apple cares strongly about privacy, so I'm hoping this can be fixed.
If this was an intentional decision, I strongly suggest you reconsider, and at a minimum more clearly document this and log an error. I wasted a lot of time debugging why the HTML content was not loading.
let configuration = WKWebViewConfiguration()
configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
let webView = WKWebView(frame: CGRect(x: 0, y: 0, width: 400, height: 400, configuration: configuration)
// This never loads
webview.loadHTMLString("<h1>Foo</h1>")
// Neither does this
let htmlFile = Bundle.main.url(forResource: "index", withExtension: "html")!
webView.loadFileURL(htmlFile, allowingReadAccessTo: htmlFile)
Both of the above cases correctly load when the com.apple.security.network.client
entitlement is added.
Relevant Apple forum discussion: https://forums.developer.apple.com/thread/116359
This is a duplicate of radar #44079032
With Mojave, sending an Apple Event to another app will elicit an authorization prompt to the user. Even in cases where the Apple Event is simply soliciting the opening of a new Safari window.
An app's scripting interface isn't inherently privacy sensitive. Treating all an any of these interactions as sensitive burdens the user experience and contributes to training users to ignore security dialogs.
Since 2012 apps can group related parts of their scripting interface using the access-group feature in their .sdef files. What I suggest is to augment that feature and let the app decide whether or not that particular part of the API is privacy sensitive.
This would allow innocuous scripting APIs to run un-prompted and greatly reduce the burden on the user. It would also incentivize developers to annotate the scripting interface to avoid the catch-all prompt when it's not needed.
The NSScreen.deviceDescription
docs says:
In addition to the display device constants described in NSWindow, you can also retrieve the CGDirectDisplayID value associated with the screen from this dictionary. To access this value, specify the Objective-C string @"NSScreenNumber" as the key when requesting the item from the dictionary. The value associated with this key is an NSNumber object containing the display ID value. This string is only valid when used as a key for the dictionary returned by this method.
It would be better to expose the screen number as a NSDeviceDescriptionKey
instead of having to document this workaround.
Expected Results:
NSScreen.main!.deviceDescription[.screenNumber] as! CGDirectDisplayID
Actual Results:
NSScreen.main!.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as! CGDirectDisplayID
Sandboxed apps must use the SMLoginItemSetEnabled
method to enable/disable enable an app to be launched at login (through a helper app). Usually, you would have a checkbox in the app's preferences to toggle it, like [ ] Launch at login
. The problem is that there is no way to know whether the helper app is set to be launched at login or not. So you can't correctly show the status in the checkbox. The SMLoginItemSetEnabled
method only lets us set the status, but not check it. We could persist the status to UserDefaults, but then it could easily get out of sync (Has happened to my app before). A common workaround is to use SMCopyAllJobDictionaries
to check the status 0, but that API has been deprecated since macOS 10.10 with no replacement...
Expected Results:
I expected there to be a way to check the current status of SMLoginItemSetEnabled
. There could be a method called SMLoginItemIsEnabled
that would accept a bundle identifier and return a bool of whether it's enabled or not.
Actual Results:
Have to use UserDefaults which can be buggy or a deprecated API (SMCopyAllJobDictionaries).
Notes:
Relevant GitHub issue: sindresorhus/LaunchAtLogin#12
It's currently not possible to attach multiple .sheet()
to a view. SwiftUI will only show the last one, even if presented at different times. This is an annoying limitation and I hope it's just temporary.
I've attached a test project. Just click the buttons and see that just the last sheet works. I'm also including the code inline here as it's not much:
import SwiftUI
struct ContentView: View {
@State var showSheet1 = false
@State var showSheet2 = false
var body: some View {
VStack {
Button(action: {
self.showSheet1 = true
}) {
Text("Show sheet 1 (does not work)")
}
Button(action: {
self.showSheet2 = true
}) {
Text("Show sheet 2 (works)")
}
}
.frame(width: 400, height: 400)
.sheet(isPresented: self.$showSheet1) {
Text("Sheet 1")
.padding()
}
.sheet(isPresented: self.$showSheet2) {
Text("Sheet 2")
.padding()
}
}
}
This is a common problem as illustrated by this Stack Overflow question: https://stackoverflow.com/questions/57103800/swiftui-support-multiple-modals
I'm only reproducing this on macOS, but I think it's an issue on iOS too.
It should be possible to show a NSPopover from a CGPoint in screen coordinates. You don't always have a NSView in a NSWindow you can show it from. The current workaround is to create an invisible 1-pixel window, but this is difficult to get right.
After creating an active (.defaultTap) CGEventTap and adding it to a run loop, the system-wide pinch and swipe behavior gets disrupted on certain CGEventType.tapDisabledByTimeout events that reach the CGEventTapCallback, e.g. by scrolling through heavy webpages in Safari.
The normal pinch and swipe behavior can be reinstated by a display sleep (reliable) or re-enabling the pinch gesture in the trackpad system preferences (not reliable).
This bug is well described in applications using CGEventTaps, see the following links:
The RFC 7159 JSON spec allows top-level fragments, like 99
, but JSONEncoder/JSONDecoder does not support this. Top-level fragments can be useful to save single values to disk or User Defaults 2.
NSJSONSerialization already supports decoding top-level fragments with the JSONSerialization.ReadingOptions.allowFragments
setting, so I'm requesting introducing the same setting for encoding too: JSONSerialization.WritingOptions.allowFragments
. Then JSONEncoder/JSONDecoder in Swift could use that to implement support for top-level fragments.
Expected Results:
I expected this to work:
let intData = "99".data(using: .utf8)!
let decoder = JSONDecoder()
decoder.allowFragments = true
try decoder.decode(Int.self, from: intData) // 99
Actual Results:
It doesn't work.
I have a status bar app with a NSMenu where I show some information in a NSMenuItem. I prefer using NSAttributedString to style the content instead of a custom view, because with a custom view I need to manually replicate all the native behavior. The problem with not using a custom view is that either the item gets highlighted on hover or I make it disabled and the text is darker. I would like to have the normal white text color, just without the highlight on hover.
I imagine it could be set like this:
let menuItem = NSMenuItem()
menuItem.canBeHighlighted = false
There actually is a private property for this already _canBeHighlighted
, so it's clear that Apple needs it somewhere too. Would be nice if you could expose this property for third-party developers.
If you have a NSMenuItem with a custom view (using NSMenuItem#view) in a NSMenu that's attached to a NSStatusItem, the NSMenu will have a top shadow that overlaps the status bar, instead of the status bar having a shadow overlapping the NSMenu. This doesn't look very good and I've gotten many complaints about that for my app, but there's no way to work around it... The problem appears even if the NSMenuItem with the custom view is not the first item in the menu.
Run the attached Xcode project, then click the "Custom View" and "No Custom View" items in the status bar and look closely at the top of the menus. Notice how the shadow differs.
I've also attached screenshots to clearly illustrate the difference (zoom in on them), and an animated GIF that toggles between them.
There are currently sandbox entitlements for the Downloads, Pictures, Music, and Movies directories, but a very common (and forgotten) need is to be able to put something on the "Desktop". I propose adding a write-only "Desktop" sandbox entitlement. I don't need to read what the user has on their desktop. I just need to write. If there are name conflicts, just rename my file from Foo
to Foo 2
like Finder does.
Having this would solve so many use-cases. Right now, I have to inconvenience the user with an NSOpenPanel
prompt...
For example, if you take a screenshot and right-click the floating screenshot thumbnail, you get some menu items: "Save to Desktop" and "Save to Documents". macOS obviously doesn't need an NSOpenPanel
prompt for these, but third-party apps do. This is unfair and shows that there's a real need for this kind of entitlement.
Date: 2019-09-02
Resolution: Open
Area: Xcode
OS: macOS 10.15 beta 8
Xcode: 11
Type: Incorrect/Unexpected Behavior
When having an SPM package that has testing dependency, Xcode Preview will try to build it and then fail most of the time making it unusable.
I need to be able to add/change location metadata to images in the Photos.app library on macOS. I need to do this without creating a new image. On iOS, I can use PHAssetChangeRequest
for this, but strangely enough it's not available on macOS. Please make this useful API available on macOS too.
https://developer.apple.com/documentation/photokit/phassetchangerequest/1624050-init
Date: 2019-10-01
Resolution: Open
Area: Combine.framework
OS: macOS 10.15 beta 10
Xcode: 11
Type: Application Crash
We tried implementing Combine extensions at Moya but it turned out that all of the package managers had problems with automatic linking & canImport(Combine) statement. When talking to Ankit he thought that it might be a problem with Combine framework itself and availability marks. We really would like to support Combine but it seems like it’s impossible right now without breaking iOS < 13. I would really appreciate any guidance on that.
Example project: https://github.com/phimage/moyacmdtest
Discussion around Combine support: Moya/Moya#1928
I use NSOpenPanel
to let the user select a directory where my app can output some files. I want to inform the user early, while the open panel is still open, if the user tries to select a read-only directory, as I wouldn't be able to write to that. The problem is that the validate
delegate method doesn't get access to the user-selected directory, so it will always show the error message for all directories, even writable ones.
Steps to Reproduce:
I have this code to open the panel:
@NSApplicationMain
final class AppDelegate: NSObject, NSApplicationDelegate {
func convert() {
let panel = NSOpenPanel()
panel.delegate = self
panel.canChooseFiles = false
panel.canChooseDirectories = true
panel.canCreateDirectories = true
panel.allowsMultipleSelection = false
panel.prompt = "Convert"
panel.message = "Choose where to save the converted images"
panel.beginSheetModal(for: window) {
if $0 == .OK {
self.startConversion(urls, outputDirectory: panel.urls.first!)
}
}
}
}
And I have implemented the validate
delegate method to show an error while the open panel is shown, which informs the user that the directory they chose is read-only:
extension AppDelegate: NSOpenSavePanelDelegate {
func panel(_ sender: Any, validate url: URL) throws {
if !FileManager.default.isWritableFile(atPath: url.path) {
throw CocoaError(.fileWriteVolumeReadOnly)
}
}
}
Expected Results:
I expected FileManager.default.isWritableFile(atPath: url.path)
to return true
for a path that is writable.
Actual Results:
The code FileManager.default.isWritableFile(atPath: url.path)
always returns false
because it doesn't get access to the security scoped bookmark created by NSOpenPanel
.
Notes:
The workaround is to just let the user select anything, then in panel.beginSheetModal
, check whether the directory writable, and if not, show an NSAlert and then show the NSOpenPanel
again. This is a bad user-experience.
I already opened rdar://46998451, but I think the use-case of "only wanting a path you can write to" such a common use-case that it should be handled by NSOpenPanel
.
My use-case: I use NSOpenPanel
to let the user select a directory where my app can output some files. I want to inform the user early, while the open panel is still shown, if the user tries to select a read-only directory, as I wouldn't be able to write to that.
Even if rdar://46998451 is fixed, I still think this feature has merits on its own.
Steps to Reproduce:
I have this code to open the panel:
@NSApplicationMain
final class AppDelegate: NSObject, NSApplicationDelegate {
func convert() {
let panel = NSOpenPanel()
panel.delegate = self
panel.canChooseFiles = false
panel.canChooseDirectories = true
panel.canCreateDirectories = true
panel.allowsMultipleSelection = false
panel.prompt = "Convert"
panel.message = "Choose where to save the converted images"
panel.beginSheetModal(for: window) {
if $0 == .OK {
self.startConversion(urls, outputDirectory: panel.urls.first!)
}
}
}
}
Expected Results:
I expected to be able to set a property, let's call it panel.allowReadOnlyPaths = false
, to make NSOpenPanel show an error if the user tries to select a read-only file or directory.
Actual Results:
Because of rdar://46998451, I can't even implement this manually, so I have to end up with a user unfriendly workaround that only shows an error after the open panel is dismissed, and then I have to show the open panel again.
In our app, we embed AVPlayerView
(and call AVPlayerView#beginTrimming()
) together with other video settings. We don't want the user to have to manually click the "Trim" button. Instead, they can click our "Convert" button when they're done with both trimming and other settings.
Since there's no way to hide those buttons at the moment, we had to resort to subview traversing, which is very fragile...
By default, AppKit doesn't always crash on uncaught exceptions. It will catch exceptions thrown on the main thread, preventing the application from crashing, but it will also likely corrupt your process’s state. This is not a good default. It's better to crash than to end up in a corrupted state. This is what iOS does.
Developers can fix this bad behavior by setting the following:
UserDefaults.standard.register(defaults: ["NSApplicationCrashOnExceptions": true])
But most don't know about this, however, which means a lot of apps would silently corrupt their own process state without even knowing.
Expected Results:
I expected "NSApplicationCrashOnExceptions": true
to be the default behavior.
Actual Results:
NSApplicationCrashOnExceptions
has to be manually enabled.
Notes:
More info: https://docs.fabric.io/apple/crashlytics/os-x.html#uncaught-exceptions
This could be fixed in a non-breaking matter by only defaulting to true when linked against the latest macOS SDK.
That would make it easier to work with stdout, stderr, and other file handles. For example, using stderr with Swift.print()
.
Currently, every project has to include this extension:
extension FileHandle: TextOutputStream {
public func write(_ string: String) {
write(string.data(using: .utf8)!)
}
}
Swift 4.2
Relevant Stack Overflow question: https://stackoverflow.com/questions/24041554/how-can-i-output-to-stderr-with-swift
Swift issue: https://bugs.swift.org/browse/SR-9918
In "System Preferences" => "Desktop & Screen Saver", if you set the wallpaper to a custom image, you can choose different display modes, one of which is "Tile".
Expected Results:
I expected to be able to set the "Tile" mode with the NSWorkspace.shared.setDesktopImageURL
API.
Actual Results:
The other modes can be set, but not "Tile".
Relevant GitHub issue: sindresorhus/macos-wallpaper#13
When calling AVPlayerView#beginTrimming()
on an AVPlayerView
instance, you get a trim UI. The user can drag the yellow handles to choose a range of the video to trim to. Currently, the user is able to drag the handles so close together that it results in a zero trim range. That should not be possible as a zero duration is useless. AVPlayerView
should ensure the trim range is at least a non-zero number, like 0.1 or 0.01`. Preferably, the minimum trim range could be set programmatically and default to a sensible number. So if I set the minimum trim range to 1 second, and the user tries to drag the trim handles closer together than 1 second, the handles would snap (with animation) to 1 second range.
The bug can also be reproduced in QuickTime Player, which I assume is also using AVPlayerView
. Just open a video in QuickTime Player, press Command+T, then drag the right trim handle all the way to the left, and then click Trim. The video is now unplayable by QuickTime Player (the play button doesn't do anything).
Sometimes you need to get a resource from the current bundle, which isn't necessarily the main bundle. It would be useful to have a property for this as it's a common need.
Expected Results:
Bundle.current.bundleURL
Actual Results:
private final class BundleMarker {}
extension Bundle {
static let current = Bundle(for: BundleMarker.self)
}
Bundle.current.bundleURL
While it's easy to work around. It's such a common use-case that it makes sense to include it in AppKit itself.
Date: 2019-07-23
Resolution: Open
Area: Xcode/AppKit
OS: macOS 10.15 beta 1 - beta 10
Xcode: 11
Type: Incorrect/Unexpected Behavior
NSSavePanel "save button" doesn't do anything when given file already exists.
Steps to reproduce:
In previous macOS versions it worked properly and showed an alert that the file already exists.
When setting NSStatusBarButton#title
(NSStatusItem), the text in the status bar is not perfectly vertically centered. It's off by 1 pixel. This becomes clear if you move it beside the system clock, which is perfectly vertically centered.
Please open the attached test-case-proof.png
file and zoom in closely. Notice how the red line touches the first T
, but not the second T
. The first Thu
is from our test case app, the second Thu
is from the system clock. Our app has 11 pixels above the text and 13 pixels below, while the system clock has 12 pixels both above and below (meaning, it's centered perfectly).
To reproduce, open NSStatusBarTestCase.xcodeproj
, run and build, then drag the app (while holding the Command key) to be beside the system clock in the status bar. You can now compare them and see that they're not identically vertically aligned.
My app lives in the status bar and users are complaining it's not vertically aligned with system status bar items like the system clock or fast user switcher.
This issue is pretty critical as it means all macOS apps with a text status bar item look uneven.
When using [NSFileManager trashItemAtURL:resultingItemURL:error:]
, the originating path is not stored in the .DS_Store file, causing the Put Back
option not to be shown for programmatically trashed files.
Steps to Reproduce:
Create a file called foobar
, then compile and run the below:
@import Foundation;
int main() {
@autoreleasepool {
NSFileManager *fm = [[NSFileManager alloc] init];
NSError *err;
NSURL *url = [NSURL fileURLWithPath:@"foobar"];
NSURL *result;
if (![fm trashItemAtURL:url resultingItemURL:&result error:&err]) {
fprintf(stderr, "%s\n", err.localizedDescription.UTF8String);
return 1;
}
NSLog(@"now at: %@", result);
}
return 0;
}
Then go to the Trash, right-click the foobar
file, and notice how "Put Back" is not there.
Expected Results:
I expected the foobar
file in the trash to show the Put Back
context menu option.
Actual Results:
The Put Back
menu item is missing and the file doesn't show up in .DS_Store
.
Notes:
It's reproducible with macOS 10.14 beta 3 and all the way back to at least 10.11.
More info: sindresorhus/macos-trash#4
Apple is known for prioritizing consistency and quality. You have a very well written and comprehensive Human Interface Guidelines that you expect third-party developers to follow. However, Finder and many of Apple's apps do not properly follow these guidelines, setting a bad example for third-party developers, and weakening your reputation of caring about quality.
Read through https://developer.apple.com/design/human-interface-guidelines/macos/app-architecture/preferences/
I have compiled a list of apps that don't follow the HIG and what they need to fix:
Update the window's title to reflect the currently visible preference pane.
Disable the Minimize and Zoom buttons.
Disable the Minimize and Zoom buttons.
Apply preference changes immediately.
Disable the Minimize and Zoom buttons.
For example, if your preferences window has a General preference pane, the window’s title should be General when that pane is active.
If your window doesn’t have multiple preference panes, then its title should be App Name Preferences.
If your window doesn’t have multiple preference panes, then its title should be App Name Preferences.
If your window doesn’t have multiple preference panes, then its title should be App Name Preferences.
Disable the Minimize and Zoom buttons.
Disable the Minimize and Zoom buttons.
This could have been all solved if Apple provided an official Preferences window controller that worked exactly like the Human Interface Guidelines describes. Lots of third-party apps also get it wrong when implementing a Preferences window.
Steps to Reproduce:
Open one of the mentions apps and click "Preferences…" in the app menu.
Expected Results:
Expected the Preferences window to follow the HIG.
Actual Results:
The window does not follow the HIG.
Every app that wants to give the user the ability to record their screen for various purposes needs to manually implement screen recording functionality and user-interface for crop selection, etc, even though the main purpose of the app may not be screen recording, it's just there as a bonus. The app also don't really need full access to the user's screen. To ensure both privacy and quality, it would be nice if AppKit had an API to programmatically control the new screen capture/recording functionality in macOS (Screenshot.app).
With such programmatic API, I should be able to choose if it's screen recording, screen capture, or both, and the appropriate UI would be presented to the user. I would register a callback that would be called when the recording is done, with the recorded video. As a bonus, in the case of a screen recording, the API would present a trim UI for the user, so the video I would get in the registered callback would be the trimmed video.
The "Close" menu item should be in the "File" menu.
From the Human Interface Guidelines:
The Window menu also doesn’t include a Close menu item; instead, it is in the File menu.
However, the following built-in apps break that rule by having it in the "Window" menu:
It doesn't set a good example for third-party developers that Apple doesn't follow its own Human Interface Guidelines.
Steps to Reproduce:
Open Photo Booth and click the "Window" menu.
Expected Results:
Expected to not see a "Close" menu item.
Actual Results:
There's a "Close" menu item there.
The ProcessInfo.processInfo.operatingSystemVersionString
property includes the build version [1], but there's no easy way to get just the build version. The build version can be useful when you want to format the macOS version in a custom way.
[1]: Example: Version 10.14.3 (Build 18D42)
Steps to Reproduce:
Expected Results:
I expected ProcessInfo.processInfo.operatingSystemVersion
to be a struct like this:
public struct OperatingSystemVersion {
public var majorVersion: Int
public var minorVersion: Int
public var patchVersion: Int
public var buildVersion: String
}
Where buildVersion
would be something like 18D42
Actual Results:
public struct OperatingSystemVersion {
public var majorVersion: Int
public var minorVersion: Int
public var patchVersion: Int
}
I have a List
of buttons. When a button is clicked, a popover is shown from that list item. Inside the popover, there's a "Dismiss" button that is supposed to dismiss the popover, but that doesn't work.
I have included a test project that reproduces the issue. I'm also including the code inline as it's not much:
import SwiftUI
// Reproduce: Click one of the "Click me" button and then click "Dismiss" in the popover. Notice how the popover is not dismissed.
struct PopoverView: View {
@Environment(\.presentationMode) var presentationMode
var body: some View {
Button(action: {
self.presentationMode.wrappedValue.dismiss()
}) {
Text("Dismiss")
.padding()
}
}
}
struct ListItemView: View {
let index: Int
@State var showPopover = false
var body: some View {
Group {
Button(action: {
self.showPopover = true
}) {
Text("Click me \(index)")
}
Text("\(index)")
.popover(isPresented: self.$showPopover) {
PopoverView()
}
}
}
}
struct ContentView: View {
var body: some View {
VStack {
List {
ForEach(0...5, id: \.self) { index in
ListItemView(index: index)
}
}
}
.frame(width: 400, height: 400)
}
}
I have a Share extension that needs to know which app triggered it. The extension presents a list of apps and by knowing which app triggered it, it can prioritize that app in the list by moving it to the top.
There are also other use-cases for knowing this:
Expected Results:
I expected NSExtensionContext
to have a .sourceApp
property with the name (or NSRunningApplication
instance) of the host/trigger app.
Actual Results:
No property like this.
Notes:
My current workaround is to use NSWorkspace.shared.frontmostApplication
, but that has timing issues.
When presenting a .sheet()
, I expected it to prevent interaction with the content behind it. It does correctly prevent normal clicks, but if you have set up a context menu, it does not prevent right-clicking. If you have a .onMove
installed, it also gives the row a blue border when right-clicking. None of this should happen when a .sheet()
is presented.
I have attached a Xcode project with a test case. Just right-click the text to see the incorrect behavior. I'm also including the code inline as it's not much:
struct ContentView: View {
var body: some View {
VStack {
Text("Right-click me")
.contextMenu {
Button(action: {}) {
Text("Foo")
}
}
}
.frame(width: 400, height: 400)
.sheet(isPresented: .constant(true)) {
Text("XXXXXXX")
.frame(width: 100, height: 100)
}
}
}
I'm aware I can work around it with .allowsHitTesting()
and I currently do, but I shouldn't have to.
I have a list of rows that can be reordered with dragging, but I also want to add the ability to double-click a row to edit it. The problem is that when I add .onTapGesture(count: 2) {}
to a row, the row can no longer be dragged and dropped.
I have attached an Xcode project that clearly illustrates the problem, I'm also including the code inline here as it's not much:
import SwiftUI
// 1. "Build & run" and then drag a row and notice the blue line indicating support for drag and drop.
struct ContentView: View {
var body: some View {
List {
ForEach(0...5, id: \.self) { index in
Text("Hello World \(index)")
.frame(maxWidth: .infinity, maxHeight: .infinity)
// 2. Uncomment this, "build & run", and notice how there's no longer a blue line indicator when you try to drag a row.
// .onTapGesture(count: 2) {}
}
.onMove { (indexSet, index) in }
}
}
}
This is needed to be able to set a button as the default button that is triggered when the user presses the Return key, or Esc to dismiss a .sheet()
.
Currently, I have to wrap NSButton to get this functionality, but I expect such functionality to be part of SwiftUI.
Preferably, the SwiftUI solution should be strongly-typed and accept an enum case instead of a string, as the current NSButton keyEquivalent
is not very elegant.
https://developer.apple.com/documentation/appkit/nsbutton/1525368-keyequivalent
If you use NSWorkspace.shared.setDesktopImageURL
to set the desktop wallpaper to an image, then later delete that image and rename another image to the same name, then set that image as the desktop wallpaper with NSWorkspace.shared.setDesktopImageURL
, the desktop wallpaper doesn't update.
Steps to Reproduce:
Run the attached Playground while being able to see the desktop wallpaper and notice that the desktop wallpaper never changes to the "chicken-dog" image.
Expected Results:
I expected calling NSWorkspace.shared.setDesktopImageURL
to always update the wallpaper, even if it's the same URL as the existing wallpaper, since the image at that URL might have changed.
Alternatively, expose some way to force update the cache.
Actual Results:
It doesn't update. Probably some kind of caching.
I would like to be able to programmatically open the Calendar app at a specific date. In my app, I show a small calendar and when the user clicks a date, I want to show that date in the Calendar app. As you can see from Stack Overflow 1, it's a common need. Currently, I'm forced to use the ScriptingBridge and ask for permissions to AppleEvents and Calendar just for that. I would prefer not asking for permissions for such a simple thing as this. I imagine the URL scheme would be something like this: ical://open?date=2019-01-01
. Alternatively, it could be a NSWorkspace method, like NSWorkspace.shared.showDate()
or something.
The trash has this useful feature where you can right-click an item in the trash and select "Put Back" to put it back where it came from. AppKit has a method for programmatically trashing a file; FileManager.default.trashItem()
. It would be useful if you could programmatically put a file pack from the trash. Apps could use this to be able to undo a trash operation. Undo is an important functionality in macOS apps and this missing API makes that much harder to achieve.
Expected Results:
I expected there to be an API for putting files back from the trash. Could be something like FileManager.default.restoreTrashItem()
, that would accept the original path of a trashed item, find it in the trash, and put it back where it came from.
Actual Results:
There's no way to achieve this now, other than manually reverse engineering the .DS_Store
file format and parse out the originals paths of the trash items.
Notes:
Relevant GitHub issue: sindresorhus/macos-trash#1
According to the Human Interface Guidelines, the "Enter Full Screen" menu item should be in the "View" menu, not in the "Window menu: https://developer.apple.com/design/human-interface-guidelines/macos/menus/menu-bar-menus/#view-menu
Built-on system apps like "ColorSync Utility.app" and "System Information.app" does not follow this. They have no "View" menu, so instead the "Enter Full Screen" menu item is placed in the "Window" menu. If this is actually allowed, it should be clarified in the Human Interface Guidelines.
Steps to Reproduce:
Open the System Information app and click the "Window" menu.
Expected Results:
I expected the "Enter Full Screen" menu item to not be there.
Actual Results:
It's there.
In a list of rejected In App Purchases, when one IAP is updated the entire list is marked as "Waiting for review". However only the one IAP which was updated will go into review.
Submit multiple In App Purchases for review
Wait for them all to be rejected
Update one In App Purchase
What did you expect to happen?
Only the updated In App Purchase should be shown as waiting for review. Or, all In App Purchases actually go back in the review queue.
What actually happened?
All In App Purchases that were rejected are shown as Waiting For Review, but still had rejections against them in the detail page.
The NSWorkspace.shared.desktopImageURL
method is useful for getting the currently active desktop wallpaper, but for dynamic wallpapers it just returns the HEIC file, which contains all the images, but there's no way to know which of those images are currently being shown on the desktop.
Steps to Reproduce:
NSWorkspace.shared.desktopImageURL(for: NSScreen.main!)
in Playground.Expected Results:
I expected there to be a way to get the currently shown image of a dynamic wallpaper.
This is important for being able to imitate the desktop, for example, for hiding the desktop icons momentarily while doing a screen recording.
Actual Results:
There no way to find this out, which makes the NSWorkspace.shared.desktopImageURL
method not reliable in all cases, even less when dynamic wallpapers gets popular.
Notes:
Relevant GitHub issue: sindresorhus/macos-wallpaper#17
The description of the method is:
Returns the URL for the desktop image for the given screen.
But the API sometimes return the URL to the directory of the active wallpaper image. This should either be fixed or the docs should be amended. Preferably fixed.
Steps to Reproduce:
NSWorkspace.shared.desktopImageURL(for: NSScreen.main!)
in Playgrounds.Expected Results:
I expected it to return the URL to the active wallpaper image, even when the "Change picture" option is enabled.
Actual Results:
It returns the URL the directory of images, not the active wallpaper image.
Notes:
Because of this, there's no way to always reliably get the active wallpaper, which makes the method pretty useless. Currently, I have a hack in place that reads the value directly from the SQLite database 0 used to store it, but that could break at anytime.
Relevant GitHub issue: sindresorhus/macos-wallpaper#7
The new screenshot UI in Mojave works great, however, the UX for sharing the screenshot could be better. When you right-click the floating screenshot window 1, you get a menu with some actions, for example, "Open in Photos", but these are hard-coded to just a few Apple apps. It would be much more useful for users if it had a "Open With" menu (like when right-clicking a file in Finder). That way the user could quickly open the screenshot in any third-party app. It would also be useful for users if they could share the screenshot right away with a system "Share" menu instead of first having to open the Quick Look preview and then clicking the share button there.
Steps to Reproduce:
Take a screenshot and then right-click the floating screenshot window at the bottom-right of the screen.
Expected Results:
I expected this menu to have a "Open With" and "Share" menu item.
Actual Results:
It doesn't, so sharing a screenshot with a service or editing it further in a third-party app becomes harder.
Notes:
Relevant GitHub issue: sindresorhus/Gifski#62
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.