Posts

Post marked as solved
1 Replies
983 Views
Got a frustrating problem. I've created two separate views (and view models) for my app, one to use in portrait mode, the other to take advantage of the extra horizontal space in landscape. In both view models, I have a bool called usingClock.   @Published var usingClock: Bool = false and in my view, I set the opacity of this clock depending on this bool... Text(vm.isRunning ? vm.formatTime() : "0")               .font(.system(.title2, design: .monospaced))               .fontWeight(.black)               .frame(width: 90, height: 40)               .background(.thinMaterial)               .cornerRadius(20)               .overlay(RoundedRectangle(cornerRadius: 20)                     .stroke(Color.gray, lineWidth: 2))               .opacity(vm.usingClock ? 1.00 : 0.00) what is crazy is that in my portrait mode, this works. I change the setting of the bool, and the view automatically updates. but in the landscape mode, it doesn't work. I change the setting of the bool, and the view does not update. but if I simply re-orient the phone (simulator) to portrait and then back to landscape, now the view is correct. I can't for the life of me figure out why the exact same code works in portrait mode, regardless of me changing the orientation, and why in landscape mode it doesn't work until I rotate the phone. I've even placed print statements showing that in my view model the bool turns false (say) and then in my view, it prints as true. Then simply reorient the phone, and now both print statements are false. Like what???? Any ideas why this is happening? This code is not that complicated.
Posted
by maark6000.
Last updated
.
Post not yet marked as solved
1 Replies
611 Views
Hi all, fairly new to SwiftUI, I'm following a sound manager class recipe, and it works fine if I just want to play one sound at a time, but now in the app I'm working on I need the sounds to overlap each other sometimes, and the singleton I'm using can't seem to do that. I'm not sure if it's the instance of the class, or the instance of the AVAudioPlayer that's the problem. Here is the code I'm using... import Foundation import AVKit class SoundManager {       static let instance = SoundManager()       var player: AVAudioPlayer?       func playMySound() {           guard let url = Bundle.main.url(forResource: "mySound", withExtension: ".wav") else { return }           do {       player = try AVAudioPlayer(contentsOf: url)       player?.play()     } catch let error {       print("Error playing sound. \(error.localizedDescription)")     }         } // each additional sound is another func like above. I've poked around on SO and other places looking for better code examples, but nothing I have found works. Any help would be appreciated! Thanks!
Posted
by maark6000.
Last updated
.
Post not yet marked as solved
1 Replies
889 Views
Hi all, I have a picker populated by an enum... works just fine. Problem is when I try to localize my app, I get a compiler error in my picker that says "Instance method 'tag' requires that 'LocalizedStringKey' conform to 'Hashable'". I don't understand what this means. Here is my code: localizable string file (excerpt) //eng "additionOnly" = "Addition Only"; "subtractionOnly" = "Subtraction Only"; "both" = "Both Addition and Subtraction"; // in VM:   enum MathMode: String, Hashable, CaseIterable {     case additionOnly = "additionOnly"     case subtractionOnly = "subtractionOnly"     case bothAdditionAndSubtraction = "both"           var localizedName: LocalizedStringKey { LocalizedStringKey(rawValue) }   }    @Published var selectedMode: String = UserDefaults.standard.string(forKey: "mathMode") ?? "Addition Only" {     didSet {       UserDefaults.standard.set(self.selectedMode, forKey: "mathMode")       print("portrait mode did set: \(selectedMode)")     }   } //in View: Menu {             Picker(selection: $settingsViewViewModel.selectedMode) {               ForEach(SettingsViewViewModel.MathMode.allCases, id: \.self) { mathMode in                 Text(mathMode.localizedName)                   .tag(mathMode.localizedName) //***               }             } label: {}           } label: {             Text(settingsViewViewModel.selectedMode)               .font(.title2)           }           .id(settingsViewViewModel.selectedMode) *** this is the problem. if I use mathMode.rawValue... the code compiles, but in the picker I'm seeing "additionOnly" as my choice, rather than the value from the string file. If there's a better way to write all this, great, happy to change. Also, if I do away with the .tag altogether it still doesn't work. Thanks for your help.
Posted
by maark6000.
Last updated
.
Post marked as solved
5 Replies
4.7k Views
I am really struggling to find how one creates a file that doesn't already exist in Objective-C, and then use that file write data. In C, one uses a fopen command, usually wrapped in an if statement to catch a failure...if ((file_pointer = fopen(file_name, "wb")) == NULL) { fprintf(stderr, "could not create file.\n"); exit(EXIT_FAILURE);}You have created a file, and you have a file_pointer to use as you write data to your file ... fprintf(file_pointer, %d, someInt); So easy.With Objective-C and Xcode... I'm already getting the feeling like there's many ways to skin a cat... but I can't get any of them to work for me.I see some people use an NSData method...BOOL written = [dataBuffer writeToFile:destinationPath options:0 error:NULL]; //assumes a NSData file *dataBuffer and NSString *destinationPath.But this doesn't work, no file is actually created.I also tried:NSFileHandle *file;NSData *data = [...file = [NSFileHandle fileHandleForUpdatingAtPath: @"/tmp/filename.xyz"];[file writeData: data];But this also failed to create a file. There also seems to be a whole other trajectory using NSFileManager and a "createFileAtPath" method, which I ALSO could not get to work. HELP! What am I missing?
Posted
by maark6000.
Last updated
.
Post not yet marked as solved
0 Replies
199 Views
I have an app that can save JSON data to a file, using try jsonData.write(to: fileURL, options: .atomic) Right now, that file's type when viewed in the finder is a TextEdit type. Not sure why, maybe that's a default. I'd like to be able to set the file's type as something other than TextEdit. Ideally create my own file type, but at least mark it as JSON data. How can I do this? I tried fiddling around with .appendingPathExtension but this does not seem like a road that leads to what I'm after. I'd love to just to be able to subclass enough of NSDocument to do this... but I can't figure out how. NSDocument class hides so much of its code I can't figure out how it works. Actually what I'd really like is to see how NSDocument saves the file as a particular type... if I could find that code and use it while saving my data file, that'd be the best scenario.
Posted
by maark6000.
Last updated
.
Post not yet marked as solved
1 Replies
301 Views
I feel like there about seven people on this planet that understand the Field Editor in a macOS app. I'm hoping you're one of those seven. I have an app that has a AVPlayerView, which as you know uses the space bar to play. When I click in a textField (also in the app), I'd like to offer the user the opportunity to abandon editing in the textField and put the focus back on AVPlayerView. I have scoured the internet for this information, looked at the myriad textfield/view delegates... I don't think anyone has ever escaped the death grip of the field editor. Is there a way? Apple documentation seems to hint at it, but naturally doesn't explain how one might accomplish this. Quite a few SO attempts at it, but none work. Any ideas?
Posted
by maark6000.
Last updated
.
Post not yet marked as solved
3 Replies
355 Views
I'm trying to figure out how these stock menus and menu items work. They seem to be controlled by some hidden code somewhere. If someone closes the app's main window, for whatever reason... you would want to present them with the opportunity to open a new window. But the "new" menu item is grayed out after the close is performed... and I can't figure out where the code for that is coming from or how I can alter it. Also, is there a way I can see the code for things like save, open, save as, revert to saved, etc.? Thanks for the help.
Posted
by maark6000.
Last updated
.
Post not yet marked as solved
1 Replies
330 Views
I have a fairly simple document app with a tableView... using MVVM... can't figure out how to get my data to the Document class so that it can be saved / loaded. I'm not listing the Document class here because it's the exact boilerplate that comes with a document app. As you can see right now my data is saved in the ViewModel... the array called "notes." That's what I want to save... perhaps by using JSON or maybe NSKeyedArchiver, not sure what's best. I just don't know how to have access from the Document class to the notes array. I've looked a little at representedObject but it's so confusing... any help would be much appreciated. Model: import Foundation struct Note: Codable {       var timecodeIn: String   var timecodeOut: String   var note: String   var comment: String       init(timecodeIn: String, timecodeOut: String, note: String, comment: String) {     self.timecodeIn = timecodeIn     self.timecodeOut = timecodeOut     self.note = note     self.comment = comment   } } View Model: import Foundation class ViewModel: NSObject, Codable {       // MARK: - Properties       var notes = [Note]() //this ultimately is the array I want saved.&#9;Maybe it doesn't go here?       // MARK: - Init       override init() {     super.init()   }       // MARK: - Public Methods     //set note   func setNote(note: Note) -> Void {     notes.append(note)   }           //delete 1 note   func deleteNote(atIndex index: Int) {     notes.remove(at: index)   }       //delete <1 notes   func deleteNotes(atIndexSet set: IndexSet) {     var count = 0     for index in set {       notes.remove(at: (index - count))       count += 1 //funky, but it works!     }   } } View Controller: import Cocoa class ViewController: NSViewController {       // MARK: - IBOutlet Properties    ...   // MARK: - Properties       var viewModel = ViewModel()       // MARK: - View Controller Lifecycle       override func viewDidLoad() {     super.viewDidLoad()     tableView.delegate = self     tableView.dataSource = self   }   override var representedObject: Any? {     didSet {             }   }       override func viewWillAppear() {     super.viewWillAppear()     tableView.reloadData()   }           // MARK: - IBAction Methods       @IBAction func addNote(_ sender: NSButton)   {     ...     viewModel.setNote(note: tempNote)     tableView.reloadData()   }       @IBAction func removeNote(_ sender: NSButton)   {     ...       viewModel.deleteNotes(atIndexSet: tableView.selectedRowIndexes)        } }   // MARK: - ViewController extensions extension ViewController: NSTableViewDataSource {   func numberOfRows(in tableView: NSTableView) -> Int {     return viewModel.notes.count   } } extension ViewController: NSTableViewDelegate {    ... }
Posted
by maark6000.
Last updated
.
Post not yet marked as solved
10 Replies
2.2k Views
macOS - I'm subclassing AVPlayerView to create my own keyDown functionality... I need to get the keyDown data from my AVPlayerView subclass to my viewController. Using delegate / protocol (although seriously thinking of abandoning it for NSNotification or something else). Here's what I have so far: class ViewController: NSViewController, ReceiveKeyDownData { var customPlayerView: CustomAVPlayerView? override func viewDidLoad() {     super.viewDidLoad() customPlayerView?.keyboardDelegate = self } func receiveKeyboardData(data: UInt16) {     print("from VC: \(data)") //this does not work!    } } protocol ReceiveKeyDownData: class {   func receiveKeyboardData(data: UInt16) } class CustomAVPlayerView : AVPlayerView {       weak var keyboardDelegate: ReceiveKeyDownData?       override var acceptsFirstResponder: Bool {       get {         return true       }     }       override func keyDown(with event: NSEvent) {     if self.superview != nil     {       print("from PlayerView: \(event.keyCode)") // this works!       self.keyboardDelegate?.receiveKeyboardData(data: event.keyCode)     }    }     } This follows the pattern I have seen in many internet delegate / protocol tutorials. I suspect that perhaps when I'm saying "var customPlayerView: CustomAVPlayerView?" that I'm instantiating ANOTHER PlayerView, not the one I already have. ??? Or, there is something about it being optional? For example, if I change the var to let, I get an error saying I have no initializers. I have tried creating initializers, and I'm just LOST. I don't even know what I'm trying to initialize... the delegate? It leads down this path of "required inits" and super.inits and it's just an unholy mess. Super frustrating. Guidance?
Posted
by maark6000.
Last updated
.
Post not yet marked as solved
1 Replies
399 Views
Trying to customize AVPlayerView. Right now, J plays the video backwards, L plays it forwards. For the app I'm making, I'd like to disable these keys. I thought the way to do this would be to subclass AVPlayerView. I found some code that allowed me to disable the scrollwheel, and it works. But when I try to use almost the same code to disable (in this case) the J key, the J key still plays the video backwards. Any idea what I should try? Thanks. code so far: (I have this as a second class in my viewController file.) class CustomAVPlayerView : AVPlayerView {   override func scrollWheel(with event: NSEvent)   {     if self.superview != nil     {       self.nextResponder?.scrollWheel(with: event)     }   }       override func keyDown(with event: NSEvent) {     if self.superview != nil     {       if event.keyCode == 38       {         self.nextResponder?.keyDown(with: event)       }     }   }         }
Posted
by maark6000.
Last updated
.
Post not yet marked as solved
1 Replies
373 Views
I'm so close here... I think I need to set my root VC as the delegate to the popover but I don't know how or even WHERE to do that. Storyboard: separate view controller, modal segue is dragged from menu item to VC. Popover works. I can get data from my textField, print it from popover's VC. Using a protocol / delegate method to get data back. Here is the code: PopOver VC: //which is a delegate to it's textField as well. protocol ReturnFromPopover {   func setStartTC(timecode: Timecode) // Timecode here is a special class I'm using } class EnterStartTCPopoverVC: NSViewController, NSTextFieldDelegate { var returnProtocol: ReturnFromPopover? func controlTextDidEndEditing(_ notification: Notification) {           printTC(timecode: tempTC) // this works     returnProtocol?.setStartTC(timecode: tempTC)     dismiss(self)   } } Root VC: class ViewController: NSViewController, NSPopoverDelegate, ReturnFromPopover { //instantiate a var called startTC func setStartTC(timecode: Timecode) {     startTC = timecode     print("it worked: \(startTC as Any)")         } } it doesn't crash... but it's not bringing the data back thru the function. Any ideas? Thanks so much for your help.
Posted
by maark6000.
Last updated
.
Post not yet marked as solved
2 Replies
980 Views
programming for macOS, (not iOS), using AVKit Player View which has transport controls built in... I want another part of the app to start a behavior when the user plays a video, and stop it when the user stops the video. How would I do that? I thought I could observe the status, but status turns out only to mean whether the video is loaded and ready to play, or not, very limited in what statuses are available. I looked through the delegate stuff... couldn't find anything. It also seems like AV Player View is the only way to view a video in macOS, am I right about that? If I didn't use a AVKit Player View, what else would I drag into my view controller storyboard to play videos? Thanks!
Posted
by maark6000.
Last updated
.
Post not yet marked as solved
2 Replies
1.7k Views
... following Apple's example. Going off of this tutorial: https://developer.apple.com/documentation/avfoundation/media_playback_and_selection/creating_a_basic_video_player_macos I have dragged into the storyboard the AVKit Player View, and here is my ViewController code: import Cocoa import AVKit import AVFoundation class ViewController: NSViewController {           @IBOutlet weak var playerView: AVPlayerView!       override func viewDidLoad() {     super.viewDidLoad()           guard let url = URL(string: "linkWasHere") else {         return //could not post actual link due to this forum's security issues, see link above for actual link. ???     }           let player = AVPlayer(url: url)     playerView.player = player   } } here is what the console is outputting when I run this, any idea why this no longer works? 2020-11-01 20:28:31.491145-0800 Player01[13477:15207676] [plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x60000025c420> F8BB1C28-BAE8-11D6-9C31-00039315CD46 2020-11-01 20:28:31.494171-0800 Player01[13477:15207338] CDN - client insert callback function client = 0 type = 17 function = 0x7fff3a9f3246 localolny = false 2020-11-01 20:28:31.494205-0800 Player01[13477:15207338] CDN - client setupremoteport 2020-11-01 20:28:31.494227-0800 Player01[13477:15207338] CDN - Bootstrap Port: 1799 2020-11-01 20:28:31.494332-0800 Player01[13477:15207338] CDN - Remote Port: 36867 (com.apple.CoreDisplay.Notification) 2020-11-01 20:28:31.494366-0800 Player01[13477:15207338] CDN - client setuplocalport 2020-11-01 20:28:31.494385-0800 Player01[13477:15207338] CDN - Local Port: 28419 2020-11-01 20:28:31.524528-0800 Player01[13477:15207676] HALCShellDriverPlugIn::Open: Can't get a pointer to the Open routine 2020-11-01 20:28:31.539261-0800 Player01[13477:15207338] Metal API Validation Enabled 2020-11-01 20:28:31.692487-0800 Player01[13477:15207700] startConfigurationWithCompletionHandler: Failed to get remote object proxy: Error Domain=NSCocoaErrorDomain Code=4097 "connection to service on pid 0 named com.apple.rtcreportingd" UserInfo={NSDebugDescription=connection to service on pid 0 named com.apple.rtcreportingd} 2020-11-01 20:28:31.692614-0800 Player01[13477:15207700] startConfigurationWithCompletionHandler: Failed to get remote object proxy: Error Domain=NSCocoaErrorDomain Code=4097 "connection to service on pid 0 named com.apple.rtcreportingd" UserInfo={NSDebugDescription=connection to service on pid 0 named com.apple.rtcreportingd} 2020-11-01 20:28:31.712175-0800 Player01[13477:15207701] dnssdclientstub ConnectToServer: connect() failed path:/var/run/mDNSResponder Socket:11 Err:-1 Errno:1 Operation not permitted 2020-11-01 20:28:31.712371-0800 Player01[13477:15207701] [] nwresolvercreatednsservicelocked [C1] DNSServiceCreateDelegateConnection failed: ServiceNotRunning(-65563) 2020-11-01 20:28:31.712656-0800 Player01[13477:15207701] Connection 1: received failure notification 2020-11-01 20:28:31.716191-0800 Player01[13477:15207701] Connection 1: failed to connect 10:-72000, reason -1 2020-11-01 20:28:31.716310-0800 Player01[13477:15207701] Connection 1: encountered error(10:-72000) 2020-11-01 20:28:31.716980-0800 Player01[13477:15207700] Task <4869798A-2285-4453-8ED6-D7F3DA7E2758>.<1> HTTP load failed, 0/0 bytes (error code: -1003 [10:-72000]) 2020-11-01 20:28:31.718743-0800 Player01[13477:15207718] Task <4869798A-2285-4453-8ED6-D7F3DA7E2758>.<1> finished with error [-1003] Error Domain=NSURLErrorDomain Code=-1003 "A server with the specified hostname could not be found." UserInfo={kCFStreamErrorCodeKey=-72000, NSUnderlyingError=0x600000cbf6f0 {Error Domain=kCFErrorDomainCFNetwork Code=-1003 "(null)" UserInfo={kCFStreamErrorCodeKey=-72000, kCFStreamErrorDomainKey=10}}, NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <4869798A-2285-4453-8ED6-D7F3DA7E2758>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=(   "LocalDataTask <4869798A-2285-4453-8ED6-D7F3DA7E2758>.<1>" ), NSLocalizedDescription=A server with the specified hostname could not be found., NSErrorFailingURLStringKey=https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_ts/master.m3u8, NSErrorFailingURLKey=https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_ts/master.m3u8, _kCFStreamErrorDomainKey=10} 2020-11-01 20:28:31.719376-0800 Player01[13477:15207676] sendMessageWithDictionary: Failed to get remote object proxy: Error Domain=NSCocoaErrorDomain Code=4097 "connection to service on pid 0 named com.apple.rtcreportingd" UserInfo={NSDebugDescription=connection to service on pid 0 named com.apple.rtcreportingd}
Posted
by maark6000.
Last updated
.
Post marked as solved
3 Replies
375 Views
code as follows, can't access the "contents" var in the struct (see line 37). what am i doing wrong? thank you! import Cocoa class Food {   var name: String       init?(name: String) {     if name.isEmpty { return nil }     self.name = name   }     } class Fruit : Food {       var color: String       init?(name: String, color: String) {     self.color = color     super.init(name: name)   }     } struct Bowl {   var contents: Fruit?   var quantity: Int } var toast = Food(name: "toast") var banana = Fruit(name: "banana", color: "yellow") var myFruitBowl = Bowl(contents: banana, quantity: 5) print(toast?.name as Any) //works print(banana?.color as Any) //works print(myFruitBowl.contents?.color as Any) //works print(myFruitBowl.quantity as Any) //even this works! print(myFruitBowl.contents as Any) // log: Optional(__lldb_expr_25.Fruit)
Posted
by maark6000.
Last updated
.
Post marked as solved
1 Replies
918 Views
Hi all... building a macOS app that will allow users to gather data from certain areas of a quicktime movie. The user should be able to specify IN and OUT timecodes of what section of the video to examine, and the app should be able to seek to that area and do its work.I thought I was on to the way of doing this by creating a CMTimeRange...``` NSDictionary *options = @{AVURLAssetPreferPreciseDurationAndTimingKey: @YES}; AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoFileURL options:options]; NSError *error; AVAssetReader *assetReader = [AVAssetReader assetReaderWithAsset:asset error:&amp;error]; if (error) { NSLog(@"Error:%@", error.localizedDescription); } AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; AVAssetReaderTrackOutput *trackOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:videoTrack outputSettings:nil]; [assetReader addOutput:trackOutput]; CMTime start = CMTimeMakeWithSeconds(_distanceFromVideoToStart, rate-&gt;fps); //this is the duration to be skipped CMTime duration = CMTimeMakeWithSeconds(_distanceToBeScanned, rate-&gt;fps); //this is the duration to be examined. CMTimeRange range = CMTimeRangeMake(start, duration); [assetReader setTimeRange:range]; [assetReader startReading]; while ((sampleBuffer = [trackOutput copyNextSampleBuffer])) { //gathering video data } ```This sort of works. My main problem is that if the user enters a "start" time 10 seconds into the video... a frame specific calculation needs to be made... if the video is 30fps... we need to skip ahead 300 frames, but at 24fps only 240. I thought that was what I was setting with the CMTime start = function... but perhaps I don't understand how this works? My values would be (for a 30fps video) 300 for start time and 30 fps... my understanding is that the output is A / B... so 300 / 30 is 10 seconds. That doesn't seem to work, I'm having to actually divide my first parameter by the frame rate (300 / 30, 30) in order for it to be close.The other problem as far as I can tell, is that at the moment I'm being returned 24fps values... as if they are a default setting. So when I ask to seek 10 seconds in, it's really only seeking 8.08 seconds in, so the area being examined is incorrect.So, first off... is this the best way to be seeking in a .mov? Next, how can I set the frame rate? And lastly... what am I not understanding about this CMTimeRange? Thanks for taking the time to help me.
Posted
by maark6000.
Last updated
.