Posts

Post not yet marked as solved
2 Replies
1.1k Views
Can anyone tell me how to retrieve all Finder tags, including user ones that may have been synced from iCloud?
Posted Last updated
.
Post not yet marked as solved
0 Replies
703 Views
I have an app where each item in an NSTableView contains an NSMetadataQuery, to listen for updates to image files that contain the keyword associated with the item. If I write the keywords to, RAW files, everything works as expected and the number label in the row gets updated correctly. However, if I write the keywords to XMP sidecar files, the NSMetadataQueryDidFinishGathering callback isn't called enough times and the count of files affected isn't updated correctly. What is more, the number returned on the final call to the callback seems to vary depending on the time of day, weather, etc Here is the code that I have used to create the predicate for finding keywords in XMP files…       let xmpFileTypePredicate = NSPredicate(fromMetadataQueryString: "kMDItemKind = \"XMP sidecar*\"cdwt")!       let xmpKeywordPredicate = NSPredicate(fromMetadataQueryString: "kMDItemTextContent = \"<rdf:li>\(keyword)</rdf:li>\"cdw")!       let xmpKeywordsMetadataQueryPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [xmpFileTypePredicate, xmpKeywordPredicate]) Can anyone give me any ideas?
Posted Last updated
.
Post not yet marked as solved
1 Replies
450 Views
Is there any way to retrieve the list of Finder Tags now that the SyncedPreferences option is no longer available for Monterey?
Posted Last updated
.
Post not yet marked as solved
0 Replies
963 Views
I have a long established app that uses a threadsafe var to protect an array of URLs from concurrency races, etc… class ThreadsafeVar<T> {   private var value = Optional<T>.none      func callAsFunction() -> T?   {     queue.sync(flags: .barrier) { [unowned self] in value }   }      func set(_ value: T?)   {     queue.async(flags: .barrier) { [unowned self] in self.value = value }   } } What I want to do is substitute an Actor, which I understand will be intrinsically threadsafe. So, I wrote one like this… actor UrlManager {   private var value = [URL]()   func callAsFunction() -> [URL]   {     value   }   func set(_ value: [URL])   {     self.value = value   } } The calling code is in one of four classes, all of which implement a protocol, which contains a read-write var… protocol FolderProtocol { …   var fileURLs: [URL] { get set } } In this particular class, the var is implemented as read-only…   private var urls = ThreadsafeVar<[URL]>()   var fileURLs: [URL]   {     get     {       urls()?.sorted(using: .finder, pathComponent: .fullPath) ?? []     }     set { }   } … the private var being updated from a metadata updating notification handler. Calling the set(_:[URL]) method on the actor poses no problem…       Task { await urls.set(foundURLs) } But, no matter what I try - continuation, try, await, etc, I don't seem to be able to read back the array of URLs from the actor's callAsFunction() method. The fileURLs var is called on the main thread in response to NSCollectionView delegate methods. Other implementing classes don't need the concurrency management as they are fixed once and never changed. Can anyone help me with this one?
Posted Last updated
.
Post not yet marked as solved
0 Replies
1k Views
Greetings allI have an app whose development language is French, which is also its base localization. I also localise it to English.The app makes use of both location services and the calendar.I have created an InfoPlist.strings file and localized both NSCalendarsUsageDescription and NSLocationWhenInUseUsageDescription.My problem is that, although the Base localization (French) of NSCalendarsUsageDescription is correctly used when requesting permission, I can only ever see the French text for NSLocationWhenInUseUsageDescription if I remove the key from the English version of InfoPlist.strings.Many thanks for any help you can give me.
Posted Last updated
.
Post not yet marked as solved
1 Replies
916 Views
I have an NSCollectionView which is showing thumbnails of images and I have just switched to using QLThumbnailGenerator to fetch them. There are over 6,000 possible images that can be viewed and, if I scroll too fast, I start to get the wrong thumbnails returned from the generator. Is this a bug, or is there something I can do to fix this? Here is the code that is written inside the NSCollectionViewItem derived class…   var request: QLThumbnailGenerator.Request?      func loadImage()   {     if imageView?.image != NSImage(imageLiteralResourceName: "Placeholder")     {       return     }          request = QLThumbnailGenerator.Request(fileAt: url!, size: imageSize, scale: 1.0, representationTypes: [.lowQualityThumbnail])        QLThumbnailGenerator.shared.generateBestRepresentation(for: request!)     {       (thumbnail: QLThumbnailRepresentation?, error: Error?) -> Void in              if let request = self.request       {         QLThumbnailGenerator.shared.cancel(request)       }              DispatchQueue.main.async       {         [unowned self] in                  if self.imageView?.image != NSImage(imageLiteralResourceName: "Placeholder")         {           return         }                  let transition = CATransition()                  transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)                  transition.duration = 0.3                  imageView?.layer?.add(transition, forKey: nil)                  imageView?.image = thumbnail?.nsImage         …
Posted Last updated
.
Post not yet marked as solved
0 Replies
534 Views
Is it possible to change the background colour of an RTF file shown in NSHelpManager to match dark mode?
Posted Last updated
.
Post not yet marked as solved
3 Replies
1.2k Views
I need to monitor a file for when its metadata changes. I'm using the following code I found. final class FileMonitor {   let url: URL   var fileHandle: FileHandle?   var source: DispatchSourceFileSystemObject?   var didReceiveChanges: (() - Void)?   func process(event: DispatchSource.FileSystemEvent)   {     print(String(describing: event))     didReceiveChanges?()   }   func eventHandler()   {     let event = self.source!.data     process(event: event)     createDispatchSource()   }   func createDispatchSource()   {     self.fileHandle = try? FileHandle(forReadingFrom: url)     source = DispatchSource.makeFileSystemObjectSource(fileDescriptor: fileHandle!.fileDescriptor, eventMask: [.attrib], queue: DispatchQueue.main)     source!.setEventHandler(handler: eventHandler)     source!.setCancelHandler     {       self.fileHandle!.closeFile()     }     source!.resume()   }   init(url: URL) throws   {     self.url = url     createDispatchSource()   }   deinit   {     source!.cancel()   } } The problem is that I am getting nearly 7,000 notifications every time a change is detected, which is causing the CPU to get rather warm. This subject seems to be very poorly documented and after days searching, I don't seem to be able to make things any better. Any ideas please? Joanna
Posted Last updated
.
Post not yet marked as solved
3 Replies
1.8k Views
I have a macOS storyboard with a main Window/View Controller and a couple of "accessory" view controllers that are shown via segues from buttons. The problem is, even having set the restoration ID of both controllers in the storyboard, that they always start at the same position, even if they have been moved. Can anyone help me to get them to reopen in the same place they were when they were closed?
Posted Last updated
.
Post not yet marked as solved
1 Replies
613 Views
I have just spent an amusing hour or two trying to track down why my app couldn't find a certain subfolder of a folder I had already enumerated. In the end I found that subpathsOfDirectory wasn't finding some folders, whereas, in the end, I found using subpaths correctly listed all subfolders. Any ideas why?
Posted Last updated
.
Post not yet marked as solved
0 Replies
611 Views
I have created a wrapped NSTextField to allow for keystroke validation. class ValidatableTextField: NSTextField, NSTextViewDelegate {   var validationClosure: ((ValidatableTextField, NSRange, String?) -> Bool)?   func textView(_ textView: NSTextView, shouldChangeTextIn affectedCharRange: NSRange, replacementString: String?) -> Bool   {     return validationClosure?(self, affectedCharRange, replacementString) ?? true   } } struct CurrencyTextField<rootT : AnyObject, valueT> : NSViewRepresentable {   private var object: rootT?   private var keyPath: ReferenceWritableKeyPath<rootT, valueT>?     func makeCoordinator() -> Coordinator   {     return Coordinator(object, keyPath: keyPath)   }   init(object: rootT?, keyPath: ReferenceWritableKeyPath<rootT, valueT>?)   {     self.object = object     self.keyPath = keyPath   }   func makeNSView(context: Context) -> ValidatableTextField   {     let textField = ValidatableTextField()     textField.validationClosure = context.coordinator.validationClosure        return textField   }   func updateNSView(_ nsView: ValidatableTextField, context: Context)   {     guard let object = object,           let keyPath = keyPath else     {       return     }     nsView.stringValue = "\(object[keyPath: keyPath])"   }   class Coordinator : NSObject   {     var object: rootT?     var keyPath: ReferenceWritableKeyPath<rootT, valueT>?     init(_ object: rootT?, keyPath: ReferenceWritableKeyPath<rootT, valueT>?)     {       self.object = object       self.keyPath = keyPath     }     lazy var validationClosure: ((ValidatableTextField, NSRange, String?) -> Bool) =     {       textField, range, replacementString in       if replacementString!.isEmpty       {         return true       }       return replacementString?.contains(where:       {         (char: Character) -> Bool in         return char.isNumber || String(char) == Locale.autoupdatingCurrent.decimalSeparator       }) ?? false     }   } } struct ContentView: View {   @ObservedObject var person: Person   var body: some View   {     VStack     {       Spacer()       Text(person.name)       HStack       {         Spacer(minLength: 100)         CurrencyTextField<Person, Double>(object: person, keyPath: \.bankBalance)         Text("\(person.bankBalance)")         Spacer(minLength: 100)       }       Button(action:       {         self.person.bankBalance = 65.43       })       {         Text("Change bank balance")       }       Spacer()     }   } } My problem is that I am setting the bankBalance property on the Person and the Text next to the TextField is being updated but my CurrencyTextField is not. I may have 30 years of programming experience, including quite a few with Swift but SwiftUI, beyond the simplest of examples, is proving a bit difficult. What am I missing here please?
Posted Last updated
.
Post not yet marked as solved
1 Replies
461 Views
I have some code that calls an external library asynchronously to read EXIF keywords from image files : &#9;func readKeywords() &#9;{ &#9;&#9;keywordsForSelectedItems.removeAll() &#9;&#9; &#9;&#9;let group: DispatchGroup = .init() &#9;&#9; &#9;&#9;let queue: DispatchQueue = .init(label: "com.keywords") &#9;&#9; &#9;&#9;collectionView.selectionIndexPaths.forEach &#9;&#9;{ &#9;&#9;&#9;indexPath in &#9;&#9;&#9; &#9;&#9;&#9;let item = self.collectionView.item(at: indexPath) as! CollectionViewItem &#9;&#9;&#9; &#9;&#9;&#9;let url = item.url! &#9;&#9;&#9; &#9;&#9;&#9;group.enter() &#9;&#9;&#9; &#9;&#9;&#9;queue.async(group: group) &#9;&#9;&#9;{ &#9;&#9;&#9;&#9;do &#9;&#9;&#9;&#9;{ &#9;&#9;&#9;&#9;&#9;try ExifReader.keywords(for: url) &#9;&#9;&#9;&#9;&#9;{ &#9;&#9;&#9;&#9;&#9;&#9;keywords in &#9;&#9;&#9;&#9;&#9;&#9; &#9;&#9;&#9;&#9;&#9;&#9;if let keywords = keywords, &#9;&#9;&#9;&#9;&#9;&#9;&#9; keywords.count > 0 &#9;&#9;&#9;&#9;&#9;&#9;{ &#9;&#9;&#9;&#9;&#9;&#9;&#9;self.keywordsForSelectedItems.append(keywords) &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9; &#9;&#9;&#9;&#9;&#9;&#9;group.leave() &#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;catch &#9;&#9;&#9;&#9;{ &#9;&#9;&#9;&#9;&#9;print(error.localizedDescription) &#9;&#9;&#9;&#9;} &#9;&#9;&#9;} &#9;&#9;} &#9;&#9;group.notify(queue: .main) &#9;&#9;{ &#9;&#9;&#9;let firstValue: [String]? = self.keywordsForSelectedItems.first &#9;&#9;&#9;{ &#9;&#9;&#9;&#9;keywords in &#9;&#9;&#9;&#9; &#9;&#9;&#9;&#9;keywords.count > 0 &#9;&#9;&#9;} &#9;&#9;&#9;&#9; &#9;&#9;&#9;if firstValue != nil &#9;&#9;&#9;{ &#9;&#9;&#9;&#9;let keywords = self.keywordsForSelectedItems.reduce(Set(firstValue!)) &#9;&#9;&#9;&#9;{ &#9;&#9;&#9;&#9;&#9;result, item in &#9;&#9;&#9;&#9;&#9; &#9;&#9;&#9;&#9;&#9;result.union(item) &#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9; &#9;&#9;&#9;&#9;self.tokenView.objectValue = keywords.sorted() &#9;&#9;&#9;} &#9;&#9;} &#9;} Before I added this code, everything worked fine and images were displayed perfectly in a CollectionView. But, since adding this code, as soon as this code has been called, the CPU fan starts to run, anywhere up to 1000% at times and it can block other asynchronous processes that normally load images in the background. Anyone got any ideas?
Posted Last updated
.
Post not yet marked as solved
2 Replies
812 Views
I have an NSCollectionView, whose items contain an image which is created with QLThumbnailImageCreate.Everything was working fine until I added in the ability to preview items using QLPreviewPanel.As long as I don't invoke the QLPreviewPanel, I can reloadData() on the CollectionView without any problem but, as soon as I have invoked the QLPreviewPanel and hidden it again, calling reloadData() causes a slew of warnings to the effect of:[QL] QLError(): Asking to compute a thumbnail in main thread is potentially blocking the user interface… for every item in the collection view.Here is the code I have added to the ViewController :extension ViewController : QLPreviewPanelDataSource { public override func acceptsPreviewPanelControl(_ panel: QLPreviewPanel!) -&gt; Bool { return true } public override func beginPreviewPanelControl(_ panel: QLPreviewPanel!) { panel.dataSource = self } override func endPreviewPanelControl(_ panel: QLPreviewPanel!) { panel.dataSource = nil } func numberOfPreviewItems(in panel: QLPreviewPanel!) -&gt; Int { return selectedItems.count } func previewPanel(_ panel: QLPreviewPanel!, previewItemAt index: Int) -&gt; QLPreviewItem! { return selectedItems[index].url! as QLPreviewItem } }All in all, this API is very poorly documented. Anyone got any ideas?
Posted Last updated
.
Post not yet marked as solved
6 Replies
1.2k Views
I am writing an app that can be sent multiple URLs, either by another app sending those URLs, or by someone selecting them in Finder and clicking "Open with…".Here is the code that receives the URLs :@NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { func application(_ application: NSApplication, open urls: [URL]) { DataProvider.clear() for url in urls { DataProvider.addURL(url) } NotificationCenter.default.post(name: .onDataLoaded, object: nil) }The problem I have is that not all of the URLs are received at the same time, therefore, clearing the DataProvider down as I would want to do after each drop, gets called part way through a single drop.e.g. I send 9 URLs but only 5 get processed in one call, followed by the other 4 in another call.I'm guessing this has something to do with asynchronous handling but, apart from setting up a timer to delay clearing DataProvider in the case of a second drop within a given timespan, I'm at a bit of a loss to solve this problem.Anyone got any better ideas please?
Posted Last updated
.
Post not yet marked as solved
3 Replies
995 Views
Greetings.I have run up against another generic brick wall, so to speak.I have a generic class:class Thing&lt;ownerT&gt; { private var owner: ownerT init(owner: ownerT) { self.owner = owner } }Now I would like to use that type inside a generic protocol:protocol Owner { var thing: Thing&lt;Self&gt; { get set } }Next, I would like to implement that protocol in a hierarchy of classes, such that the "owner" passed to the generic class is the current subclass:class Base : Owner { var thing: Thing&lt;Self&gt; // meant to allow use of Derived but obviously this won't compile } class Derived : Base { }Problem 1: the use of Self in the protocol makes its compulsory to use a final class to implement the protocol.Problem 2: derived classes need to use Thing&lt;…&gt; as if it belonged to their concrete type, not Base.Any bright ideas how I can get Derived to see Thing ?If this were C#, I could bind the generic type to something akin to type(of: self)But this is Swift and I am struggling with the lack of dynamicism
Posted Last updated
.