Re: WatchKit Baby Apps
Well, let me modify something I just said. If you’re writing an app to show how many days until you reach retirement, WKInterfaceTimer is just the thing to use. It’s not completely useless—it just doesn’t help with the thing you really want, which is notification that the wait is over. On Fri, Mar 2, 2018 at 7:50 AM, Charles Jenkins wrote: > The things you are describing are paths I already followed to dead ends. > WKInterfaceTimer is truly and completely bogus. It just shows a > countdown/count-up UI label while the app is onscreen. You have to pair it > with an NSTimer set to count down to the same time in to make your program > react in any way when the time period elapses. But lower your wrist, and > the app and NSTimer are soon killed. I think WKInterfaceTimer is just there > because someone though it could be used to make a cool demo app, not to use > for any actual purpose. You could use both these objects in a game, when > you’d know the user would be constantly interacting with the game and thus > keeping the app alive. But they’re no good for any non-frivolous use. > > I already described my reason for not trusting local notifications: you > can’t specify that they’ll alert you on the Watch, and you can’t be 100% > sure they’ll alert you at all. What we need is a call to programmatically > set the actual timer used by the Timer app, a way to schedule the app to be > awakened at a specific time so it can play a haptic or do whatever it wants > to get attention, or a way to set a local notification that will definitely > always truly for sure be handled by the watch. WatchKit doesn’t give us > those things because of Apple’s philosophical desire to prevent Watch apps > that annoy the user. The very purpose of a timer is to annoy the user so > he’ll be sure to notice and deal with something, so in my opinion it’s > simultaneously the most useful kind of app you might want to create and > exactly the kind of app WatchKit effectively prevents. > > > On Thu, Mar 1, 2018 at 9:50 PM, J. Scott Tury wrote: > >> Creating a WatchKit app with Timers should be fairly easy. There’s a >> nice interface object called *WKInterfaceTimer* which should do the >> trick - at least for the UI interface. Here’s a link to the >> documentation: >> >> https://developer.apple.com/documentation/watchkit/wkinterfacetimer >> >> You might also be interested in reading the WatchKit Programming Guide. >> It explains that WatchKit apps, are quite different from iOS applications. >> The Interface is running in a separate process from your actual code - >> which is running in a watch extension. >> >> https://developer.apple.com/library/content/documentation/Ge >> neral/Conceptual/WatchKitProgrammingGuide/index.html >> >> Your extension does not run for very long. Apple is extremely aggressive >> about how much time a watch extension will run. Running for a long period >> of time is useful if you are collecting biometric data (heart rate, etc). >> >> A simple Timer application should be doable. One of the challenges will >> be how to tell your user that the timer has finished. The simplest thing I >> can think of is to schedule a *Local Notification*. That should be able >> to get your user’s attention! >> >> Hopefully this helps you move in the right direction. >> >> Scott >> > > > > -- > > Charles > -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: WatchKit Baby Apps
The things you are describing are paths I already followed to dead ends. WKInterfaceTimer is truly and completely bogus. It just shows a countdown/count-up UI label while the app is onscreen. You have to pair it with an NSTimer set to count down to the same time in to make your program react in any way when the time period elapses. But lower your wrist, and the app and NSTimer are soon killed. I think WKInterfaceTimer is just there because someone though it could be used to make a cool demo app, not to use for any actual purpose. You could use both these objects in a game, when you’d know the user would be constantly interacting with the game and thus keeping the app alive. But they’re no good for any non-frivolous use. I already described my reason for not trusting local notifications: you can’t specify that they’ll alert you on the Watch, and you can’t be 100% sure they’ll alert you at all. What we need is a call to programmatically set the actual timer used by the Timer app, a way to schedule the app to be awakened at a specific time so it can play a haptic or do whatever it wants to get attention, or a way to set a local notification that will definitely always truly for sure be handled by the watch. WatchKit doesn’t give us those things because of Apple’s philosophical desire to prevent Watch apps that annoy the user. The very purpose of a timer is to annoy the user so he’ll be sure to notice and deal with something, so in my opinion it’s simultaneously the most useful kind of app you might want to create and exactly the kind of app WatchKit effectively prevents. On Thu, Mar 1, 2018 at 9:50 PM, J. Scott Tury wrote: > Creating a WatchKit app with Timers should be fairly easy. There’s a nice > interface object called *WKInterfaceTimer* which should do the trick - > at least for the UI interface. Here’s a link to the documentation: > > https://developer.apple.com/documentation/watchkit/wkinterfacetimer > > You might also be interested in reading the WatchKit Programming Guide. > It explains that WatchKit apps, are quite different from iOS applications. > The Interface is running in a separate process from your actual code - > which is running in a watch extension. > > https://developer.apple.com/library/content/documentation/ > General/Conceptual/WatchKitProgrammingGuide/index.html > > Your extension does not run for very long. Apple is extremely aggressive > about how much time a watch extension will run. Running for a long period > of time is useful if you are collecting biometric data (heart rate, etc). > > A simple Timer application should be doable. One of the challenges will > be how to tell your user that the timer has finished. The simplest thing I > can think of is to schedule a *Local Notification*. That should be able > to get your user’s attention! > > Hopefully this helps you move in the right direction. > > Scott > -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
WatchKit Baby Apps
Marco Arment’s article at https://marco.org/2018/02/26/watchkit-baby-apps describes how frustrating it is to develop for Apple Watch. I hope Apple takes notice and improves this situation. Last year I wanted to develop my own timer and repetition counter for my workouts at the gym, but in the end it seemed impossible. I don’t know if the situation has now changed, but at the time, there was no way to programmatically set the real timer, and no way to set a label to act as a timer--and convince the OS not to kill your app while it was counting down. The best I could do for a timer was schedule a notification and hope it worked. (Occasionally I have to reboot my phone and watch because apparently they each think the other handled incoming notifications, so neither triggers an alert.) -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: [ANN] Nursery Framework 1.0.1 (build with Xcode 9) released
No, using foreign language words incorrectly is not a surprise. We should not accuse Mr. Takata of doing anything wrong simply on the basis of choosing the wrong words. Translating between English and Japanese is extremely difficult. If you visit Japan, it will not take very long before you see instances of misapplied and even profane English words appearing in print or on clothing. I remember passing one guy in Shibuya, handing out tissues for advertising purposes, which means he had been hired by someone to present himself in public. His shirt said something shocking with the F-word, but I’m sure it raised no eyebrows among the hundreds of people who passed him on the street that day and couldn’t have cared less what the words on his shirt might have meant. If Mr. Takata’s library has something to do with object lifecycles, keeping and spawning objects, it would be no surprise he’d look in the dictionary and find words related to the general topic of "doing things with children”; and since he is not yet fluent, it shouldn’t be a surprise that some of his word choices would be incorrect and unfortunate. You are absolutely right that he should have a fluent speaker look at his code and comment on it. But isn’t that what he asked us to do? Let’s comment on these problems, but be kind when we do. Ganbatte kudasai. On Thu, Oct 26, 2017 at 11:58 AM, Alex Zavatone wrote: > OK. You REALLY need someone who is fluent in English to review the words > you have chosen to use in your library. > > In English, kidnapping means to steal someone against their will and keep > them prisoner. > > Honestly, I hope that this is just another mistake, but really, these are > big mistakes that you need to take seriously if you plan on working with an > English audience. > > If you are serious about your effort, you need to do this immediately. > > I must admit that one incidence of this is unfortunate. Multiple cases of > this almost seems intentional. > > > > > > On Oct 25, 2017, at 8:37 PM, Akifumi Takata wrote: > > > > NUKidnapper > > ___ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com > > This email sent to cejw...@gmail.com > -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Video Player Controls?
This might help. I think it was a free course, but since I'm subscribed, I no longer see the price… https://www.udemy.com/draft/451494/learn/v4/overview On Wed, May 17, 2017 at 8:40 AM, Dave wrote: > Hi, > > Should have said - this is an iOS project. It would be great if I could > just get the same graphics for the controls as the Main Player, I could > easily wire up my own action handlers….. > > Cheers > Dave > > > On 17 May 2017, at 13:14, Charles Jenkins wrote: > > > > If you’re doing your work on the Mac, there’s an available Apple demo, > AVSimplePlayer, which demonstrates how to wire up KVO (in Obj-C) in order > to provide playback controls. I was never able to get it working after > porting to Swift, but it works fine in Obj-C. > > > > On Wed, May 17, 2017 at 7:05 AM, Dave d...@looktowindward.com>> wrote: > > > > Hi All, > > > > (The content of the original message seems to have disappeared!) > > > > I’m using AVPlayer and AVPlayerLayer to play a movie in a view. However > when I do this I lose the Video Playback Controls (Play/Pause/Fast Forward > etc) I get when using AVPlayerViewController. Is there a class to handle > displaying and responding to these controls or do I have to completely roll > my own, with my own graphics etc? > > > > Thanks a lot > > > > All the Best > > Dave > > ___ > > > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com Cocoa-dev@lists.apple.com>) > > > > Please do not post admin requests or moderator comments to the list. > > Contact the moderators at cocoa-dev-admins(at)lists.apple.com < > http://lists.apple.com/> > > > > Help/Unsubscribe/Update your Subscription: > > https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com < > https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com> > > > > This email sent to cejw...@gmail.com <mailto:cejw...@gmail.com> > > > > > > -- > > > > Charles > > ___ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com > > This email sent to cejw...@gmail.com > -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Video Player Controls?
If you’re doing your work on the Mac, there’s an available Apple demo, AVSimplePlayer, which demonstrates how to wire up KVO (in Obj-C) in order to provide playback controls. I was never able to get it working after porting to Swift, but it works fine in Obj-C. On Wed, May 17, 2017 at 7:05 AM, Dave wrote: > > Hi All, > > (The content of the original message seems to have disappeared!) > > I’m using AVPlayer and AVPlayerLayer to play a movie in a view. However > when I do this I lose the Video Playback Controls (Play/Pause/Fast Forward > etc) I get when using AVPlayerViewController. Is there a class to handle > displaying and responding to these controls or do I have to completely roll > my own, with my own graphics etc? > > Thanks a lot > > All the Best > Dave > ___ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com > > This email sent to cejw...@gmail.com -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: AVSimplePlayer in Swift?
er( forInterval: CMTimeMake( 1, 10 ), queue: DispatchQueue.main ) { [weak self] ( time: CMTime ) -> () in let seconds = CMTimeGetSeconds( time ) NSLog( "Periodic time observer asking to set time to \(seconds) seconds" ) if let weakSelf = self { weakSelf.currentTime = seconds } } } } override func observeValue( forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer? ) { if context == &statusContext { // Status changed if let change = change, let statusInt = ( change[ NSKeyValueChangeKey.newKey ] as AnyObject ).integerValue { let status = AVPlayerStatus( rawValue: statusInt ) let enable = ( status == AVPlayerStatus.readyToPlay ) pausePlayButton.isEnabled = enable fastForwardButton.isEnabled = enable rewindButton.isEnabled = enable } } else if context == &rateContext { // Rate changed if let change = change, let rate = ( change[ NSKeyValueChangeKey.newKey ] as AnyObject ).floatValue { let title = ( rate == 1.0 ) ? pauseStr : playStr pausePlayButton.title = title } } else if context == &readyContext { // Ready condition changed playerLayer?.isHidden = false if let item = player.currentItem { self.duration = item.duration.seconds self.currentTime = 0 } } else { // We don't handle this change, but our // parent class might super.observeValue( forKeyPath: keyPath, of: object, change: change, context: context ) } } func close() { player.pause() if let timeObserverToken = timeObserverToken { player.removeTimeObserver( timeObserverToken ) } removeObserver( self, forKeyPath: KeyPath.playerRate ) removeObserver( self, forKeyPath: KeyPath.playerStatus ) if playerLayer != nil { removeObserver( self, forKeyPath: KeyPath.playerLayerReady ) } } func adjustSpeed( step: Float ) { let rate = player.rate if ( step < 0 && rate > step ) || ( step > 0 && rate < step ) { player.rate = step } else { player.rate = rate + step } } @IBAction func rewind( _ sender: Any ) { adjustSpeed( step: -2.0 ) } @IBAction func togglePausePlay( _ sender: Any ) { if player.rate != 1.0 { player.rate = 1.0 if currentTime >= duration { currentTime = 0.0 } player.play() } else { player.pause() } } @IBAction func fastForward( _ sender: Any ) { adjustSpeed( step: 2.0 ) } } On Sun, Jan 8, 2017 at 5:13 PM, Charles Srstka wrote: > On Jan 8, 2017, at 1:12 PM, Quincey Morris rivergatesoftware.com> wrote: > > > On Jan 8, 2017, at 05:49 , Charles Jenkins wrote: > > > changing to CDouble didn’t help > > > This is one of those cases where I regretted pressing “Send” just 2 > minutes later. What I wrote was a thought process that didn’t make complete > sense. > > There are 4 possibilities and you’ll need to narrow it down to one: > > 1. The property type is incorrect. You could try changing it to an > explicit NSNumber, which is the type that the binding actually requires. > > > This is not the problem; KVO works just fine with a property typed as > Double as long as the property is marked ‘dynamic', which my sample code > demonstrates (for some reason, the mailing list software separated the > “.zip” from the rest of the link, so just add “.zip” to the end manually to > download it). > > 2. The property accessors are not using the correct calling convention > (@objc). If they’re in a view controller subclass (which is an @objc) > object, they’ll normally be @objc, but there are some situations (e.g. > declaring them private) that may make them native Swift. Leaving off the > “dynamic” would come under this case too, but this was covered already. > > > 3. The property declaration is fine, but IB is broken and doesn’t > recognize the property as compatible. It may simply fail to set up the > binding properly, even though it would work if it did. You could try > leaving it unbound, and set up the binding at run time. > > 4. The property is fine, and something else is wrong. > > Finally, I’d note that the discussion in this thread had jumped back and > forth between bindings and KVO. I’ve lost track of whether you’re saying > that KVO isn’t working here (Charles posted sample code that he said > works), or whether bindings aren’t working here. > > > I think that seeing a simplified version of the code that isn’t working > would be the easiest way to debug this at this point. OP, would you mind > posting it? > > Charles > > -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: PDF to Word ( docx) Conversion
Just my two cents, but I find .RTF way more arcane than .DOCX, and I don’t think Apple’s exporters for .RTF and .DOC produce high-quality documents. If users are only going to read the documents you produce—they will not be edited or reformatted in any way—then Apple-generated .RTFD (which can include graphics) is probably okay. But if you’re producing something intended to be edited or formatted for publishing, you should seriously consider .DOCX, because with it you can easily define and export powerful styles. I mean, you could also create high-quality .DOC files, but you’d have to use an external package to do it, not the functions Apple provides. On Tue, Jan 24, 2017 at 3:58 PM, Peter Hudson wrote: > Hi Jens > > I wondered about RTF - but I've built everything into a view and I can't > see a method on NSView to produce rtf. > I've done it previously with, I think, an NSText. > > Peter > > > On 24 Jan 2017, at 20:27, Jens Alfke wrote: > > > > > >> On Jan 24, 2017, at 11:54 AM, Peter Hudson wrote: > >> > >> But the bottom line is, I think, to get a Word doc that really behaves > like a > >> Word doc ( in word ) I need to export straight to docx format. > > > > Have you tried exporting to RTF? It’s a simple text-based markup format, > and imports well into Word. (In fact Microsoft invented RTF back in the > ‘80s as an interchange format for Word.) > > > > —Jens > ___ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com > > This email sent to cejw...@gmail.com > -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: PDF to Word ( docx) Conversion
There is an open specification for the file format, which will allow you to easily (if tediously) write your own exporter. The spec is at: http://www.ecma-international.org/publications/standards/Ecma-376.htm (These are huge downloads) If you have access to a Windows PC, there is a Windows-based software development kit INCLUDING an inspector that will let you open and inspect documents. It is invaluable to be able to create a document in Word similar to the one you need to generate, then save and inspect it to see what files actually go inside. Unfortunately the inspector often refuses to open malformed files, so you’ll be using it to see what you need to imitate, not to gauge how far off you are from the mark. Those tools are at: https://www.microsoft.com/en-us/download/details.aspx?id=30425 On Tue, Jan 24, 2017 at 2:54 PM, Peter Hudson wrote: > Hi All > > I have a report that I currently print to PDF. > Its a simple table with text ( varying fonts ) in the table. > > I have tried to convert it to docx with a variety of proprietary > converters. > One or two of them do a reasonable job. > > But the bottom line is, I think, to get a Word doc that really behaves > like a > Word doc ( in word ) I need to export straight to docx format. > > I’ve hunted around - but turned up little. > Does anyone know of a library that could do it ? > > Peter > ___ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com > > This email sent to cejw...@gmail.com -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: AVSimplePlayer in Swift?
I will post code later today. In the meantime, I think I know what’s happening, but not yet why. In short, the IB message is worthless, and KVO is actually working. Ironically, proved that to myself by ditching it altogether and switching currentTime back to using a local (non-computed) property and didSet, but this time, in didSet I imitated the code in the ObjC setCurrentTime() a little more closely. What I found is if I comment out my call to player.seek(), the video plays through and all the controls work (except of course no scrubbing). The count of seconds reported by the periodic time observer (hereafter, PTO) always increases. But if I uncomment the player.seek() line, the video seems to be frozen on the first frame and all the PTO requests are to seek back to 0.0. I think what happens is, the video actually is playing, but the PTO checks when it’s at 0.0, the player internally moves on, and then my KVO or didSet requests a seek back to 0.0. And the process repeats ad infinitum. The PTO is always a tiny bit behind where the video actually is, so it just keeps requesting seeks backward. It appears that if my setter for currentTime does the same thing as the ObjC one, I’m toast. On Sun, Jan 8, 2017 at 5:13 PM, Charles Srstka wrote: > On Jan 8, 2017, at 1:12 PM, Quincey Morris rivergatesoftware.com> wrote: > > > On Jan 8, 2017, at 05:49 , Charles Jenkins wrote: > > > changing to CDouble didn’t help > > > This is one of those cases where I regretted pressing “Send” just 2 > minutes later. What I wrote was a thought process that didn’t make complete > sense. > > There are 4 possibilities and you’ll need to narrow it down to one: > > 1. The property type is incorrect. You could try changing it to an > explicit NSNumber, which is the type that the binding actually requires. > > > This is not the problem; KVO works just fine with a property typed as > Double as long as the property is marked ‘dynamic', which my sample code > demonstrates (for some reason, the mailing list software separated the > “.zip” from the rest of the link, so just add “.zip” to the end manually to > download it). > > 2. The property accessors are not using the correct calling convention > (@objc). If they’re in a view controller subclass (which is an @objc) > object, they’ll normally be @objc, but there are some situations (e.g. > declaring them private) that may make them native Swift. Leaving off the > “dynamic” would come under this case too, but this was covered already. > > > 3. The property declaration is fine, but IB is broken and doesn’t > recognize the property as compatible. It may simply fail to set up the > binding properly, even though it would work if it did. You could try > leaving it unbound, and set up the binding at run time. > > 4. The property is fine, and something else is wrong. > > Finally, I’d note that the discussion in this thread had jumped back and > forth between bindings and KVO. I’ve lost track of whether you’re saying > that KVO isn’t working here (Charles posted sample code that he said > works), or whether bindings aren’t working here. > > > I think that seeing a simplified version of the code that isn’t working > would be the easiest way to debug this at this point. OP, would you mind > posting it? > > Charles > > -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Code Review Requested - In-App Purchases
And of course the second after I posted that, I decided userInterface should be a weak var. On Sun, Jan 8, 2017 at 8:29 AM, Charles Jenkins wrote: > As a programmer, aren’t you suspicious when you write something that works > flawlessly the first time? I worry it just means there’s a disastrous time > bomb. > > In Apple’s documentation about in-app purchases, there’s a lot of talk > about verifying receipts, but when I look at articles and sample code, it > seems payment transactions are all anyone really cares about. And if that’s > so, it seems there are two parts to an in-app store: (1) a “clerk”: code > with no user interface that runs practically all the time to deal with > payment transactions; and (2) a flashy “salesman” with a UI to display > products, make the pitch, and offer buttons the user can click to make the > clerk spring into action. > > With that in mind, I decided to write a single-file, general-purpose clerk > that I could use in any app. It seems to work beautifully, but one thing > surprised me: when I deleted my app, reloaded, and restored purchases, the > payment queue replayed instantly, without asking me to sign in. It went so > smoothly that I’m suspicious. > > So I’m going to share the clerk code with you here and ask for critiques, > if you have time. Thanks! > > // > // InAppStore.swift > // > // Created by Charles Jenkins on 12/25/16. > // Offered into the public domain. > // > > import StoreKit > > // The store user interface implements this protocol > // in order to be notified of updates as the payment > // queue is processed. It should plug itself into > // InAppStore.instance.userInterface when it appears > // and clear the same when it disappears; and should > // react to update() callbacks by displaying results > // reported by InAppStore.instance.latestTransaction. > > protocol InAppStoreUserInterfaceProvider { > func update() > } > > // The app delegate should implement this protocol > // and be able to react to activate() callbacks > // regardless of whether any user interface is on > // display. > > protocol InAppStoreProductActivator { > func activate( transaction: SKPaymentTransaction ) > } > > // Store operations management class > > final class InAppStore : > NSObject, > SKPaymentTransactionObserver > { > > // MARK: - Public Properties > > static let instance = InAppStore() > > // This object's lifetime is far greater than the > // store's UI, so we need to handle all queued > // responses without depending on the store's UI. > // The userInterface variable allows the store UI > // to temporarily plug in and sign up for update > // callbacks. > > var userInterface: InAppStoreUserInterfaceProvider? > > // When the store UI appears or receives update() > // callbacks, it can check the latestTransaction > // variable to determine which elements or messages > // to display. > > var latestTransaction: SKPaymentTransaction? { > get { > forgetExpiredDeferral() > return _latestTransaction > } > set { > _latestTransaction = newValue > } > } > > // Ask if user can make a purchase before calling makePurchase() > > var canMakePurchase: Bool { > return SKPaymentQueue.canMakePayments() > } > > // MARK: - Non-Public Properties > > private var _latestTransaction: SKPaymentTransaction? > > private var productActivator: InAppStoreProductActivator? > > private var queue : SKPaymentQueue { > return SKPaymentQueue.default() > } > > // MARK: - Public Methods > > // Call this function as soon as possible after > // launching the app, so waiting transactions > // can be dealt with immediately. > // > // NOTE: I do this in the app delegate's > // application( _: didFinishLaunchingWithOptions ), > // but first I check user defaults: if all products > // have already been purchased, we'll never show > // the store and we don't need to startObserving() > > func startObserving( productActivator: InAppStoreProductActivator ) > { > NSLog( "Adding payment queue observer" ) > self.productActivator = productActivator > queue.add( self ) > } > > func stopObserving() > { > NSLog( "Removing payment queue observer" ) > queue.remove( self ) > self.productActivator = nil > } > > static public func requestActiveProducts( > productIds: [String], > observer: SKProductsRequestDelegate > ) { > let req = SKProductsRequest( > productIdentifiers: Set( productIds ) > ) >
Code Review Requested - In-App Purchases
As a programmer, aren’t you suspicious when you write something that works flawlessly the first time? I worry it just means there’s a disastrous time bomb. In Apple’s documentation about in-app purchases, there’s a lot of talk about verifying receipts, but when I look at articles and sample code, it seems payment transactions are all anyone really cares about. And if that’s so, it seems there are two parts to an in-app store: (1) a “clerk”: code with no user interface that runs practically all the time to deal with payment transactions; and (2) a flashy “salesman” with a UI to display products, make the pitch, and offer buttons the user can click to make the clerk spring into action. With that in mind, I decided to write a single-file, general-purpose clerk that I could use in any app. It seems to work beautifully, but one thing surprised me: when I deleted my app, reloaded, and restored purchases, the payment queue replayed instantly, without asking me to sign in. It went so smoothly that I’m suspicious. So I’m going to share the clerk code with you here and ask for critiques, if you have time. Thanks! // // InAppStore.swift // // Created by Charles Jenkins on 12/25/16. // Offered into the public domain. // import StoreKit // The store user interface implements this protocol // in order to be notified of updates as the payment // queue is processed. It should plug itself into // InAppStore.instance.userInterface when it appears // and clear the same when it disappears; and should // react to update() callbacks by displaying results // reported by InAppStore.instance.latestTransaction. protocol InAppStoreUserInterfaceProvider { func update() } // The app delegate should implement this protocol // and be able to react to activate() callbacks // regardless of whether any user interface is on // display. protocol InAppStoreProductActivator { func activate( transaction: SKPaymentTransaction ) } // Store operations management class final class InAppStore : NSObject, SKPaymentTransactionObserver { // MARK: - Public Properties static let instance = InAppStore() // This object's lifetime is far greater than the // store's UI, so we need to handle all queued // responses without depending on the store's UI. // The userInterface variable allows the store UI // to temporarily plug in and sign up for update // callbacks. var userInterface: InAppStoreUserInterfaceProvider? // When the store UI appears or receives update() // callbacks, it can check the latestTransaction // variable to determine which elements or messages // to display. var latestTransaction: SKPaymentTransaction? { get { forgetExpiredDeferral() return _latestTransaction } set { _latestTransaction = newValue } } // Ask if user can make a purchase before calling makePurchase() var canMakePurchase: Bool { return SKPaymentQueue.canMakePayments() } // MARK: - Non-Public Properties private var _latestTransaction: SKPaymentTransaction? private var productActivator: InAppStoreProductActivator? private var queue : SKPaymentQueue { return SKPaymentQueue.default() } // MARK: - Public Methods // Call this function as soon as possible after // launching the app, so waiting transactions // can be dealt with immediately. // // NOTE: I do this in the app delegate's // application( _: didFinishLaunchingWithOptions ), // but first I check user defaults: if all products // have already been purchased, we'll never show // the store and we don't need to startObserving() func startObserving( productActivator: InAppStoreProductActivator ) { NSLog( "Adding payment queue observer" ) self.productActivator = productActivator queue.add( self ) } func stopObserving() { NSLog( "Removing payment queue observer" ) queue.remove( self ) self.productActivator = nil } static public func requestActiveProducts( productIds: [String], observer: SKProductsRequestDelegate ) { let req = SKProductsRequest( productIdentifiers: Set( productIds ) ) req.delegate = observer req.start() } func restorePurchases() { // New successful transactions will be sent to the // payment queue to mimic all previously completed // successful transactions, which should trigger // the proper product activations NSLog( "Restore Purchases - Requesting completed transactions" ) self.queue.restoreCompletedTransactions() } func makePurchase( paymentRequest: SKPayment ) { queue.add( paymentRequest ) } // MARK: - Non-Public Methods private func forgetExpiredDeferral() { if let tran = _latestTransaction, let date = tran.transactionDate, tran.transactionState == .deferred { let timePassed = -( date.timeIntervalSinceNow ) let oneDayInSeconds = 60 *
Re: AVSimplePlayer in Swift?
I did try after you asked, and KVO may be working, but the video doesn’t play. If I delete the KVO bindings from IB and change my code like this: var currentTime : Double = 0 { didSet { timeSlider.doubleValue = currentTime } } var duration: Double = 0 { didSet { timeSlider.maxValue = duration } } The video will play and all the buttons will work right. Seriously, *everything* works except I can’t scrub and I haven’t bothered yet to test the volume slider. If I take that working code and the ONLY changes I make are to (a) change currentTime to the code below and (b) add the binding in IB, the video will not play. The strange thing is when I do this, I think KVO is actually working because I get hammered with log messages saying “Seek to 0.0 seconds.” dynamic var currentTime : Double { get { return CMTimeGetSeconds( player.currentTime() ) } set ( seconds ) { NSLog( "Seek to \(seconds) seconds" ) let time = CMTimeMakeWithSeconds( seconds, 1 ) player.seek( to: time ) } } I thought maybe this meant my periodic time observer was messed up, so I replaced my equivalent of the ObjC code with this: myTimeObserver = player.addPeriodicTimeObserver( forInterval: CMTimeMake( 1, 10 ), queue: DispatchQueue.main ) { [weak self] ( time: CMTime ) -> () in if let weakSelf = self { let seconds = weakSelf.currentTime // Force a read from player NSLog( "Asking to set time to \(seconds) seconds" ) weakSelf.currentTime = seconds // Force KVO update } } And the resulting log messages prove, I think, that player.currentTime() really does sit at 0.0 while I’m using KVO for the slider. On Sat, Jan 7, 2017 at 3:32 PM, Charles Srstka wrote: > On Jan 7, 2017, at 2:27 PM, Charles Jenkins wrote: > > > Charles, > > Thank you for the reply. “Won’t compile” was incorrect shorthand for a > long-winded explanation. What really happens is this: > > In the AVSimplePlayer demo, the timeSlider has two bindings: Value is > bound to File’s Owner.currentTime and MaxValue is bound to File’s > Owner.duration. These are double properties in ObjC. Here is an example of > one of them: > > - (double)currentTime > { > return CMTimeGetSeconds(self.player.currentTime); > } > > - (void)setCurrentTime:(double)time > { > [self.player seekToTime:CMTimeMakeWithSeconds(time, 1) > toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero]; > } > > In my project using Swift, I haven’t found a way to set File’s Owner in > IB, so I choose my binding object to be “View Controller,” because Xcode > automatically generated my view controller class with the name > ViewController. I have the currentTime and duration properties in my Swift > file, so I try to make my timeSlider mimic Apple’s two bindings: Value is > bound to ViewController.currentTime and MaxValue is bound to > ViewController.duration. I know I haven’t mistyped them because when I > clear the Model Key Path boxes, I can use a pulldown to select the > properties. But when I select them, a red stop sign appears in each Model > Key Path box, and when I hover over it I see this message like this: “The > Value binding expects to be bound to an object of type NSNumber, but > currentTime is of type Double.” > > Here’s my updated code for the currentTime property IB doesn’t like: > > dynamic var currentTime: Double { > get { > return CMTimeGetSeconds( player.currentTime() ) > } > set ( seconds ) { > let time = CMTimeMakeWithSeconds( seconds, 1 ) > player.seek( to: time ) > } > } > > To be clear, my ViewController object is an NSViewController subclass, so > I think NSObject conformance is a given. What else could be wrong? > > > Have you just tried compiling and running it and seeing if it works? I’ve > found that little stop sign in the Model Key Path box to produce false > positives from time to time, and this sounds like one. The KVO system wraps > primitive types in objects, and for Double, that’ll be NSNumber. As long as > your properties are dynamic, it should work. > > Charles > > -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
[OT] Testing In-App Purchases
Could someone with good experience testing in-app purchases contact me? I have created a test Sandbox user in iTunes connect, but no matter what I do, I can’t log in as that user on my device in order to test an in-app purchase. I have verified the email, logged in to the Apple ID management site, and set security questions. But logging in on a device only gets me a failure message saying the user “cannot be created” and I need to try again later. -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
AVSimplePlayer in Swift?
Has anyone recoded Apple's AVSimplePlayer example in Swift? I’m trying to do that in order to get some AVFoundation experience in Swift, and I’m having a bit of trouble. I can’t figure out how to do the bindings to currentTime and duration. - If I do them the easy way, using didSet clause, everything works and I can play the video and use the Rewind and Fast Forward buttons to alter playback rate, but I can’t scrub using the time slider. - If I imitate the ObjC version and try to do the bindings in IB, the time slider’s maxValue and value bindings don’t work (won’t compile) because duration and currentTime are not NSNumbers. - And if I change duration and currentTime to computed variables based on NSNumber, the video won’t play at all. Any suggestions? -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Elementary NSUserDefaults Question
Sean, Originally I did store bookmarks back when my app allowed users to pick background music from their music libraries. But I could find no way to play bookmarked library music at a low background volume, so I abandoned that and just began using a .wav file stored with the app’s resources. If anyone knows how to play music from the library at a low volume, without screwing up the system volume for other apps, e.g. Music.app, I’d love to learn it. On Wed, Dec 7, 2016 at 11:16 AM, Sean McBride wrote: > On Wed, 7 Dec 2016 10:25:46 -0500, Charles Jenkins said: > > >When the app starts up, we call NSUserDefaults.standard.register( [ > “bgm” : > > ) to default to the real file name, so the user will hear > > Charles, > > It's also best practice not to store file names/paths, but instead to > store "bookmarks". See NSURL's bookmarkDataWithOptions: > includingResourceValuesForKeys:relativeToURL:error:. > > Cheers, > > -- > > Sean McBride, B. Eng s...@rogue-research.com > Rogue Researchwww.rogue-research.com > Mac Software Developer Montréal, Québec, Canada > -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Elementary NSUserDefaults Question
That makes sense. Thanks, Ken! On Wed, Dec 7, 2016 at 11:00 AM, Ken Thomases wrote: > On Dec 7, 2016, at 9:25 AM, Charles Jenkins wrote: > > > > I may be misusing NSUserDefaults. I want to store the name of a > background > > music file, which may be nil if the user doesn’t want to hear anything. > For > > the time being, I have only two settings for my variable > > “currentBackgroundMusicFileName”: either a file that I distribute with > the > > app, or nil. > > > > When the app starts up, we call NSUserDefaults.standard.register( [ > “bgm” : > > ) to default to the real file name, so the user will hear > > music on first run. Then I call NSUserDefaults.standard.object( forKey: > > “bgm” ) as? String to read the current setting. > > > > When I run the app, I go into my settings and select “None” as the > > background music file I want to hear, and the variable gets changed and > we > > call NSUserDefaults.standard.set( nil, forKey: “bgm” ). The music is > > silenced. > > > > But when I kill the app and start again, the music comes back. Is it it a > > mistake to try using nil as an object value? Perhaps object( forKey: ) is > > meant to return the registered default value again instead of the nil > when > > I reload the app, making it impossible for me to use nil as a valid > value? > > Sort of. > > The user defaults system organizes the defaults into a stack of > "domains". For any given key, it consults the domains in order. If one > domain doesn't have a value for the key, it continues on to the next > domain. Like with a dictionary, nil is not a value, it's the absence of a > value. > > For purposes of this discussion, there are two relevant domains, the > application domain and the registration domain, consulted in that order. > The registration domain is the combination of whatever was passed to the > register() method. It is a volatile domain that's not persisted. It's > recreated from scratch for each run of the app by your calls to register(). > > The app domain is where settings are saved for your app. It's a > persistent domain. The various set(_:forKey:) methods modify this domain. > Most of them add or modify a value for the key, but set(nil, > forKey:"someKey") is a special case and removes the key-value pair for the > given key. > > So, your attempt to set nil for a key only ever removes it from the app > domain (where it never was in the first place), leaving the user defaults > system to proceed to the next domain, the registration domain, to satisfy > any future lookups. > > You should instead use a boolean key to control whether background music > plays. If you really intend to allow the user to change which file to play > from, you could continue to have a key for the file name, but it would be > subordinate to the boolean as to whether anything should play at all. > > Regards, > Ken > > -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Elementary NSUserDefaults Question
I may be misusing NSUserDefaults. I want to store the name of a background music file, which may be nil if the user doesn’t want to hear anything. For the time being, I have only two settings for my variable “currentBackgroundMusicFileName”: either a file that I distribute with the app, or nil. When the app starts up, we call NSUserDefaults.standard.register( [ “bgm” : ) to default to the real file name, so the user will hear music on first run. Then I call NSUserDefaults.standard.object( forKey: “bgm” ) as? String to read the current setting. When I run the app, I go into my settings and select “None” as the background music file I want to hear, and the variable gets changed and we call NSUserDefaults.standard.set( nil, forKey: “bgm” ). The music is silenced. But when I kill the app and start again, the music comes back. Is it it a mistake to try using nil as an object value? Perhaps object( forKey: ) is meant to return the registered default value again instead of the nil when I reload the app, making it impossible for me to use nil as a valid value? It will be funny if, for a purpose like this, one must define an additional value that means “none”—exactly the thing Optionals were supposed to prevent—but not surprising. OTOH, maybe there’s something I’m supposed to do after setting a value to tell NSUserDefaults I really, really mean for it to save the changed value? -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Custom Timer on Apple Watch
I asked this question recently, but maybe not in a clear enough way. If I use Apple’s Timer program on the watch, I can tell it to alert me in 15 minutes, and it works without fail. I want to make a smarter timer program for the watch, but I want my timer to “go off” in a way that’s prominent and noticeable—but short, so I don’t have to tap anything to silence the alert. (In case my terminology is not precise, what I mean by “alert” is: the watch makes a prominent vibration and sound and my app comes to the foreground for optional interaction.) Is there any possible way to make an alert that will definitely sound on the watch? Alternatively, is there any way to schedule an app to wake up and come to the foreground? -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Swift 3: How to Create CFArray of CGColors?
Thank you, Eric and Quincey! Both Eric’s resource and Quincey’s explanation gave good ideas on how to tackle problems like this in the future, which will probably help with the next stumbling block. Cheers! On Tue, Nov 22, 2016 at 7:36 PM, Quincey Morris < quinceymor...@rivergatesoftware.com> wrote: > On Nov 22, 2016, at 16:17 , Charles Jenkins wrote: > > > I have this line of code: > > let gradient = CGGradient( colorsSpace: CGColorSpaceCreateDeviceRGB(), > colors: [ clearWhite.cgColor, clearWhite.cgColor, > clearWhite.blendedColorWithFraction(0.5, ofColor: white).cgColor, > white.cgColor ], locations: [0, 0.57, 0.93, 1]) > > The array of colors is no longer legal in Swift 3. I get an error > message—“Contextual type CFArray cannot be used with an array > literal”—which I think is saying I must pass a CFArray. > > > The immediate problem is that the error message is spurious. Method > “blendedColorWithFraction(:ofColor:)” has been renamed in Swift 3 to > “blendedColor(withFraction:of:)”, so your array cannot be constructed as > the desired type "[GCColor]". > > The secondary problem is that “blendedColor(withFraction:of:)” returns an > optional, so you need a “!” operator after it. > > The third problem is that you need “as CGArray”. There would have been a > fix-it for this, if the first two problems had been fixed. The following > code compiles in a (macOS) playground: > > import AppKit > > let clearWhite = NSColor.white // or whatever > let white = NSColor.white // or whatever > > let colors = [ clearWhite.cgColor, clearWhite.cgColor, >clearWhite.blended(withFraction: 0.5, of: white)!.cgColor, >white.cgColor ] > > let gradient = CGGradient( colorsSpace: CGColorSpaceCreateDeviceRGB(), >colors: colors as CFArray, locations: > [0, 0.57, 0.93, 1]) > > > I would expect the iOS version is the same, if that’s what you need. > > For puzzling problems like this, I suggest “unrolling” the parameters like > the above, specifying explicit type annotations if you’re not sure what > types are being inferred. > > -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Swift 3: How to Create CFArray of CGColors?
I’m sure this will turn out to be elementary, but the Apple documentation of CFArray is so EMPTY that I can’t seem to figure it out. I have this line of code: let gradient = CGGradient( colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: [ clearWhite.cgColor, clearWhite.cgColor, clearWhite.blendedColorWithFraction(0.5, ofColor: white).cgColor, white.cgColor ], locations: [0, 0.57, 0.93, 1]) The array of colors is no longer legal in Swift 3. I get an error message—“Contextual type CFArray cannot be used with an array literal”—which I think is saying I must pass a CFArray. Despite Xcode crashing every few minutes while I’m typing, I was able to create a CFMutableArray object, but then I get an error when trying to add the colors because they aren’t unsafe pointers. How can I convert my array to the needed CFArray? -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Make WatchKit app show local notification
Well, I have two responses. First let me ask the question a different way: if people use this app, it is because they want the *watch* to “buzz” them at a certain time. Is there any foolproof way to make that happen? Second, I’m not doing anything in the iPhone portion of the app, which it think should mean if the watch won’t show the notification, the phone should by default. I’ll work on it today to see if that’s the case, and if not I’ll try adding notification handling to the phone. On Fri, Nov 11, 2016 at 9:49 AM, Jeff Kelley wrote: > The recommended approach here (I think) is to show the notification on > whichever device the user is using. Are you implementing any of the > UserNotification framework pieces on the phone? Would it work for your > purposes if the alert sometimes appeared there? > > > Jeff Kelley > > slauncha...@gmail.com | @SlaunchaMan <https://twitter.com/SlaunchaMan> | > jeffkelley.org > > On Nov 11, 2016, at 7:13 AM, Charles Jenkins wrote: > > Thanks, Jeff! Lordy be, the only thing I want is a sound and prominent > haptic when the countdown reaches zero. Is there no foolproof way to > achieve that? Everything I’ve tried seems to only work in certain cases. > > -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Make WatchKit app show local notification
Thanks, Jeff! Lordy be, the only thing I want is a sound and prominent haptic when the countdown reaches zero. Is there no foolproof way to achieve that? Everything I’ve tried seems to only work in certain cases. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Make WatchKit app show local notification
I’m trying to write an app that basically serves as a countdown timer. I’ve learned that the WKInterfaceTimer object doesn’t really do anything but draw the countdown on the screen. The documentation suggests pairing it with an NSTimer in order to be able to do something when the timer expires. I think the NSTimer approach is pretty worthless on the watch, because if the timer counts down for a long time, the app may be suspended or killed. And even if it only goes to background, when the timer expires, you’re not allowed to play haptics to alert the user. (These are the first things I tried, to no avail.) So instead of using a timer, I schedule a notification. The problem is, I can’t seem to make sure the notification’s alert is displayed when it arrives! Below is the top part of my ExtensionDelegate file. When the notification arrives, I get the message on my console saying we’re asking the system to present it, but nothing happens. What the heck else do I need to do to make sure notifications aren’t suppressed by the watch? import WatchKit import UserNotifications class ExtensionDelegate: NSObject, WKExtensionDelegate, UNUserNotificationCenterDelegate { func applicationDidFinishLaunching() { let nc = UNUserNotificationCenter.current() nc.delegate = self nc.requestAuthorization( options: [.alert, .sound] ) { ( accepted, error ) in if !accepted { print("Notification access denied.") } } } func userNotificationCenter( _ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping ( UNNotificationPresentationOptions ) -> Void ) { print( "Received alert--asking system to present it" ) completionHandler( [ .alert, .sound ] ) } } -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: WatchKit Noob Question
Well, no. The Apple docs I have found* and sample code from people asking questions in places like StackOverflow all completely fail to mention you need to import UserNotifications. Now that Apple’s docs have been reformatted attractively with plenty of whitespace, it seems crucial requirements info is often missing. When I get home tonight, I’ll add that import statement, and from there everything will probably work, so thanks, Quincey and Hunter! :-) *I’m sure someone will be able to reply to this with a link and say “See? It was right here!” But the word “import” doesn’t appear anywhere on important pages where it should be such as https://developer.apple.com/reference/usernotifications or https://developer.apple.com/reference/usernotifications/unusernotificationcenter On Mon, Nov 7, 2016 at 10:47 PM, Quincey Morris < quinceymor...@rivergatesoftware.com> wrote: > On Nov 7, 2016, at 17:00 , Charles Jenkins wrote: > > > What am I doing wrong? > > > What is the error message? > > And you did import UserNotifications, right? > > -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
WatchKit Noob Question
I’m writing my first WatchKit app. My deployment target is watchOS 3.1. I have searched the documentation and tutorials for scheduling local notifications on the watch, and I’m stuck at step 1. This line of my WatchKit Extension app’s InterfaceController.swift app file will not compile: let content = UNMutableNotificationContent() I’m sure I’m missing something that should be obvious, but this is how the documentation I’ve found says to instantiate the content object. What am I doing wrong? -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: HandOff Problems
I don’t have any answers, but please keep us posted. Sierra is the first macOS upgrade that proved to be a complete disappointment to me, because the interesting new features are based on Handoff, which worked for me in Yosemite and El Cap, but now doesn’t work at all. Looks like Handoff is joining AirDrop and Siri as features that would be incredible if they worked… On Thu, Oct 13, 2016 at 7:40 AM, Gerriet M. Denkmann wrote: > I have two apps for macOS 12 and iOS 10 which should do HandOff. > HandOff works ok between iOS devices. > > It once worked from any iOS device to Mac. (Never worked from Mac to an > iOS device). > > Until recently it worked from iPad to Mac (but not from iPhone to Mac). > Then I rebooted the Mac, and now even from iPad to Mac does no longer work. > > How can I debug this? > > Gerriet. > > > ___ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com > > This email sent to cejw...@gmail.com -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: How to avoid swift.retain/release
Gerriet, Take this with a huge grain of salt because I don’t know what’s really going on here and whether the API will permit it, but the first thing I would do is try to get the expensive operation outside any loop if possible: override function doSomething() { let ty = self.dynamicType for index = 0 to hugeNumber step 3 // pseudo code { ty.setBitFieldAtIndex(index) } } On Fri, Sep 9, 2016 at 2:54 AM, Gerriet M. Denkmann wrote: > This code executes in a strange way: SubClass takes much longer than > BaseClass. > > class BaseClass > { > let hugeNumber: Int > var bitfield: UnsafeMutablePointer > > init() > { > hugeNumber = 1_000_000_000 > bitfield = calloc( hugeNumber, 1) > } > > function doSomething() > { > for index = 0 to hugeNumber step 2 // pseudo code > { > self.dynamicType.setBitFieldAtIndex(index) > } > } > > class function setBitFieldAtIndex( index: Int ) > { > bitfield[index] = 5 > } > } > > final SubClass: BaseClass > { > override function doSomething() > { > for index = 0 to hugeNumber step 3 // pseudo code > { > self.dynamicType.setBitFieldAtIndex(index) > } > } > } > > One assumes that SubClass is faster: it should take about 2/3 the time of > BaseClass. But this is NOT the case. > > Instruments Time Profiler shows (total time, % of time, self time, name of > function): > > BaseClass (does NOT override doSomething) > 5743 ms 92.0% 644 doSomething > Instruments shows only Assembly code > 5099 ms 81.7% 4644 setBitFieldAtIndex > > SubClass(overrides doSomething) > 8407 ms 92.6% 186 doSomething > Instruments can show Swift code > 2693 29.6% 2576 > setBitFieldAtIndex this about expected > 2746 29.1% 2643 swift_retain > (_swift::HeapObject) BAD > 2643 29.1% 2643 swift_release > (_swift::HeapObject) BAD > > I guess that in BaseClass doSomething gets inlined and the compiler knows > that retain/release is not needed. > > So: How can I convince the compiler not to use retain/release in SubClass? > > Gerriet. > > > > ___ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com > > This email sent to cejw...@gmail.com -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Odd File Truncation
I have a Time Capsule and find it very unreliable. It simply won’t stay mounted as a Time Machine volume. I would never save a file directly to it. Can you not save the original locally and then sync with the Time Capsule? On Wed, Sep 7, 2016 at 3:56 AM, Peter Hudson wrote: > Hi All > > One of my apps saves its’ files to an Airport Time Capsule. > Bog standard doc based app - using the usual framework methods to save its > data. > This works extremely well. > And then, one day, the file that was saved was 20 bytes long instead of > the usual 5 MBytes. > > I’m sure there are a host of possibilities as to what went wrong. > Wondered if anyone else has experienced something similar… > > > Peter > ___ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com > > This email sent to cejw...@gmail.com -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Limiting app installation
They don’t allow it. It’s a specific promise of the app store that you pay once and then you can load the app on all your compatible devices. On Mon, Sep 5, 2016 at 2:44 PM, Rick Mann wrote: > Does Apple allow a developer to limit the number of devices on which an > app can run? I have an app that requires you to pay more to install it on > more than one iPhone and two iPads. It should go without saying these are > all on the same Apple ID. > > I thought Apple didn't allow this. But maybe they just don't provide a > mechanism for imposing this limitation, but don't prevent developers from > implementing their own? > > TIA, > > -- > Rick Mann > rm...@latencyzero.com > > > > ___ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com > > This email sent to cejw...@gmail.com -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Sprite Kit app won’t operate in foreground
Kirk and Everyone: I learned that developers can call Apple with questions, so I called in about my theory that it is iOS that’s killing my app and the disastrous bug I’m hunting for doesn’t actually exist. The tech who took my call agreed: when you build an app using a free developer account, Xcode creates a certificate only good for seven days. Seven days after your last debug session, the app will simply be killed without comment whenever it launches. I have asked that they add a message when this happens. Because money is tight, I wasn’t going to pay the sign-up fee for a full developer account until I was ready to distribute; but the fact that I could never seem to write an app that would work reliably over time meant I would NEVER be ready to distribute. On Tue, Aug 2, 2016 at 5:19 PM, Kirk wrote: > > I also have such an app. > > No SpriteKit in it, so there's one variable eliminated. > > It also is magically rejuvenated by running it from Xcode. > > No log messages on the phone. > > Kirk Kerekes > (iPhone) > > > On Aug 2, 2016, at 2:00 PM, cocoa-dev-requ...@lists.apple.com wrote: > > > > Subject: Sprite Kit app won’t operate in foreground > > Message-ID: > > > > Content-Type: text/plain; charset=UTF-8 > > > > A few weeks ago I wrote about a demo app that seemed to expire—it would > > work perfectly for a few weeks and then crash whenever opened. > > ___ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com > > This email sent to cejw...@gmail.com -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Sprite Kit app won’t operate in foreground
A few weeks ago I wrote about a demo app that seemed to expire—it would work perfectly for a few weeks and then crash whenever opened. Carl Hoefs advised me how to look for crash logs on the device. I did, and was surprised to find there is no crash log for my app. It’s not actually crashing! If I double-click the home button, I find my app there in the task list. But when I tap to bring it to the foreground, the splash screen shows for a half second, then I’m returned to Springboard. If I flick the app out of the task list to kill it and restart, I get the same behavior. But I have already learned that if I connect to my laptop and run the app under the debugger, it will reload and run correctly, then continue to function normally for a few weeks. Does anyone have experience with such behavior? Could I be doing something wrong with SpriteKit to make the app hibernate instead of showing the main scene? What could make an app resign foreground status every time it is restored? -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Do Debug Apps Expire on iOS?
Thank you all. I’ll start my research on how to find crash logs. On Thu, Jul 21, 2016 at 10:30 AM, Roland King wrote: > > > On 21 Jul 2016, at 22:15, Steve Bird wrote: > > > > > >> On Jul 21, 2016, at 10:05 AM, Eric E. Dolecki > wrote: > >> > >> I believe that debug apps built directly to hardware have a shelf life > of > >> one year. At least they did. > > > > I don’t know, but I would hope that they would pop up some notice like > “This app has expired. Contact the developer for the current version”. > > > > That would seem to be the polite thing to do, rather than driving off > into the ditch and staying there. > > Debug apps expire when your debug provisioning profile expires, which you > should know because you renewed your membership. > > TestFlight apps have a shorter lifetime to encourage developers to release > test versions on a regular basis and stop TestFlight just being an easy > mechanism for distributing private apps to your friends for a year at a > time. > > So the original poster most likely has a bug. > > > ___ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com > > This email sent to cejw...@gmail.com > -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Do Debug Apps Expire on iOS?
I have an app (written in Swift) that’s nearly ready to submit to the app store. I just need to get better background music. But it seems that every few weeks, it stops launching on my iPhone. It seems whenever I want to show it off, it won’t start. It dies after the launch screen appears. Then when I go back home and hook up my phone to my computer and use Xcode to debug and launch to see what happens, the app launches without incident and works fine. Then it will run normally for some weeks, despite reboots and other events that would cause it to relaunch. So I see two possibilities: 1. Debug versions expire, iOS will not let you keep using them for months or years, and there is no problem. 2. I have a serious bug that will make users mad, so I need to find out what is happening despite the fact that it NEVER happens when I have Xcode hooked up and could get a crash report. Can anyone tell me how to pursue this? What do you do if a debug version of an app only ever crashes when you are not running in the debugger? -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
[OT] Recent News Story Related to App Store Refunds
This is off topic, but I don’t know where else to ask this question of iOS Developers. There was a recent news story about a developer being charged back because Apple refunded a large number of sales dating back several years. Three years, I think. I was hoping to hear a followup that the story was just a hoax or a simple mistake that got corrected, but I haven’t seen anything, and now when I google or search my Mac news sites, I can’t even find the original story. (Searching with terms including “App Store” and “refund” is like trying to sip from a firehose.) Does this ring a bell for anyone? If so could you reply to me off list with any information about where to find details? ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: debugging AirDrop (update)
My family and I all have iPhones. We often try to use AirDrop to share photos and videos of my grandbabies. It almost never works. We’re on the same AirPort-based wireless network and all have Bluetooth on, in case that matters. When sitting right next to one another, Airdrop will often just sit there not showing anyone to share to. Sometimes if you close and open the share sheet a few times, the other person’s generic user icon will appear in the share sheet, and when it does the transfers always seem to succeed. But discovery seems to be an issue with AirDrop in general, so these problems you experience may not be due in any way to problems within your app. On Fri, May 27, 2016 at 1:23 AM, Gerriet M. Denkmann wrote: > I have an OS X app (10.11.5) which has a button called AirDrop, which does: > > - (IBAction)airDrop: (NSButton *)sender > { > NSArray *shareItems = list of one or more urls of pdf files > NSSharingService *service = [ NSSharingService > sharingServiceNamed: NSSharingServiceNameSendViaAirDrop]; > service.delegate = self;// probably not needed > [service performWithItems:shareItems]; > } > > Usually this just works: > I click the AirDrop button, a Panel slides down with a picture of the pdf > (or a symbol for multiple files if more than one). > I grab my iPad (which has “AirDrop: Contacts Only" set) and unlock it. > The AirDrop panel on the Mac shows (after a few seconds) my Mac Login > picture, I click it, and all is well. > > Sometimes it does not work correctly: > In this case I have to set the iPad to “AirDrop: Everyone". A generic user > picture will appear on the Mac and it will still work. > > But sometimes it does not work at all: > I can do whatever (like restarting the iPad; restarting the Mac) but still > no picture of a recipient will appear in the Mac AirDrop Panel. > > How can I debug this? > > Gerriet. > > Found some log messages, which seem to be related: > > Clicking my AirDrop button: > > 27/05/2016 12:17:41.630 sharingd[17313]: 12:17:41.629 : Bonjour discovery > started > 27/05/2016 12:17:41.662 sharingd[17313]: 12:17:41.662 : BTLE advertiser > Powered On > 27/05/2016 12:17:41.664 sharingd[17313]: 12:17:41.663 : BTLE advertising > hashes <01ca38ce b5742b51 4900> > 27/05/2016 12:17:41.667 sharingd[17313]: 12:17:41.666 : > SDBonjourBrowser::failedToStartAdvertisingWithError Error > Domain=NSMachErrorDomain Code=8 "(os/kern) no access" > UserInfo={NSLocalizedDescription=wirelessproxd can't start advertising at > this time.} > 27/05/2016 12:17:43.720 sharingd[17313]: 12:17:43.719 : > SDBonjourBrowser::failedToStartAdvertisingWithError Error > Domain=NSMachErrorDomain Code=8 "(os/kern) no access" > UserInfo={NSLocalizedDescription=wirelessproxd can't start advertising at > this time.} > > Clicking “Cancel" in the AirDrop Panel: > > 27/05/2016 12:19:46.595 AirDrop[17426]: Error in > CoreDragRemoveTrackingHandler: -1856 > 27/05/2016 12:19:46.595 AirDrop[17426]: Error in > CoreDragRemoveReceiveHandler: -1856 > 27/05/2016 12:19:46.658 sharingd[17313]: 12:19:46.657 : Bonjour discovery > stopped > 27/05/2016 12:19:46.671 sharingd[17313]: 12:19:46.671 : BTLE advertising > stopped > > But still don’t know what to do. > > Gerriet. > > > ___ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com > > This email sent to cejw...@gmail.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Proper way to set up constants when building an iOS framework
Alex, I suddenly had big fires to put out yesterday and couldn’t respond, but Jens is right. In the .m file but outside of any implementation, define the constant string and assign its value. In the header file just declare the same thing, but with the extern keyword and no value assignment. This creates exactly one copy of the variable but allows other source files to use it; the problem with what you were doing before was that it created a totally new variable with the same name in every source file where you imported the .h, which prevented the program from linking. Not to contradict Jens, but I recommend a constant name like kMyImportantConstant, not an all-uppercase name. All-uppercase names signify macro constants, not actual variables. You don’t want to trick a maintainer, not even your future self. Also, because of my C++ background, I’d see if the compiler would accept NSString const * const, because you want a constant pointer to an NSString that is constant; but I recognize that may not be the way things are done in Obj-C. You could look in old Apple Obj-C example code declaring NSString constants beginning with ‘k’ to see the right syntax. -- Charles On April 12, 2016 at 15:54:49, Jens Alfke (j...@mooseyard.com) wrote: On Apr 12, 2016, at 10:30 AM, Alex Zavatone wrote: How should they be initialized in the .m? Within an init method? No, just NSString * const ABC_MY_IMPORTANT_CONSTANT = @"abc"; Also, I'm quite familiar with the .pch for iOS apps, but are frameworks allowed a file like this or is that the myAwesomeFramework.h file? That’s what the framework header is. Thank you sir. Searching for instructions on how to do this is quite challenging. The ‘extern’ stuff is basic C, although it’s not stuff you deal with much using Obj-C. You might want to grab a book on C and read up on global variables. —Jens ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Proper way to set up constants when building an iOS framework
I imagine you’re already doing this, but your message wasn’t clear, so forgive me if I sound patronizing. The constants should be declared extern in the header file, but not assigned any values. The value assignments should appear inside a single .m file in your framework. -- Charles On April 12, 2016 at 12:35:55, Alex Zavatone (z...@mac.com) wrote: Do you guys have any tips on setting up a constants file when building a framework? I just moved in our SecurityConstants.h and KeychainWrapper, went to build my framework and now it's full of duplicate symbol build errors in the .o files. All the constants are NSString * const and defined in a .h file, which is is included where needed. Are there special approaches that I need to take when working with a framework on iOS that don't cause issues within a standalone app that would prevent this? Thanks in advance. Alex Zavatone ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com This email sent to cejw...@gmail.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Volume of background music
I will definitely check out the books. My fear is that they are for playing music files in my sandbox, stuff I ship with the app, but won’t be able to access the user’s music library as MPMusicPlayer does. But hopefully I’ll learn I’m wrong about that. -- Charles On March 27, 2016 at 21:02:28, dangerwillrobinsondan...@gmail.com (dangerwillrobinsondan...@gmail.com) wrote: You probably want to look at 3 things. SpriteKit AVAudioEngine Core Audio. SpriteKit It has some basic audio capability but I don't recall how much control. AVAudioEngine It's a higher level wrapper around Core Audio. You kind of still need to understand a lot of concepts from Core Audio but it's a lot easier to write code for, though its patterns are still not super easy and are a bit different from much of Cocoa and Cocoa touch. Make no mistake, there's a learning curve to audio but it's a valuable one that pays back. Audio is hard, and subtle, and people are sensitive to it. If you get it right they don't realize it. If you get it wrong, it stands out. I recommend the Learning Core Audio book as well as the AVAudioEngine book. In that order. Core Audio is hard partly because it deals in C structs a lot and you often have to worry about bytes and audio formats. You don't have to master it to do good things with it. AVAudioEngine makes spatial audio so much easier but still not a cakewalk. Sent from my iPhone > On Mar 27, 2016, at 10:26 PM, Charles Jenkins wrote: > > I would like to let users select their own background music from their music > libraries. From my researches, I can only find the MPMusicPlayer and its > associated media picker as the way to let the user make his or her own play > list; but if I use those interfaces, I cannot control the volume, so the > background music will be too loud. The user can of course lower the system > volume to compensate, but doing so will attenuate the game’s sound effects as > well. > > Have I missed anything, or is that really the current state of affairs on > iOS? > > -- > > Charles > ___ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/cocoa-dev/dangerwillrobinsondanger%40gmail.com > > > This email sent to dangerwillrobinsondan...@gmail.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Volume of background music
Yep. My understanding may be incorrect, but I think MPVolumeView controls the system volume. People have apparently found ways to bring the window up and use fake touches to alter the system volume programmatically, but because it controls the overall volume of all apps you switch to and the next app you run, I think making use of these tricks would upset users. -- Charles On March 27, 2016 at 17:56:22, Graham Cox (graham@bigpond.com) wrote: > On 28 Mar 2016, at 12:26 AM, Charles Jenkins wrote: > > I would like to let users select their own background music from their music > libraries. From my researches, I can only find the MPMusicPlayer and its > associated media picker as the way to let the user make his or her own play > list; but if I use those interfaces, I cannot control the volume, so the > background music will be too loud. The user can of course lower the system > volume to compensate, but doing so will attenuate the game’s sound effects as > well. > > Have I missed anything, or is that really the current state of affairs on > iOS? I’m unfamiiar with programming this task, but a quick trawl through the docs led me to MPVolumeView, which seems to the current approach to handling playback volume on iOS. —Graham ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Volume of background music
I would like to let users select their own background music from their music libraries. From my researches, I can only find the MPMusicPlayer and its associated media picker as the way to let the user make his or her own play list; but if I use those interfaces, I cannot control the volume, so the background music will be too loud. The user can of course lower the system volume to compensate, but doing so will attenuate the game’s sound effects as well. Have I missed anything, or is that really the current state of affairs on iOS? -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Seeking image manipulation book/site/course recommendations
I’m developing my first iOS game. I let the player pick photos as images for the sprites, and currently use SKCropNodes to combine layers. So each sprite on the screen is a crop node. This works great on my iPhone 6, but performance is just awful on my iPad 2. I think I should (a) make sure selected photos are converted so they are no larger than what I’ll actually need to display—in other words never scaled down for display in the game, and (b) find a way to combine my layers into one image and use that to make the SKSpriteNodes, rather than trying to have a bunch of crop nodes moving around onscreen at once. Can anyone recommend a good book or site or video course where I could learn how to do such image manipulation on iOS? -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Is a portrait-only launch image possible?
Thank you, David. Is it possible then to have two launch images and the system will select the correct one based on orientation? If not, I’ll have to give up on my idea of a smooth transition, because my launch image won’t be able to look anything like the welcome screen that follows. -- Charles On March 14, 2016 at 01:40:09, David Duncan (david.dun...@apple.com) wrote: > On Mar 13, 2016, at 12:32 PM, Charles Jenkins wrote: > > I’m developing my first iOS app. On the General tab of my app’s build > settings, I have checked only Portrait as the supported orientation. When > testing on an iPad today, I noticed that if I start the app with the iPad > held in landscape mode, the launch image appears in landscape and of course > looks terrible because parts of it are cut off. > > The next screen that appears is my welcome/splash screen, which is very > similar to the launch image; I meant for the transition from launch image to > welcome screen to be subtle. But the welcome screen appears in portrait mode > as it should, so the transition is jarring. > > It is not possible to have a Portrait-only launch image? If so, where else do > I need to look for settings controlling the orientation of the launch image? Modern iPad apps (which support multitasking) do not support control of interface orientation – your application will have to support all orientations. You can opt out of this by setting an Info.plist setting that states that your application must always be presented fullscreen (I don’t recall the property off hand, but it shouldn’t be too hard to find it if you really need it) but the recommendation would be to instead support all orientations so that your application will participate in multitasking. -- David Duncan ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Is a portrait-only launch image possible?
I’m developing my first iOS app. On the General tab of my app’s build settings, I have checked only Portrait as the supported orientation. When testing on an iPad today, I noticed that if I start the app with the iPad held in landscape mode, the launch image appears in landscape and of course looks terrible because parts of it are cut off. The next screen that appears is my welcome/splash screen, which is very similar to the launch image; I meant for the transition from launch image to welcome screen to be subtle. But the welcome screen appears in portrait mode as it should, so the transition is jarring. It is not possible to have a Portrait-only launch image? If so, where else do I need to look for settings controlling the orientation of the launch image? -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Starting out with storyboards (on Mac)
Thank you for that, Jerry. I started to reply in a similar way this morning, but deleted my draft because I thought I might just be making unhelpful noise. I am in Storyboards 101 right along with Daryle, and as I typed in example code from a tutorial project, my fumbling around with autolayout constraints confused XCode and caused it to lock up and crash—but not before saving my main storyboard file. After that, XCode beachballed for a long time and then crashed every time I attempted opening that file, so I lost access to all the screens in the storyboard at once. I’m sure I could have looked into ways to manually edit the file to remove the deadly constraints, but my point it, I hear there’s a way to break up storyboards and add segue references between them. So my advice would be similar: Storyboards are option. Feel free to stick with XIBs. If you do use storyboards, consider breaking your UI up among several, so if a problem develops in one file, it won’t cost you all the work you’ve done on the UI. -- Charles On March 1, 2016 at 10:22:36, Jerry Krinock (je...@ieee.org) wrote: > On 2016 Mar 01, at 01:33, Daryle Walker wrote: > > Tried out Mac programming … turned on … storyboards. If: • Your primary experience is in OS X> • You know nibs. • Your purpose is to ship OS X apps, not broaden your horizons. Is there any reason to learn and use storyboards? ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com This email sent to cejw...@gmail.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: UI to allow user to scale and crop image within a circle
Good tip! Thanks, Dave and Quincey. I was pretty sure the problem was something embarrassingly basic. The next step is to redesign the CircleOverlayView to fill its view with black except for the center of the circle. I already learned that filling the view with black and then filling the circle with clearColor() doesn’t work! My guess is, you do this by adding a mask layer; but you probably don’t redraw the mask in drawRect(), hm? It should never need to be refreshed unless the bounds change. Assuming I can figure out how to make a mask layer, what is the correct way to monitor for a bounds change in order to recreate the mask? -- Charles On February 24, 2016 at 03:16:00, David Duncan (david.dun...@apple.com) wrote: > On Feb 23, 2016, at 7:17 PM, Quincey Morris > wrote: > > On Feb 23, 2016, at 18:50 , Charles Jenkins wrote: >> >> I draw based on the overlay view’s frame, NOT based on the rect that gets >> passed in to drawRect(). I must not understand what that parameter is for. > > From the UIView documentation for ‘drawRect’: > >> The portion of the view’s bounds that needs to be updated. The first time >> your view is drawn, this rectangle is typically the entire visible bounds of >> your view. However, during subsequent drawing operations, the rectangle may >> specify only part of your view. > > > So, yes, your code is right now. :) > Its almost right – drawing should be done based on the bounds not the frame (this will be an issue if you either use the frame.origin or if you transform the view). > ___ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/cocoa-dev/david.duncan%40apple.com > > This email sent to david.dun...@apple.com -- David Duncan ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: UI to allow user to scale and crop image within a circle
I might’ve solved this. My overlay view works now because I draw based on the overlay view’s frame, NOT based on the rect that gets passed in to drawRect(). I must not understand what that parameter is for. I guess the pinning constraints were working all along, but I just couldn’t tell because my circle kept being drawn in the wrong place. Does it look like I’m doing this the right way now, or am I heading for trouble by ignoring the parameter to drawRect()? class CircleOverlayView: UIView { override init( frame: CGRect ) { super.init( frame: frame ) opaque = false userInteractionEnabled = false translatesAutoresizingMaskIntoConstraints = false backgroundColor = UIColor.clearColor() } required init?( coder: NSCoder ) { super.init( coder: coder ) } override func drawRect( rect: CGRect ) { let w = frame.size.width let h = frame.size.height let d = min( w, h ) let innerRect = CGRectMake( ( w - d ) / 2, ( h - d ) / 2, d, d ) let innerPath = UIBezierPath( ovalInRect: innerRect ) UIColor.redColor().setStroke() innerPath.lineWidth = 2 innerPath.stroke() } } -- Charles On February 23, 2016 at 3:49:28 PM, Quincey Morris (quinceymor...@rivergatesoftware.com) wrote: On Feb 23, 2016, at 12:32 , Charles Jenkins wrote: This is the first time I’ve tried to inject an overlay view into the view hierarchy, so I’m probably doing it completely wrong or missing something very basic. I’d suggest you go and watch the WWDC videos about advanced scroll view usage, starting with session 104 in 2011, then session 223 in 2012, session 217 in 2013 and session 235 in 2014. Unfortunately, that’s where the series seems to have ended. That’s a bit under 4 hours of video, but they’re incredibly well worth watching for anyone who’s interested in doing clever things with scroll views. Not only are they technically enlightening, but they are very, very entertaining. There’s 5 minutes or so in one of these videos that will tell you how to solve your problem neatly. (Bu I don’t know *which* 5 minutes. Possibly the “moon over cityscape” section?) The rest is just for fun. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: UI to allow user to scale and crop image within a circle
Jon: Thanks for that advice. I’ll have a look! Quincey: I start with a screen in the storyboard and its default view I’ll call “superview.” Into the superview I toss a scrollview and a toolbar with Cancel and Crop buttons. I position them with autolayout and wire them up to my Swift view controller class. In viewDidLoad(), I take an image previously selected by the user, create a UIImageView for it, then put that into the scrollview. The view controller instance sets itself to be the scrollview’s delegate, and when the scrollview asks, “what am I scrolling and sizing?” that UIImageView is what the call returns. When the user taps “Crop,” we notify the class that brought this view controller into existence, and it asks for the scaled and cropped portion of the image appearing in the scrollview. So far all this stuff seems to work perfectly. The only thing I’m lacking is, I want to show a circle over the scrollview so that the user can see what portion of the image will be retained if we crop the image into a circle. The circle should aspect-fit over the scrollview’s viewport, but not be managed by the scrollview. The scrollview knows nothing about the circle. The circle’s just a layer hovering “above” the scrollview but not accepting touch events. I’ve been trying to make the circle with an overlay UIImageView pinned so its frame is sized and positioned over the scrollview, but either (a) the overlay isn’t getting resized by autolayout, or (b) the circle artwork isn’t aspect-fitting inside the overlay view. My approach may be completely wrong. This is the first time I’ve tried to inject an overlay view into the view hierarchy, so I’m probably doing it completely wrong or missing something very basic. -- Charles On February 23, 2016 at 12:51:59, Quincey Morris (quinceymor...@rivergatesoftware.com) wrote: On Feb 23, 2016, at 04:28 , Charles Jenkins wrote: My scrollview containing an imageview seems to work just fine: I can scale and crop an image with no problem. But I’m having difficulty getting the desired “crop circle” to hover over the scrollview properly. It’s not clear to me exactly what strategy you’re attempting. I can see at least 4 possibilities: 1. The scroll view is itself a child (or a sibling) of a view that represents the circle. 2. The circle view is a child of the scroll view, but not of its content view. 3. The circle view is a child of the scroll view’s content view, but is a different view from the image view. 4. The circle view and image view are the same custom view, with gestures to pan and scale cause the image to move/resize relative to the circle. So I’m not sure whether scrolling the scroll view is the UI for positioning the image relative to the circle, or is the UI for scrolling. Similarly, I’m not sure if scaling from the scroll view is the UI for scaling the image relative to the circle, or is just the UI for zooming in. I’m inclined to think that using the scroll view to position the image relative to the circle isn’t semantically correct, but perhaps that’s not what you’re doing anyway. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: UI to allow user to scale and crop image within a circle
Still struggling with this… My scrollview containing an imageview seems to work just fine: I can scale and crop an image with no problem. But I’m having difficulty getting the desired “crop circle” to hover over the scrollview properly. When I add it to the main view (not the scrollview) at runtime, I try using autolayout constraints to pin it to the left, top, right, and bottom of the scrollview; but it always appears positioned elsewhere, as if it’s not resizing due to the constraints. I viewDidLoad(), I create each constraint like this: let lc = NSLayoutConstraint( overlay, attribute: .Left, relatedBy: .Equal, toItem: scrollView, attribute: .Left, multiplier: 1, constant: 0 ) And when all four have been created, I call NSLayoutConstraint.activateConstraints( [ lc, tc, rc, bc ] ) Is this the wrong approach? What’s the right way to display a simple overlay above the content of a scrollView? -- Charles On February 21, 2016 at 20:48:18, Charles Jenkins (cejw...@gmail.com) wrote: I’m trying to do something that’s so simple, conceptually, that I’m sure there’s a demo program for it, if only I could find the right Google search to locate it. I want to allow iOS users to select an image (either from the camera roll or by taking a photo) and display it in a CIRCLE for cropping. Users should be able to scale and position the image as they like to fit within the circle, then tap a DONE button to have the image cropped and saved into my app’s image store. I spent all day today screwing around making a view controller with a scrollview containing an imageview, and I haven’t figured out how to make the circle overlay correctly to fit over the scrollview. Does anybody know of a demo program that’ll show me how to do this? -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
UI to allow user to scale and crop image within a circle
I’m trying to do something that’s so simple, conceptually, that I’m sure there’s a demo program for it, if only I could find the right Google search to locate it. I want to allow iOS users to select an image (either from the camera roll or by taking a photo) and display it in a CIRCLE for cropping. Users should be able to scale and position the image as they like to fit within the circle, then tap a DONE button to have the image cropped and saved into my app’s image store. I spent all day today screwing around making a view controller with a scrollview containing an imageview, and I haven’t figured out how to make the circle overlay correctly to fit over the scrollview. Does anybody know of a demo program that’ll show me how to do this? -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Two Problems
Alex, The suggestion of changing the graphic’s name is a terrific one. I’ll do that tonight, and I expect it will work. I should’ve thought of that myself. Thanks! I’m using Swift, but whether my controller conforms or not is the nature of my question. I wasn’t totally clear, but when I said I added UISearchBarDelegate to my controller, I meant I added that protocol name to the list of protocols implemented by the class. Then I added the one optional protocol method I actually need (and I didn’t do something terribly stupid like marking it static). But when I set the status bar’s delegate to self, I crash anyway, as if I’m not really conforming. Since all the methods in the protocol are marked as optional, I don’t know what I could be missing. This is behaving as if my outlet were connected to the wrong kind of object. I think tonight I’ll delete it an re-drag from IB again, just to make sure my outlet really is getting set to an instance of UISearchBar. -- Charles On February 12, 2016 at 11:07:00, Alex Zavatone (z...@mac.com) wrote: 1. What are you setting the delegate to? Self? If so, have you made sure to "conform" to that delegate in your class? Something like @interface CharlesViewController : UIViewController ?? If you don't do that, then the method you need isn't accessible through self and BLAMMO! Unrecognized selector sent to instance. 2. Are you including the asset lib in your bundle for the build? Is the old name the same as the new name? Change the name of the graphic and see if it's even in the new build. GL Charles. Alex Zavatone. On Feb 12, 2016, at 8:59 AM, Charles Jenkins wrote: > PROBLEM 1: > > Is there anything new/tricky about the UISearchBar? I have placed one in my > view, and dragged an IBOutlet to the companion source file. The result is an > @IBOutlet weak var searchBar: UISearchBar! > > I added UISearchBarDelegate to my ViewController and implemented one method: > func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) > > My app works beautifully if I do NOT set searchBar.delegate = self in > viewDidLoad(). But if I try to set that delegate to make search work, my app > crashes on launch with an unhandled exception saying that an unrecognized > selector was called. > > UISearchDelegate’s methods are all marked “optional," I think, but I’m > wondering if in the latest version of iOS, one or more of them isn’t really > optional anymore…? > > PROBLEM 2: > > I made a change to my launch image graphic and dragged the new version into > the assets. The new image shows up there and in my LauchImage UI view, but > there seems to be nothing I can do to get it onto a device! > > I performed these steps: > Cleaned my project > Cleaned my project build directory > Quit Xcode > Rebooted my computer > Deleted the test app from my device—at this point, the old launch screen > should not exist ANYWHERE > Restarted Xcode > Reconnected my device > Started a debug session, which should have rebuilt and reinstalled a fresh, > clean copy onto the device > But somehow the old launch screen appears every time. Clearly there is a > cache somewhere that is not cleaned out with the project or its build > directory. > > What’s the secret to really getting rid of Xcode’s memory of an old launch > image? > > -- > > Charles > ___ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/cocoa-dev/zav%40mac.com > > This email sent to z...@mac.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Two Problems
PROBLEM 1: Is there anything new/tricky about the UISearchBar? I have placed one in my view, and dragged an IBOutlet to the companion source file. The result is an @IBOutlet weak var searchBar: UISearchBar! I added UISearchBarDelegate to my ViewController and implemented one method: func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) My app works beautifully if I do NOT set searchBar.delegate = self in viewDidLoad(). But if I try to set that delegate to make search work, my app crashes on launch with an unhandled exception saying that an unrecognized selector was called. UISearchDelegate’s methods are all marked “optional," I think, but I’m wondering if in the latest version of iOS, one or more of them isn’t really optional anymore…? PROBLEM 2: I made a change to my launch image graphic and dragged the new version into the assets. The new image shows up there and in my LauchImage UI view, but there seems to be nothing I can do to get it onto a device! I performed these steps: Cleaned my project Cleaned my project build directory Quit Xcode Rebooted my computer Deleted the test app from my device—at this point, the old launch screen should not exist ANYWHERE Restarted Xcode Reconnected my device Started a debug session, which should have rebuilt and reinstalled a fresh, clean copy onto the device But somehow the old launch screen appears every time. Clearly there is a cache somewhere that is not cleaned out with the project or its build directory. What’s the secret to really getting rid of Xcode’s memory of an old launch image? -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: OT? Xcode Question
Well, clearly I was hoping for something simpler than all that :-D I found a drag-and-click operation that seems to work, mostly. Drag the proxy icon from the Assistant Editor’s file over the icon for the file in the main editor, then click the X at the far right of the Assistant Editor window. That leaves me with the right file in the main editor, even though the wrong item is highlighted in the source list. -- Charles On February 11, 2016 at 2:17:01 PM, Quincey Morris (quinceymor...@rivergatesoftware.com) wrote: On Feb 11, 2016, at 07:49 , Charles Jenkins wrote: With no close button on the left side to give me a one-click solution, it would be mighty handy to find two quick keystrokes that would result in leaving the right-side file open in the main editor. So you want something like “Open in Primary Editor” — which you’ll find on the right click context menu in the assistant editor, or on the Navigate menu, or Command-Option-Comma? Admittedly, that doesn’t close the assistant editor, so you’d need Command-Return too, and if the focus was in the primary editor you’d have to switch to the assistant editor first, making the keyboard sequence be: Command-Option-` Command-Option-Comma Command-Return But it’s only two steps with the mouse: right-click and left-click. Is that the sort of thing you were looking for? ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
OT? Xcode Question
I find that when working with an Assistant Editor, I’m typically doing things like creating outlets and actions, where I’m dragging from IB on the left into companion code on the right. Then I’m done with the left side and need to start working on the right side. So what I almost always want to do is close the file on the left side; but XCode only offers a way to quickly get rid of the right side. It takes some thought and clicking around to get back to the place I need to work. Is there a keystroke I could use to SWAP the content of the left and right panes? I’ve looked around in the menus to find it, but no luck so far. With no close button on the left side to give me a one-click solution, it would be mighty handy to find two quick keystrokes that would result in leaving the right-side file open in the main editor. -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Protocol extensions returning self
I’m trying to learn how to use protocols and extensions to factor out redundant function bodies. Supposedly in a protocol, “Self” is the class implementing the protocol. So it seems to me that extension methods should be able to have a return type of Self so they can return self, and thus have the extension method behave the same as it would as if it were defined in the class adopting the protocol. But it seems as if that’s not the case, because in the code below, when I return “self” from the extension’s function bodies in order to enable method chaining, I get a compiler error. I’m told the class is immutable. If I move those bodies into the separate classes adopting the protocol and change Self to the name of the class, then everything works as expected. Is it possible to get the code working, or am I tilting at a windmill? I can imagine there’s just some minor syntax gotcha of which I’m unaware; but then again maybe there’s just no way to return a mutable self from a protocol-extension function body. BTW, I wondered if it was a reference type vs value type thing, so I tested: it doesn’t matter whether I define these classes as classes or structs; the error message is the same. import SpriteKit // Create a protocol specifying the items an action collection // must have in order for us to do fluent configuration using // chained method calls protocol SKActionCollection { var list: [SKAction] { get set } // Should be mutable! var action: SKAction { get } } // Use an extension to define methods common to both types // of action collection extension SKActionCollection { mutating func withAction( target: SKAction ) -> Self { list.append( target ) return self } mutating func withBlock( block: ()->() ) -> Self { return withAction( SKAction.runBlock( block )) } mutating func withDelay( duration: NSTimeInterval ) -> Self { return withAction( SKAction.waitForDuration( duration )) } // ... Many other useful mutating functions omitted func performOnceOn( node: SKNode ) { node.runAction( action ) } } extension SKAction { struct Fluent { // Fluent configuration for an action collection which // runs the actions sequentially class Sequence : SKActionCollection { var list = [SKAction]() var action: SKAction { return SKAction.sequence( list ) } } // Fluent configuration for an action collection which // runs the actions concurrently class Group : SKActionCollection { var list = [SKAction]() var action: SKAction { return SKAction.group( list ) } } } } // Try to use fluent configuration to define action collections // I get the same error, saying my function call (to the constructor?) // returns an immutable value, regardless of whether I use var or let var sequence = SKAction.Fluent.Sequence() .withDelay( 0.5 ) .withBlock( { print( "I did something in sequence!" ) } ) .action let group = SKAction.Fluent.Group() .withBlock( { print( "A group of one action is really pitiful" ) } ) .action -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: UIViews in SpriteKit Apps
The difference in visual style is something I’m considering. I’m hoping to use the standard system pickers, but adjust the colors to fit my game’s aesthetic. I’m still a real iOS noob, so even though I think it can be done, maybe I’m wrong. Thanks for the modal view controller idea: I’ll start researching that right away. -- Charles On February 3, 2016 at 01:31:54, Quincey Morris (quinceymor...@rivergatesoftware.com) wrote: On Feb 2, 2016, at 19:00 , Charles Jenkins wrote: I’m thinking of presenting a “menu” SpriteKit SKScene with an SKSpriteNode button on it that says “Set Background Music,” and when the user touches that node, I then switch to an entirely new screen for picking media. Can I do that, then transition back to my SKScene after the user selects a song? How do I do that? If I wanted to “switch to an entirely new screen”, I would present a new view controller modally so that it covers everything. Depending on the nature of the game, you might choose to pause the SKScene while it’s overlaid by the modal view. Then dismiss the modal controller to get back to the game. There’s no need to transition anything within Sprite Kit, as far as I can see. However, the controlling criterion is likely to be style and esthetics. For some games, it might be perceived as jarring if the visual style of the game is suddenly changed to the regular iOS UI style. It might be preferable to implement it all within Sprite Kit, to keep the style consistent. That means, of course, reinventing the controls you need, which can be a huge pain, but the design priorities are different for a game. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
UIViews in SpriteKit Apps
When I’ve previously dabbled a bit with iOS programming, it was with normal UIView forms and controls. Now I’m writing my first SpriteKit game, and I want to give users the ability to select their own background music. Can I use “normal” UIViews to do that, and have the standard media pickers? I tried to do web research on mixing SpriteKit and UIKit, and the hits I found were all about using UIKit objects on top of SpriteKit scenes. This isn’t exactly what I want… I’m thinking of presenting a “menu” SpriteKit SKScene with an SKSpriteNode button on it that says “Set Background Music,” and when the user touches that node, I then switch to an entirely new screen for picking media. Can I do that, then transition back to my SKScene after the user selects a song? How do I do that? -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: delete stock apps
System Integrity Protection, OS X’s new feature to (IIRC) keep malware from altering trusted default programs. -- Charles On January 25, 2016 at 12:07:59, Alex Zavatone (z...@mac.com) wrote: On Jan 25, 2016, at 1:16 AM, Rick C. wrote: > Does anyone know if there’s a way to delete stock apps on 10.11 without > disabling SIP and rebooting the machine? Or, is there a way to disable SIP > without rebooting? Thanks! > ___ SIP? SIP means the library behind internet telephony to me. What is the extension to the SIP acronym that you're referring to? ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com This email sent to cejw...@gmail.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: OT: Swift Code Autoformatter?
Quincey, That’s a fantastic suggestion! I work in VS all day, and I’m quite happy with how I can set up formatting rules in it. If VS Code is as rich for Swift, I’ll be able to do most of what I want automatically within it. -- Charles On January 15, 2016 at 13:47:47, Quincey Morris (quinceymor...@rivergatesoftware.com) wrote: take a look at Visual Studio Code ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: OT: Swift Code Autoformatter?
Thank you, squarqDev and Charles! I’ll give sed/awk a go! Quincey, your responses are normally very helpful, so I’m sorry I picked an example that bothered you. It’s not that it’s too much trouble for me to manually fix a typo like “let half = numerator /2”; I just wanted a completely innocuous example that wouldn’t open up a debate leading to unhelpful noise like “your formatting ideas are stupid, so clearly you don’t need the formatter you’re looking for.” However, considering that the compiler allows “let half = numerator/2,” complaining about the spacing in my example is either an inline compiler bug or someone at Apple just being an ass. If spaces are optional, then either space should be optional. There is no unary division operator to create any possible confusion about what the statement means. (And if I create my own unary division operator to do some insane thing, then I get what I deserve, right?) -- Charles On January 15, 2016 at 05:40:11, sqwarqDev (sqwarq...@icloud.com) wrote: > On 15 Jan 2016, at 03:36, Charles Jenkins wrote: > > there’s no way for the end user to create them. A combination of AppleScript, sed and awk will pretty much do anything you can imagine in terms of text formatting, and they’re all included on you mac already; no need for 3rd party apps. With a project and source document already open, doing this in the (Apple)Script Editor will get your code into the editor, where you can then transform it any way you like before sending it back: tell application "Xcode" tell source document 1 set _sourceCode to contents -- do shell script //do all your formatting here -- replace the original code with your formatted changes set contents to _sourceCode end tell end tell Best Phil @sqwarqdev ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com This email sent to cejw...@gmail.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
OT: Swift Code Autoformatter?
I keep eyeing a program that you can install to work with Xcode and autoformat source code. You know, things like automatically fixing spacing around arithmetic operators and other important types of punctuation. This is oddly important in Swift, where the compiler can’t interpret things like “let half = numerator /2” The program I’ve got my eye on has loads of good formatting rules, but a few I really want are missing, and there’s no way for the end user to create them. Can anyone recommend a good similar program that works with Xcode and allows the user to design his own formatting rules? -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Panes vs. Separate Windows
Interesting that so many others like the multiwindow approach. I’ve always thought that a horrible design, because you constantly have to fool with them to get them out of the way as you work on a document. I like the approach taken by Photoshop, where you can dock them them together in the layout that’s most effective for you, then mark some columns as being pinned open while others can collapse when not in use. I have Photoshop 5.5 or 6 and love the interface, but because I didn’t want to subscribe to Creative Cloud, I try to do photo stuff in other programs as much as possible—to get comfortable with other products so it’s not tempting to use PS every time. Initially I tried to do as much as possible in Pixelmator, but having tool windows scattered all over the place drove me crazy; now I’m using Affinity Photo, and the docked toolwindows are a major reason why. -- Charles On January 9, 2016 at 17:21:14, Rick Mann (rm...@latencyzero.com) wrote: In complex apps (e.g. CAD apps, IDEs) a given document has many auxiliary windows. The trend in UI at Apple has been to consolidate these into panes in a single window. I've always preferred separate windows (e.g. separate toolbar window). One more concrete example is in a CAD program: the objects in the document are often related to each other hierarchically. There's usually a view of this hierarchy using something like an outline table. I can see this naturally fitting as either a pane in a split view, or as a separate window. Best of both worlds, I suppose, would be a dockable window (a window that can be separate, or live as a pane in a split view), but that might be a lot of additional coding (is there a nice library that offers this?). Complicating matters is whether or not each open document shares a single instance of these auxiliary windows or has its own. I think something like a tool palette is clearly shared (it's more app-global then per-document), but the model object hierarchy window is probably per-document.f Separate windows have tremendous advantages, but I think panes are considered more "simple." Simplicity has advantages, but we're talking about complex apps that by their nature demand more of their users than something like iPhoto. Thoughts? -- Rick Mann rm...@latencyzero.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com This email sent to cejw...@gmail.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Kernel Panics Developing for SpriteKit
No sarcasm. Since the advent of Swift, it seems each version of Xcode has its weak and unstable points, and I just supposed SpriteKit was one of them for this version. I’m using a 2010 MacBook Air at the moment; hoping to buy a beefy iMac soon, but first I gotta see what the taxman says this year. -- Charles On December 28, 2015 at 12:25:06, Jens Alfke (j...@mooseyard.com) wrote: On Dec 28, 2015, at 6:23 AM, Charles Jenkins wrote: While less than ideal, I expect kernel panics when developing for SpriteKit on the Mac are just the way things are these days, right? Nothing to really worry about? Can’t quite tell if that’s sarcasm… Obviously kernel panics are serious bugs and nothing to be blasé about. Hopefully you’ve been reporting them to Apple. If you’re working off of demo projects from a book, you probably have some excellent test cases to reproduce the panics too, which would be invaluable to the engineers trying to fix them. BTW, what Mac hardware are you running [simulating] these on? That makes a big difference, because these are almost certainly GPU driver bugs. You might want to try a different Mac, if you have access to one. (In my experience, the Retina iMac has a lot of GPU issues, although I get visual glitches not panics. MacBook Pros seem pretty solid.) —Jens ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Kernel Panics Developing for SpriteKit
I’m testing the iOS game-development waters by working through Ray Wenderlich’s iOS and tvOS 2D game-development tutorial book. I’ve never used SpriteKit before. I have the latest released (non-beta) versions of El Capitain and Xcode. I’m experiencing regular kernel panics when working with SpriteKit, whether in the Xcode scene editor or through code. One chapter of the book is a physics-testing playground, and that has been no fun at all to work through, due to Xcode hangs and crashes along with regular kernel panics. While less than ideal, I expect kernel panics when developing for SpriteKit on the Mac are just the way things are these days, right? Nothing to really worry about? -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: [OT] Good XML Viewer App for Mac
I don’t remember where I got the script, but I use TextWrangler in conjunction with an XML formatter script to view XML documents. -- Charles On November 20, 2015 at 08:22:46, Dave (d...@looktowindward.com) wrote: Hi All, Could anyone recommend an XML Viewer for Mac? I just need to open XML text files are have it format the text sensibly. I’ve tried a couple from the Mac App Store but I couldn’t get then to work properly and requested a refund….. All the Best Dave ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Language options: Objective-C, Swift, C or C++?
Jens, I agree with what you say, but for the record, there was no sarcasm in my message. I was speaking very literally about what I thought I heard in the WWDC ’14 intro versus what I encountered when I began using it. -- Charles On Monday, June 15, 2015 at 13:50, Jens Alfke wrote: > > > On Jun 15, 2015, at 5:30 AM, Charles Jenkins > (mailto:cejw...@gmail.com)> wrote: > > I may have misinterpreted the WWDC ’14 announcement of Swift. Somehow I got > > the impression Swift was supposed to make Mac programming easier and more > > fun. > > Can we pleease stay away from sarcasm in this thread. Language flame-wars > suck and we’re very close to having one. > > The only thing I’ll say about this is that programming includes debugging and > testing, not just hammering out code. What I’m finding with Swift is that it > makes me think about more stuff about up-front, which can be annoying when > I’m just learning the language, but it’s better to explicitly consider > questions like “what happens if this is nil?” or “what types can this > collection hold?” than to run into them later when the app unexpectedly > crashes or misbehaves. > > (In the case of string manipulation, it makes the easy stuff wa > > harder.) > A lot of the “easy” stuff in NSString is only easy because it's Doing It > Wrong*, i.e. assuming characters are 16-bit and ignoring a bunch of the > details of Unicode. As a result if you’re not careful you end up with code > that breaks in many non-Roman languages and, nowadays, with emoji (which are > up in the 32-bit character space.) > > So what you’re really saying is that _Unicode_ makes stuff harder, which is > true, but that’s only because our ancestors were illogical and came up with > hundreds of thousands of different characters and symbols to communicate > with, instead of sticking to a simple set of 255. > > —Jens > > * To be fair, NSString was designed long ago when Unicode _was_ 16-bit. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Language options: Objective-C, Swift, C or C++?
I may have misinterpreted the WWDC ’14 announcement of Swift. Somehow I got the impression Swift was supposed to make Mac programming easier and more fun. What I found was that with Cocoa, it makes easy stuff harder without making the hard stuff the slightest bit easier. (In the case of string manipulation, it makes the easy stuff wa harder.) I am adopting Swift anyway because it cuts my number of source files in half. Having fewer places for bugs to crop up is more important to me than a language’s likeability. I believe I would be happier with an ObjC-3 that modernized the language a bit and did away with header files, but that’s not what we’re ever going to get—so Swift it is. -- Charles On Friday, June 12, 2015 at 20:51, Maxthon Chan wrote: > News outlets says that Objective-C is quickly falling out of people’s > attention and developers are turning away from it to Swift and C++. So what > language will you use to code various parts of your new project? Objective-C? > Swift 2? C++? Or the good old plain C? > > ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSUndoManager.prepareWithInvocationTarget:
Quite right. I also tend to use the obj-c style to describe method signatures because the punctuation is cleaner. Looking at my original message, only the word AnyObject gives a clue I’m using Swift. I’ll try to do better. — Charles On May 10, 2015 at 9:47:41 PM, Graham Cox (graham@bigpond.com) wrote: > On 11 May 2015, at 11:05 am, Charles Jenkins wrote: > > Here’s my registerUndo function that now works great: > > // Document_Undo.swift It would have been useful to have mentioned that you’re using Swift, saves us Obj-C guys giving you useless advice. You’re still in the minority you know… —Graham ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSUndoManager.prepareWithInvocationTarget:
Solved, thanks to Charles Srstka for the example!!! I wondered why the invocation would work for him but not me. In the example, Charles marks the method to be invoked “dynamic.” That was the difference. Like most examples in the docs, NSUndoManager’s invocation example is shown in obj-c, where this isn’t necessary, and I don’t think the current BNR mentions it. But the invoked method must be available through dynamic dispatch. This is probably stated somewhere in the docs, but I just missed it. EDIT: Actually the fact is obvious when you think about it, but because I’m working with a subclass of NSObject/NSDocument, it never would’ve occurred to me I’d have to do something special to achieve it. Here’s my registerUndo function that now works great: // Document_Undo.swift import Cocoa extension Document { private func objectsNecessaryForUndo() -> ( undoManager:NSUndoManager, textView:NSTextView ) { // We need to crash if these objects can't be retrieved return ( self.undoManager!, self.textView! ) } // Register undo for any method, with captured parameters. // IMPORTANT: Dynamic dispatch is required, so if the code you add in // the invocationClosure results in the error "AnyObject // does not have a member named...", just mark the invoked method // with the "dynamic" keyword. func registerUndo( actionName:String, invocationClosure:( AnyObject ) -> () ) { let ( undoManager, textView ) = objectsNecessaryForUndo() if textView.allowsUndo { println( "Preparing UNDO for \(actionName)" ) invocationClosure( undoManager.prepareWithInvocationTarget( self ) ) undoManager.setActionName( actionName ) } else { println( "Skipping UNDO for \(actionName) because textView.allowsUndo is false" ) } } } I call it like this: registerUndo( “Action Name” ) { $0.dynamicMethodName( neededParameter ) } — Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
NSUndoManager.prepareWithInvocationTarget:
Am I correct to believe there is NO way to use NSUndoManager.prepareWithInvocationTarget: if your undo method requires a parameter? I can use any method I want which has no parameter, but any method with parameters gets me the error “AnyObject does not have member named…” I thought about making a ClosureWrapper object which could have a parameterless method to call any method on a captured object, but since the invocation holds a weak reference, I think any instance of ClosureWrapper would be destroyed immediately after registration, so I didn’t bother trying. Right now I’m sticking with registerUndoWithTarget:selector:object:, but I’d like to know if there is a good way to use prepareWithInvocationTarget: instead. — Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Where and how do I know a save completed successfully?
On May 8, 2015 at 1:09:01 PM, Quincey Morris (quinceymor...@rivergatesoftware.com) wrote: In this case, the text view should probably use the document undo manager, though you may have to do extra work to coordinate its use with your document’s needs. To configure it, you should tell the text view what its undo manager is, via its ‘undoManagerForTextView:’ delegate method. My NSTextViewDelegate section begins like this: extension Document : NSTextViewDelegate { /// Plug document undo manager into the text v func undoManagerForTextView( view:NSTextView ) -> NSUndoManager? { var um = self.undoManager describeUndoManager( um, source:"NSTextViewDelegate.undoManagerForTextView:" ) return self.undoManager } I think the delegate is good, because its other methods get called. But this one doesn’t. I tell the text view its delegate is my Document instance as soon as possible in windowControllerDidLoadNib: — right after I test and find that my Document’s undoManager is NOT nil. So the situation remains that the Document has an undoManager, but the text view’s undoManager variable remains nil throughout execution. Is there still a step I’m missing? ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Where and how do I know a save completed successfully?
I may have a fundamental misunderstanding of how a document class, a text view, and an undo manager work together. I made these override functions in my Document class: override func updateChangeCount( change:NSDocumentChangeType ) { println( "updateChangeCount:" ) super.updateChangeCount( change ) if change == .ChangeCleared { println( "Change count cleared. Now clearing modification flags" ) project.resetModificationFlags() } } override func updateChangeCountWithToken( changeCountToken:AnyObject, forSaveOperation saveOperation:NSSaveOperationType ) { println( "updateChangeCountWithToken:forSaveOperation:" ) let before = documentEdited super.updateChangeCountWithToken( changeCountToken, forSaveOperation:saveOperation ) let after = documentEdited println( "Before=\(before); after=\(after)" ) project.resetModificationFlags() } I start my app and type some junk in the main window’s text view, where Undo works, then save. updateChangeCount: is never called, ever. I expected it to be called upon changing text in the text view and again upon saving. updateChangeCountWithToken:forSaveOperation: is called after saving, but the “before" and “after" flags are both FALSE, meaning that my typing in the text view didn’t cause the document to be marked as edited. Here’s the way I thought things worked: the first time you type into a text view, it needs to get an undo manager in order to put the change on its undo stack. Unless you do something special, it will get the window’s undo manager, which will also (for a document window) be the document’s undo manager. So I thought I’d be dealing with exactly one undo manager. When the undo stack contains operations, the change count is non-zero, and the document knows it has been edited. Somehow, that’s not all true for me. At the time updateChangeCount:forSaveToken: is called, the document’s undoManager property returns a value: an undoManager with zero levelsOfUndo, which may mean it’s going unused. The text view’s undoManager property returns nil. I already tried plugging the document’s undoManager into the text view after the NIB loads, but the text view’s undoManager property isn’t directly settable. As a text editor, shouldn’t my app have just one undo manager for each Document, one that works for the document window and the text view contained within it? If so, how do I configure that? — Charles On April 29, 2015 at 10:19:22 AM, Uli Kusterer (witness.of.teacht...@gmx.net) wrote: On ٢٩/٠٤/٢٠١٥, at ١١:٠٨, Charles Jenkins wrote: I think it most likely I’m doing this in the wrong place. But what’s the right place? Overriding NSDocument’s setFileModificationDate() would seem like the best way, but the NSDocument Programming guide says messages are sent to setFileURL:, setFileType: and setFileModificationDate: “if appropriate,” so I’m not sure I can count on getting that message. I don't think that's a good spot, as it isn't explicitly connected to file saving. I'd try updateChangeCount: instead, and check for NSChangeCleared. Also, keep in mind that "Save to..." and the likes also may get used on your document, saving to a different file but (IIRC) leaving the original document dirty. Maybe I'm misremembering what they do, but all those definitely need testing. -- Uli http://stacksmith.org ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Where and how do I know a save completed successfully?
Thank you, Uli and everyone. I’ll check out updateChangeCount: I did file a bug report about the compiler crash caused by my syntax. — Charles On April 29, 2015 at 10:19:22 AM, Uli Kusterer (witness.of.teacht...@gmx.net) wrote: On ٢٩/٠٤/٢٠١٥, at ١١:٠٨, Charles Jenkins wrote: I think it most likely I’m doing this in the wrong place. But what’s the right place? Overriding NSDocument’s setFileModificationDate() would seem like the best way, but the NSDocument Programming guide says messages are sent to setFileURL:, setFileType: and setFileModificationDate: “if appropriate,” so I’m not sure I can count on getting that message. I don't think that's a good spot, as it isn't explicitly connected to file saving. I'd try updateChangeCount: instead, and check for NSChangeCleared. Also, keep in mind that "Save to..." and the likes also may get used on your document, saving to a different file but (IIRC) leaving the original document dirty. Maybe I'm misremembering what they do, but all those definitely need testing. -- Uli http://stacksmith.org ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Where and how do I know a save completed successfully?
I realized yesterday that my app doesn’t mark its data structures as clean (saved) after a save operation, and I’m trying to find the right place to do that. My NSDocument subclass implements saveToURL and fileWrapperOfType. Intuitively I thought I could probably mark things as saved at the end of saveToURL if no error occurs. But if I try to do it as shown below, the compiler crashes with the error message “swiftc failed with exit code 1”: override func saveToURL( url:NSURL, ofType typeName:String, forSaveOperation saveOperation: NSSaveOperationType, completionHandler:(NSError!) -> Void ) { // Here I prepare my data structures for saving //super.saveToURL( url, ofType:typeName, forSaveOperation:saveOperation, completionHandler:completionHandler ) super.saveToURL( url, ofType:typeName, forSaveOperation:saveOperation, completionHandler:{ ( error:NSError! ) -> Void in { completionHandler( error ) // TODO: If no error, mark data structures as "clean" } } ) } As you can see, I’m attempting to wrap the passed-in completion handler, over which I may have no control, in my own completion handler which will both call the existing one and add mark my data structures. I couldn’t get the syntax to work as a trailing closure, so I added the closure as an argument—but of course I still might have the signature wrong . . . (I’m also concerned about the way the completion handler demands an NSError object, even though the documentation says it could be nil when no error occurs.) I think it most likely I’m doing this in the wrong place. But what’s the right place? Overriding NSDocument’s setFileModificationDate() would seem like the best way, but the NSDocument Programming guide says messages are sent to setFileURL:, setFileType: and setFileModificationDate: “if appropriate,” so I’m not sure I can count on getting that message. What’s your advice? — Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: To Swiftly Crash
That’s it! Thank you, Quincey! It no longer crashes if I put a question mark after replacementString:String and then ignore XCode’s warning, but I went ahead and implemented the “shouldChangeTextInRanges" method instead. Thanks for the quick, correct response! -- Charles On April 26, 2015 at 16:05:00, Quincey Morris (quinceymor...@rivergatesoftware.com) wrote: On Apr 26, 2015, at 12:40 , Charles Jenkins wrote: Is this a disaster in Swift-to-ObjC bridging, or have I done something wrong to cause it? func textView( tv:NSTextView, shouldChangeTextInRange range:NSRange, replacementString:String ) -> Bool The problem is that the replacement string can be nil (if only attributes are being changed, which is what happens when you Command-B), but the bridged signature is missing a ‘?’ on the replacementString type. (You can see this if you change the type to ’String!’, ignore the warning, and see the log message when you run.) Why this is, I don’t know, but I doubt it’s your fault. This delegate method is described as “superseded” in the header file. I suggest you try using the recommended method: func textView(textView: NSTextView, shouldChangeTextInRanges affectedRanges: [AnyObject], replacementStrings: [AnyObject]?) -> Bool ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
To Swiftly Crash
I’m experiencing a crash in what looks like Swift-library code in preparation for a call from NSTextView to my delegate method. I put a breakpoint on my method, but the crash seems to happen before actually getting into my code. To see if the problem could be reproduced succinctly, I took an old demo program and made its Document class implement NSTextViewDelegate. Now exactly the same crash happens in that project, which you can find at https://github.com/CharlesJenkins/ZoomableTextView To see the crash, just run the program, select a word in the editor, and press Command-B. (The crash won’t happen for normal typing, and if you comment out the line that sets the text view delegate, Command-B will work normally.) Is this a disaster in Swift-to-ObjC bridging, or have I done something wrong to cause it? — Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Swift: How to determine if a Character represents whitespace?
So my Character.isMemberOfSet() is a poor general-purpose method, and I need to ditch it. I like your code. I had to modify it a bit so it wouldn’t fall on strings composed entirely of whitespace: let testString = " \n\n \t\t" let attrStr = NSAttributedString( string:testString ) let str = attrStr.string as NSString let notWhitespace = NSCharacterSet.whitespaceAndNewlineCharacterSet().invertedSet var resultRange:NSRange let startRange = str.rangeOfCharacterFromSet( notWhitespace, options:NSStringCompareOptions.allZeros ) if startRange.length > 0 { let endRange = str.rangeOfCharacterFromSet( notWhitespace, options:NSStringCompareOptions.BackwardsSearch ) let startIndex = startRange.location let endIndex = endRange.location + endRange.length resultRange = NSRange( location:startIndex, length:endIndex - startIndex ) } else { // String is empty or all whitespace resultRange = NSRange( location:0, length:0 ) } let resultStr = attrStr.attributedSubstringFromRange( resultRange ) So, even though attrStr.string returns an NSString, you have use the “as” to explicitly keep the type and be able to do math on range indexes. Lacking that cast is what made rangeOfCharacterFromSet() useless to me yesterday. Your code seems way better. but is there a way in the playground for use to test addresses to make sure attrStr.string as NSString doesn’t perform a copy? — Charles On April 3, 2015 at 2:04:01 PM, Quincey Morris (quinceymor...@rivergatesoftware.com) wrote: On Apr 3, 2015, at 04:00 , Charles Jenkins wrote: for char in String( self ).utf16 { if set.characterIsMember( char ) { return true } Now we’re back to the place we started. This code is wrong. It fails for any code point that isn’t representable a single UTF-16 code value, and it fails for any grapheme that isn’t representable as a single code point. This is what I would do (playground version): import Cocoa let notWhitespace = NSCharacterSet.whitespaceAndNewlineCharacterSet().invertedSet let attrStr = NSAttributedString( string:" Fourscore and seven years ago... \n\n \t\t" ) let str = attrStr.string as NSString let startRange = str.rangeOfCharacterFromSet(notWhitespace, options: NSStringCompareOptions.allZeros) let endRange = str.rangeOfCharacterFromSet(notWhitespace, options: NSStringCompareOptions.BackwardsSearch) let startIndex = startRange.length != 0 ? startRange.location : 0 let endIndex = endRange.length != 0 ? endRange.location + 1 : str.length let resultRange = NSRange (location: startIndex, length: endIndex - startIndex) let resultStr = attrStr.attributedSubstringFromRange (resultRange) It’s the Obj-C code, just written in Swift. The ‘as NSString’ in the 3rd line makes it work. The practical difficulty in your original approach is that (e.g.) String.rangeOfCharacterFromSet returns a Range, but AFAICT that isn’t convertible back to a NSRange, or even just integer indexes. At the same time, AFAICT it isn’t useful with a String because it doesn’t contain Character indexes, just unichar indexes, which have no meaning for a String in general. Actually, my testing is with Swift 1.1, since I’m not in a position to move to Xcode 6.3 yet. It’s possible that the results are different in Swift 1.2. However, in the section of the release notes that talks about bridging between String and NSString, it says: Note that these Cocoa types in Objective-C headers are still automatically bridged to their corresponding Swift type so I suspect the results would be the same in 1.2. It seems to me there is an actual bug here: “String methods corresponding to NSString methods that return NSRange values actually return Range values, but these are not valid ranges, either for String objects (they represent UTF-16 code value positions, not Character positions) or for NSString objects (they’re not convertible back to NSRange). The String methods ought to return NSRange values just like their NSString counterparts.” ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Swift: How to determine if a Character represents whitespace?
I imagine you’re right, that they’re NString indexes packaged up into a frustrating return type. After sleeping on it, though, I imagined that even if complex grapheme clusters WERE to make count( attrStr.string ) return a different result than attrStr.length, it would probably never be due to whitespace. So if I go back to Charles Strstka’s original suggestion, where you pull off one character at a time, convert it to a 1-Character string, and then test for whitespace membership, I should be able to count leading and trailing whitespace characters and then do math based on attrStr.length to create the range. Here’s my current playground: import Cocoa extension Character { func isMemberOfSet( set:NSCharacterSet ) -> Bool { // The for loop only executes once; // its purpose is to convert Character to a type // you can actually do something with for char in String( self ).utf16 { if set.characterIsMember( char ) { return true } } return false } } var result:NSRange let whitespace = NSCharacterSet.whitespaceAndNewlineCharacterSet() let attrStr = NSAttributedString( string:" Fourscore and seven years ago... \n\n \t\t" ) let str = attrStr.string var headCount = 0 var tailCount = 0 var startIx = str.startIndex var endIx = str.endIndex while endIx > startIx && str[ endIx.predecessor() ].isMemberOfSet( whitespace ) { ++tailCount endIx = endIx.predecessor() } if endIx > startIx { while str[ startIx ].isMemberOfSet( whitespace ) { ++headCount startIx = startIx.successor() } let length = attrStr.length - ( headCount + tailCount ) result = NSRange( location:headCount, length:length ) } else { // String was empty or all whitespace result = NSRange( location:0, length:0 ) } let resultString = attrStr.attributedSubstringFromRange( result ) — Charles On April 2, 2015 at 11:16:52 PM, Quincey Morris (quinceymor...@rivergatesoftware.com) wrote: On Apr 2, 2015, at 19:28 , Charles Jenkins wrote: I can indeed call attrStr.string.rangeOfCharacterFromSet(). But in typical Swift string fashion, the return type is as unfriendly as possible: Range? — as if the NSString were a Swift string. I finally read the whole of what you said here, and I had to run to a playground to check: import Cocoa var strA = "Hello?, String” var strB = "Hello?, String" as NSString var strC = "Hello\u{1f650}, String” var strD = "Hello\u{1f650}, NSString" as NSString var rangeA = strA.rangeOfCharacterFromSet(NSCharacterSet.whitespaceCharacterSet()) // {Some “7..<8”} var rangeB = strB.rangeOfCharacterFromSet(NSCharacterSet.whitespaceCharacterSet()) // (7,1) var rangeC = strC.rangeOfCharacterFromSet(NSCharacterSet.whitespaceCharacterSet()) // {Some “8..<9”} var rangeD = strD.rangeOfCharacterFromSet(NSCharacterSet.whitespaceCharacterSet()) // (8,1) So, yes, these are NSString indexes all the way, even if the result is packaged as a Range. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Swift: How to determine if a Character represents whitespace?
Amen, brother. Given my attributed string “attrStr,” I can indeed call attrStr.string.rangeOfCharacterFromSet(). But in typical Swift string fashion, the return type is as unfriendly as possible: Range? — as if the NSString were a Swift string. So after doing two anchored searches, one at the beginning and one at the end of the string, if I get two different ranges, I’m stuck with two values that aren’t subtractable to determine the length of the NSRange I need in a call to attributedSubstringFromRange(). I think the safest thing for me to do for attributed string compatibility is give up on Swift purity and put my range-trimming function in an Objective-C file. — Charles On April 2, 2015 at 2:15:07 PM, Quincey Morris (quinceymor...@rivergatesoftware.com) wrote: On Apr 2, 2015, at 04:54 , Charles Jenkins wrote: Swift has a built-in func stringByTrimmingCharactersInSet(set: NSCharacterSet) -> String There is something wacky going on here — or not. (I know you don’t want to use this particular method, but I’m just using it as an example.) First of all, String and NSString are different classes, for real. Quoting a god-like personage, in a recent thread: On Mar 23, 2015, at 13:52 , Greg Parker wrote: Most of NSString's methods are re-implemented in a Swift extension on class String. You get this extension when you `import Cocoa`. And indeed, if you try this in a playground: let strA = "Hello, string" let strB = "Hello, NSString" as NSString let a = strA.characterAtIndex (6) // line 3 let b = strB.characterAtIndex (6) // line 4 you get an error at line 3, as you would expect/hope (since Strings aren’t “made of” unichars), but no error in line 4 (since NSStrings are). So it’s not odd that String.stringByTrimmingCharactersInSet would return a String. What’s very odd is that *in Swift* NSString.stringByTrimmingCharactersInSet returns a String — not a NSString — as does NSAttributedString.string, or apparently any Cocoa API that would return a NSString in Obj-C. This means it’s not possible *in Swift* to apply NSString methods to a NSString and stay entirely within the NSString world without casting/converting. *That’s* wacky, given that String and NSString are different classes with different (though very similar) APIs. The only way to un-wack this, that I can think of right now, would be for expressions like ‘someNSString.stringByTrimmingCharactersInSet (…) as NSString’ to involve only a cheap or free conversion from String to NSString. However there is no API contract to this effect AFAIK. Therefore: 1. We need a god-like personage to step in and un-wack this for real. 2. Subject to the outcome of #1, you can approach this entirely in the NSString world, in which case I like Uli’s suggestion, applied to 'yourAttributedString.string as NSString’. You’d have to verify by performance testing that massive conversions aren’t being made. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Swift: How to determine if a Character represents whitespace?
Oops. My documentation viewer was set up wrong. characterAtIndex() is indeed supposed to be available in Swift. Don’t know what I’ve done wrong that I can’t use it in a playground. -- Charles On April 2, 2015 at 10:18:00, Charles Jenkins (cejw...@gmail.com) wrote: The documentation certainly says that, Ken, but stick this code in a playground and see that you can’t examine the characters via index no matter whether you assume it to be String or NSString: let whitespaceSet = NSCharacterSet.whitespaceAndNewlineCharacterSet() let attrStr = NSAttributedString( string:" Fourscore and seven years ago \n\n\n\t\t\t " ) let str = attrStr.string var head = 0 let tooFar = attrStr.length while head < tooFar { if whitespaceSet.characterIsMember( str.characterAtIndex( head ) ) { // Skip -- I did it this way so the error message received from the above line will be clear } else { break; } ++head } var headIx = str.startIndex let tooFarIx = str.endIndex while headIx < tooFarIx { if whitespaceSet.characterIsMember( str[ headIx ] ) { // Skip } else { break; } headIx = headIx.successor() } characterAtIndex() doesn’t work because it’s not available in Swift. If you replace str.characterAtIndex( head ) with with str[ head ], you get the same error as in the version below it that incorrectly assumes it’s a Swift string: “Could not find overload of 'subscript' that accepts the supplied arguments.” Now, I did just type this out on a computer running Xcode 6.2. At home I’m using 6.3 beta, so it’s possible I’ll get home and find one of these versions works as expected, even though I’m sure I tried both ways last night when I first hit the roadblock… I’m now guessing that maybe converting from NSString to String and examining characters via one of the UTF views might possibly not involve a copy. But then how do I decide which view I should be using... -- Charles On April 2, 2015 at 08:44:52, Ken Thomases (k...@codeweavers.com) wrote: On Apr 2, 2015, at 6:54 AM, Charles Jenkins wrote: > What would be nice is a way to count leading and trailing characters in place > while the thing is still an NSAttributedString--without using > NSAttributedString.string to convert to a Swift string in the first place. NSAttributedString.string does not involve a conversion. The underlying string is part of NSAttributedString's data model. The documentation for the method explicitly says, "For performance reasons, this property returns the current backing store of the attributed string object." I don't know if there's a conversion to create a Swift string from that, but you don't have to. I believe you can work with NSString in Swift. Regards, Ken ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Swift: How to determine if a Character represents whitespace?
The documentation certainly says that, Ken, but stick this code in a playground and see that you can’t examine the characters via index no matter whether you assume it to be String or NSString: let whitespaceSet = NSCharacterSet.whitespaceAndNewlineCharacterSet() let attrStr = NSAttributedString( string:" Fourscore and seven years ago \n\n\n\t\t\t " ) let str = attrStr.string var head = 0 let tooFar = attrStr.length while head < tooFar { if whitespaceSet.characterIsMember( str.characterAtIndex( head ) ) { // Skip -- I did it this way so the error message received from the above line will be clear } else { break; } ++head } var headIx = str.startIndex let tooFarIx = str.endIndex while headIx < tooFarIx { if whitespaceSet.characterIsMember( str[ headIx ] ) { // Skip } else { break; } headIx = headIx.successor() } characterAtIndex() doesn’t work because it’s not available in Swift. If you replace str.characterAtIndex( head ) with with str[ head ], you get the same error as in the version below it that incorrectly assumes it’s a Swift string: “Could not find overload of 'subscript' that accepts the supplied arguments.” Now, I did just type this out on a computer running Xcode 6.2. At home I’m using 6.3 beta, so it’s possible I’ll get home and find one of these versions works as expected, even though I’m sure I tried both ways last night when I first hit the roadblock… I’m now guessing that maybe converting from NSString to String and examining characters via one of the UTF views might possibly not involve a copy. But then how do I decide which view I should be using... -- Charles On April 2, 2015 at 08:44:52, Ken Thomases (k...@codeweavers.com) wrote: On Apr 2, 2015, at 6:54 AM, Charles Jenkins wrote: > What would be nice is a way to count leading and trailing characters in place > while the thing is still an NSAttributedString--without using > NSAttributedString.string to convert to a Swift string in the first place. NSAttributedString.string does not involve a conversion. The underlying string is part of NSAttributedString's data model. The documentation for the method explicitly says, "For performance reasons, this property returns the current backing store of the attributed string object." I don't know if there's a conversion to create a Swift string from that, but you don't have to. I believe you can work with NSString in Swift. Regards, Ken ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Swift: How to determine if a Character represents whitespace?
I kept my original question as brief as I could, but let me tell you what problem I’m trying to solve, and maybe someone will have good advice I haven’t yet considered. I’m trying to code in pure Swift. I have an NSAttributedString which can potentially be very large, and I want to save off the attributedSubstringFromRange: which represents the string with leading and trailing whitespace trimmed. I’m trying to avoid copying the giant string merely to determine the proper substring range for copying it again. Swift has a built-in func stringByTrimmingCharactersInSet(set: NSCharacterSet) -> String which won’t help me because using it would copy the string and discard the attributes. Even using it for length-testing wouldn’t work, because I have no way to know how many characters were trimmed off the head versus the tail of the string. What would be nice is a way to count leading and trailing characters in place while the thing is still an NSAttributedString--without using NSAttributedString.string to convert to a Swift string in the first place. If there were no conversion to the unicode-compliant and amazingly difficult-to-do-anything-with-it Swift string, I’d be more confident that the shrunken range I calculate would be apples to apples. -- Charles On April 2, 2015 at 01:25:40, Quincey Morris (quinceymor...@rivergatesoftware.com) wrote: On Apr 1, 2015, at 21:17 , Charles Jenkins wrote: for ch in String(char).utf16 { if !set.characterIsMember(ch) { found = false } } Except that this code can’t possibly be right, in general. 1. A ‘unichar’ is a UTF-16 code value, but it’s not a Unicode code point. Some UTF-16 code values have no meaning as “characters” by themselves. I think you could mitigate this problem by using ‘longCharacterIsMember’, which takes a UTF-32 code value instead (and enumerating the string as UTF-32 instead of UTF-16). 2. A Swift ‘Character’ isn’t a Unicode code point, but rather a grapheme. That is, it might be a sequence of code points (and I mean code points, not code values). It might be such a sequence either because there’s no way of representing the grapheme by a single code point, or because it’s a composed character made up of a base code points and some combining characters. In this case, you can’t validly test the individual code points for membership of the character set. I’m not sure, but I suspect the underlying obstacle is that NSCharacterSet is at best a set of code points, and you cannot test a grapheme for membership of a set of code points. In your particular application, if it’s true that all** Unicode whitespace characters are represented as a single code point (via a single UTF-32 code value), or a single UTF-16 code value, then you can get away with one of the above solutions. Otherwise you’re going to need a more complex solution, that doesn’t involve NSCharacterSet at all. ** Or at least the ones you happen to care about, but ignoring the others may be a perilous proceeding. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Swift: How to determine if a Character represents whitespace?
Thank you very much. :-) I had been trying to figure out how to use NSCharacterSet, but I didn’t know the bit about converting to UTF-16 string first. — Charles On April 1, 2015 at 9:52:47 PM, Charles Srstka (cocoa...@charlessoft.com) wrote: On Apr 1, 2015, at 8:14 PM, Charles Jenkins wrote: > > Given this code: > > let someCharacter = str[str.endIndex.predecessor()] > > How can I determine if someCharacter is whitespace? import Foundation func isChar(char: Character, inSet set: NSCharacterSet) -> Bool { // this function is from an answer on StackOverflow: // http://stackoverflow.com/questions/27697508/nscharacterset-characterismember-with-swifts-character-type var found = true for ch in String(char).utf16 { if !set.characterIsMember(ch) { found = false } } return found } let str = "foo " let chr = str[str.endIndex.predecessor()] let isWhitespace = isChar(chr, inSet: NSCharacterSet.whitespaceAndNewlineCharacterSet()) // true Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Swift: How to determine if a Character represents whitespace?
Given this code: let someCharacter = str[str.endIndex.predecessor()] How can I determine if someCharacter is whitespace? — Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Drawing in a view with alpha < 1.0 shows windows behind
I confused the view with the color, but in essence that’s what I was afraid you were saying: that Yosemite is blending with unrelated content instead of what is layered by your app/view/window/whatever “under” the rectangle you’re trying to fill. I believe you should file a bug report on this. -- Charles On March 31, 2015 at 10:33:04, Eyal Redler (e...@beamr.com) wrote: First, I'm not setting the alpha for the view, I'm setting a color with 0.5 alpha and using that to fill the view (code is from "drawRect"). Second, and more importantly, my problem is not that content is showing through the view (that is the purpose), the problem is that what's showing through is not the right content: I'm seeing other windows and the desktop insetad of seeing what's painted on the superview, the superview's superview etc. To clarify, one of my view's superviews is painted opaque below that view so it's not a case where we have transparency all the way down to the window. Eyal > On Mar 31, 2015, at 4:01 PM, Charles Jenkins wrote: > > Eyal, > > I don’t have an answer for you, just a request for clarification. If a view > has a low alpha setting, you expect the content behind it to show through, so > your description sounds like normal behavior. However, I suspect you’re > dealing with a real problem. > > Are you saying that your view with low alpha is above other content in your > app, but instead of the information which *should* show through, Yosemite is > blending with other content—content from windows or the desktop behind your > app? > > -- > > Charles > > On March 31, 2015 at 08:42:30, Eyal Redler (eyred...@netvision.net.il) wrote: > > > Hi, > > I'm working on a custom view. I'm using the following code to draw the view > > [[NSColor colorWithDeviceRed:(float)42/255 > green:(float)49/255 > blue:(float)58/255 > alpha:0.5] set]; > NSRectFill([self bounds]); > > [[NSColor colorWithDeviceRed:(float)242/255 > green:(float)110/255 > blue:(float)80/255 > alpha:1.0] set]; > > NSFrameRect([self bounds]); > > For some reason the view is showing through the windows/desktop behind the > window where my view is located. > Surly this is a manifestation of one of the (somewhat unwanted IMO) features > of Yosemite but I've not been able to find where I can opt out of this. > The window I'm drawing to is a custom window, if that matters > > TIA > > Eyal ___ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com > > This email sent to cejw...@gmail.com > ___ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/cocoa-dev/eyredler%40netvision.net.il > > > This email sent to eyred...@netvision.net.il ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Drawing in a view with alpha < 1.0 shows windows behind
Whoops. Sorry to everyone about the doubled-up email. I had a problem with my email program and thought the first reply didn’t send, so I tried again, and apparently it went out as a reply to my own reply :-( -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Drawing in a view with alpha < 1.0 shows windows behind
Eyal, I don’t have an answer for you, just a request for clarification. If a view has a low alpha setting, you expect the content behind it to show through, so your description sounds like normal behavior. However, I suspect you’re dealing with a real problem. Are you saying that your view with low alpha is above other content in your app, but instead of the information which *should* show through, Yosemite is blending with other content—content from windows or the desktop behind your app? -- Charles On March 31, 2015 at 08:59:48, Charles Jenkins (cejw...@gmail.com) wrote: Eyal, I don’t have an answer for you, just a request for clarification. If a view has a low alpha setting, you expect the content behind it to show through, so your description sounds like normal behavior. However, I suspect you’re dealing with a real problem. Are you saying that your view with low alpha is above other content in your app, but instead of the information which *should* show through, Yosemite is blending with other content—content from windows or the desktop behind your app? -- Charles On March 31, 2015 at 08:42:30, Eyal Redler (eyred...@netvision.net.il) wrote: Hi, I'm working on a custom view. I'm using the following code to draw the view [[NSColor colorWithDeviceRed:(float)42/255 green:(float)49/255 blue:(float)58/255 alpha:0.5] set]; NSRectFill([self bounds]); [[NSColor colorWithDeviceRed:(float)242/255 green:(float)110/255 blue:(float)80/255 alpha:1.0] set]; NSFrameRect([self bounds]); For some reason the view is showing through the windows/desktop behind the window where my view is located. Surly this is a manifestation of one of the (somewhat unwanted IMO) features of Yosemite but I've not been able to find where I can opt out of this. The window I'm drawing to is a custom window, if that matters TIA Eyal ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/cejwork%40gmail.com This email sent to cejw...@gmail.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
How to Extend Swift Dictionary?
Does anyone know of a good tutorial on how to extend the generic dictionary class in Swift? I can add whatever I want to a typed dictionary, but I haven’t figured out the right syntax to add extensions generically. -- Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Memory optimization of NSAttributedString
Thank you, Aki. It’s such an awesome and unexpected feature, I found it hard to believe my test results. -- Charles On March 23, 2015 at 16:54:11, Aki Inoue (a...@apple.com) wrote: Hi Charles Yes, NSAttributedString does unique attribute dictionaries. Aki > On Mar 22, 2015, at 5:39 AM, Charles Jenkins wrote: > > My app uses lots of attributed strings in “subdocuments” which get moved into > and out of a text edit window. > > I began to wonder if I needed to add a cache for paragraph styles and string > attributes, because when each subdocument gets loaded, I’m repetitively > deserializing identical attributes to apply to the strings. > > Today I wrote the first draft of a test to see what happens when you blindly > and repetitively instantiate the same attributes: > > func attributedStringsWithNoCache() { > var array = [NSAttributedString]() > let fm = NSFontManager.sharedFontManager() > for index in 1...30 { > var font = NSFont( name:"Times", size:12.0 ); > font = fm.convertFont( font!, toHaveTrait:NSFontTraitMask.BoldFontMask ) > if ( index % 3 == 0 ) { > font = fm.convertFont( font!, toHaveTrait:NSFontTraitMask.ItalicFontMask ) > } > var para = NSMutableParagraphStyle(); > para.lineSpacing = 1.4 > para.alignment = NSTextAlignment.CenterTextAlignment; > let attributes = [ > "StyleName":"Bold", > NSFontAttributeName:font!, > NSParagraphStyleAttributeName:para > ]; > var attrStr = NSAttributedString( string:"Bold Para \(index)", > attributes:attributes ); > array.append( attrStr ); > } > for index in 1...30 { > var font = NSFont( name:"Times", size:10.0 ); > var para = NSMutableParagraphStyle(); > para.lineSpacing = 1.2 > para.alignment = NSTextAlignment.LeftTextAlignment; > let attributes = [ > "StyleName":"Roman", > NSFontAttributeName:font!, > NSParagraphStyleAttributeName:para > ]; > var attrStr = NSAttributedString( string:"Roman Para \(index)", > attributes:attributes ); > array.append( attrStr ); > } > var fontDict = [NSFont:Int]() > var attrDict = [NSDictionary:Int]() > var paraDict = [NSParagraphStyle:Int]() > for attrStr in array { > attrStr.enumerateAttributesInRange( > NSRange( location:0, length:attrStr.length ), > options:NSAttributedStringEnumerationOptions.allZeros, > usingBlock:{ ( attributes, Range, stop ) -> Void in > attrDict[ attributes ] = 1 > if let para = attributes[ NSParagraphStyleAttributeName ] as? > NSParagraphStyle { > paraDict[ para ] = 1 > } > if let font = attributes[ NSFontAttributeName ] as? NSFont { > fontDict[ font ] = 1 > } > }) > } > println( "NO CACHE:\nFound \(fontDict.count) fonts and \(paraDict.count) > paragraph styles in \(attrDict.count) attribute dictionaries" ) > } > > I expected the result to say it found 3 fonts and 60 paragraph styles in 60 > attribute dictionaries. (I know the system uniquifies fonts.) But when I run > the test, I get the best result possible—3 fonts and 2 paragraph styles in 3 > attribute dictionaries—as if NSAttributedString already uniquifies > everything. > > Is my test bad somehow, or am I really seeing that the text system already > optimizes memory usage by uniquifying all attribute dictionaries, so I can > forget about doing any caching of my own? > > — > > Charles > ___ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/cocoa-dev/aki%40apple.com > > This email sent to a...@apple.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Memory optimization of NSAttributedString
My app uses lots of attributed strings in “subdocuments” which get moved into and out of a text edit window. I began to wonder if I needed to add a cache for paragraph styles and string attributes, because when each subdocument gets loaded, I’m repetitively deserializing identical attributes to apply to the strings. Today I wrote the first draft of a test to see what happens when you blindly and repetitively instantiate the same attributes: func attributedStringsWithNoCache() { var array = [NSAttributedString]() let fm = NSFontManager.sharedFontManager() for index in 1...30 { var font = NSFont( name:"Times", size:12.0 ); font = fm.convertFont( font!, toHaveTrait:NSFontTraitMask.BoldFontMask ) if ( index % 3 == 0 ) { font = fm.convertFont( font!, toHaveTrait:NSFontTraitMask.ItalicFontMask ) } var para = NSMutableParagraphStyle(); para.lineSpacing = 1.4 para.alignment = NSTextAlignment.CenterTextAlignment; let attributes = [ "StyleName":"Bold", NSFontAttributeName:font!, NSParagraphStyleAttributeName:para ]; var attrStr = NSAttributedString( string:"Bold Para \(index)", attributes:attributes ); array.append( attrStr ); } for index in 1...30 { var font = NSFont( name:"Times", size:10.0 ); var para = NSMutableParagraphStyle(); para.lineSpacing = 1.2 para.alignment = NSTextAlignment.LeftTextAlignment; let attributes = [ "StyleName":"Roman", NSFontAttributeName:font!, NSParagraphStyleAttributeName:para ]; var attrStr = NSAttributedString( string:"Roman Para \(index)", attributes:attributes ); array.append( attrStr ); } var fontDict = [NSFont:Int]() var attrDict = [NSDictionary:Int]() var paraDict = [NSParagraphStyle:Int]() for attrStr in array { attrStr.enumerateAttributesInRange( NSRange( location:0, length:attrStr.length ), options:NSAttributedStringEnumerationOptions.allZeros, usingBlock:{ ( attributes, Range, stop ) -> Void in attrDict[ attributes ] = 1 if let para = attributes[ NSParagraphStyleAttributeName ] as? NSParagraphStyle { paraDict[ para ] = 1 } if let font = attributes[ NSFontAttributeName ] as? NSFont { fontDict[ font ] = 1 } }) } println( "NO CACHE:\nFound \(fontDict.count) fonts and \(paraDict.count) paragraph styles in \(attrDict.count) attribute dictionaries" ) } I expected the result to say it found 3 fonts and 60 paragraph styles in 60 attribute dictionaries. (I know the system uniquifies fonts.) But when I run the test, I get the best result possible—3 fonts and 2 paragraph styles in 3 attribute dictionaries—as if NSAttributedString already uniquifies everything. Is my test bad somehow, or am I really seeing that the text system already optimizes memory usage by uniquifying all attribute dictionaries, so I can forget about doing any caching of my own? — Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Programmatically putting attributed string RTF on the pasteboard
Thank you, Ken. Because the section on copying to the pasteboard speaks of writing an array of objects to the pasteboard and elsewhere the guide says you provide each possible representation, I thought that meant I “owed” the pasteboard one object for each representation. I couldn’t see how promised types could possibly work, considering that the source data might not exist by the time a consumer accepted it. So what you say makes it all clear. I put my Clipping object on the pasteboard and forget about it; consumers negotiate with the pasteboard, which only calls pasteboardPropertyListForType: to generate a specific requested representation when needed. Would it work to use the writing options to specify that all the types are only promised? CLIPPING_UTI must be the first type I specify so my app will receive the most faithful copy of the data; but it would be nice to skip my conversion process entirely in cases where the data gets cut but never pasted or pasted as RTF into another app. -- Charles On March 11, 2015 at 04:44:58, Ken Thomases (k...@codeweavers.com) wrote: On Mar 11, 2015, at 3:36 AM, Charles Jenkins wrote: > I’m having a bit of difficulty learning how to use the pasteboard. I have a > text view which holds the text in a rich attributed string. I determined that > the built-in methods for cutting and pasting were screwing up my data because > not all attributes survive the cut-and-paste process’s translation to and > from RTF for the pasteboard. > > For that reason I created my on custom data class as described in the > Pasteboard Programming Guide. The class is called “Clipping,” and of course I > defined an Exported UTI to go with it. > > The problem is in my implementation of NSPasteboardWriting. Here are the > writable types: > > -(NSArray*)writableTypesForPasteboard:(NSPasteboard*)pasteboard > { > NSMutableArray* arr = [[NSMutableArray alloc] initWithObjects:CLIPPING_UTI, > nil]; > [arr addObjectsFromArray:[self.attrStr > writableTypesForPasteboard:pasteboard]]; > return arr; > } > > The result is three types: CLIPPING_UTI, RTF, and plain string. The first > type allows my data to be copied and pasted intact within the text views of > my document windows; followed by the normal types of an attributed string for > compatibility with other apps. > > What I don’t know is the right way to put all the promised types on the > pasteboard in order. Here’s what I tried that does not work: > > -(BOOL)copyToPasteboard:(NSPasteboard*)pasteboard > { > [pasteboard clearContents]; > NSMutableArray* objectsToCopy = [[NSMutableArray alloc] init]; > for ( NSString* type in [self writableTypesForPasteboard:pasteboard] ) { > id data = [self pasteboardPropertyListForType:type]; > [objectsToCopy addObject:data]; > } > return [pasteboard writeObjects:objectsToCopy]; > } You have one item to add to the pasteboard. That item supports multiple types, but that's not relevant here. You want to do: -(BOOL)copyToPasteboard:(NSPasteboard*)pasteboard { [pasteboard clearContents]; return [pasteboard writeObjects:@[ self ]]; } That is, just write your object itself, alone, to the pasteboard. Once you do that, with the -writableTypesForPasteboard: method above and the method below, you're good. > -(id)pasteboardPropertyListForType:(NSString*)type > { > if ( [type isEqualToString:CLIPPING_UTI] ) { > return self.xml; > } else { > return [self.attrStr pasteboardPropertyListForType:type]; > } > } Regards, Ken ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Programmatically putting attributed string RTF on the pasteboard
I’m having a bit of difficulty learning how to use the pasteboard. I have a text view which holds the text in a rich attributed string. I determined that the built-in methods for cutting and pasting were screwing up my data because not all attributes survive the cut-and-paste process’s translation to and from RTF for the pasteboard. For that reason I created my on custom data class as described in the Pasteboard Programming Guide. The class is called “Clipping,” and of course I defined an Exported UTI to go with it. The problem is in my implementation of NSPasteboardWriting. Here are the writable types: -(NSArray*)writableTypesForPasteboard:(NSPasteboard*)pasteboard { NSMutableArray* arr = [[NSMutableArray alloc] initWithObjects:CLIPPING_UTI, nil]; [arr addObjectsFromArray:[self.attrStr writableTypesForPasteboard:pasteboard]]; return arr; } The result is three types: CLIPPING_UTI, RTF, and plain string. The first type allows my data to be copied and pasted intact within the text views of my document windows; followed by the normal types of an attributed string for compatibility with other apps. What I don’t know is the right way to put all the promised types on the pasteboard in order. Here’s what I tried that does not work: -(BOOL)copyToPasteboard:(NSPasteboard*)pasteboard { [pasteboard clearContents]; NSMutableArray* objectsToCopy = [[NSMutableArray alloc] init]; for ( NSString* type in [self writableTypesForPasteboard:pasteboard] ) { id data = [self pasteboardPropertyListForType:type]; [objectsToCopy addObject:data]; } return [pasteboard writeObjects:objectsToCopy]; } -(id)pasteboardPropertyListForType:(NSString*)type { if ( [type isEqualToString:CLIPPING_UTI] ) { return self.xml; } else { return [self.attrStr pasteboardPropertyListForType:type]; } } When I run the program and copy something, the second type placed on the pasteboard is NSData containing RTF provided by the attributed string (self.attrStr). When I call [pasteboard writeObjects:objectsToCopy], this message appears in the debugger: “Instances of class NSConcreteMutableData not valid for Pasteboard -writeObjects:. The class NSConcreteMutableData does not implement the NSPasteboardWriting protocol.” Sure enough, if I switch to TextEdit and paste, only plain string data appears. RTF styling is completely lost. It seems to me that NSAtttributedString offers to write public.rtf data, but when asked for pasteboardPropertyListForType:@“public.rtf” it’s returning an NSData that cannot actually be used on the pasteboard. What am I missing? I know NSAttributedString implements NSPasteboardWriting, so I could just return the attributed string itself, but then I’d be advertising three data types but providing only two... — Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSTextView Copy-and-Paste Problem
Thanks, Martin. The docs say you can put anything you want into the attributes dictionary—without mentioning that cutting and pasting will screw it all up. But it makes sense why, if cutting and pasting involves a translation into some non-native format. I’ll try to learn how to override cutting and pasting to make them include the full attributes. -- Charles On March 2, 2015 at 16:43:51, Martin Wierschin (mar...@nisus.com) wrote: > I’m having problems with text attributes getting mangled by copy-and-paste > operations within the selfsame text view. Obviously text pasted in from > outside the app would have an unpredictable set of attributes, but you’d > think copying and pasting in the same text view would leave you with a > consistent set of attributes. … > I’d like to know if this behavior is expected or a bug I didn’t look long at your code, but from what I saw, the behavior is expected. You’re applying custom keys to the NSTextView/NSTextStorage that will not be serialized when copy-pasting. By default when you select some text in NSTextView and trigger a copy action, the selected text will be vended on the pasteboard via some common data format (eg: HTML, RTF, DOCX, etc) so the content can be pasted into another application. Naturally these common data formats have no understanding of your custom attribute keys, and thus cannot encode them. If you need to preserve you own custom attributes when copy-pasting within your app, you’ll need to override the copy-paste methods in your NSTextView subclass to add a custom pasteboard data type with higher priority. ~Martin ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSTextView Copy-and-Paste Problem
Can I convince anyone to look at my demo app and tell me what if anything I'm doing wrong? I can hardly believe copying and pasting in a text view would lose or replace attributes like this . . . seems like a very serious bug someone would have noticed long before me. -- Charles On February 28, 2015 at 06:25:39, Charles Jenkins (cejw...@gmail.com) wrote: I’m having problems with text attributes getting mangled by copy-and-paste operations within the selfsame text view. Obviously text pasted in from outside the app would have an unpredictable set of attributes, but you’d think copying and pasting in the same text view would leave you with a consistent set of attributes. I fought the Swift battle to create a quick-and-dirty demonstration app which, if you are so inclined, you can check out from GitHub: https://github.com/CharlesJenkins/TextViewRevealer/tree/master (This is my first foray into GitHub, so let me know if something is missing from my project.) I’d like to know if this behavior is expected or a bug, or if there is something else I’m supposed to do in my code to make copying and pasting work better by faithfully copying text attributes. — Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
NSTextView Copy-and-Paste Problem
I’m having problems with text attributes getting mangled by copy-and-paste operations within the selfsame text view. Obviously text pasted in from outside the app would have an unpredictable set of attributes, but you’d think copying and pasting in the same text view would leave you with a consistent set of attributes. I fought the Swift battle to create a quick-and-dirty demonstration app which, if you are so inclined, you can check out from GitHub: https://github.com/CharlesJenkins/TextViewRevealer/tree/master (This is my first foray into GitHub, so let me know if something is missing from my project.) I’d like to know if this behavior is expected or a bug, or if there is something else I’m supposed to do in my code to make copying and pasting work better by faithfully copying text attributes. — Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Convert CGFloat to NSNumber
A structure?!? I did look it up in the documentation, and all I found was “the basic type for all floating-point values.” That the basis of all floating-point types could be a structure never occurred to me. Thanks! Swift is a language I want to like, but currently it makes the easy stuff hard without making the hard stuff any easier. — Charles On February 24, 2015 at 7:45:22 AM, Roland King (r...@rols.org) wrote: On 24 Feb 2015, at 18:57, Charles Jenkins wrote: I’m surprised how painful it is to do trivial things in Swift. I’ve stopped being surprised at this. Between the anal type checking and the spew of optionals I spend all my time fiddling around trying to get a ‘?’ in the right place or splitting lines up into individual expressions so that I can check the type of each line I’m hoping the improved error checking in the latest Swift 1.2 beta is going to help with this, but that version is currently buggy enough it crashes on my example code so I’m waiting for some of those bugs to get fixed before I try Swift again in earnest. All I want to do is convert NSFont.pointSize to an NSNumber, but I can’t figure out any syntax the Swift compiler will accept. My latest fruitless attempt has involved trying to simply cast the value into something for which NSNumber has a corresponding init(): let size:Float = font.pointSize as Float let points = NSNumber( float: size ) Neither Float nor Double works. What the heck is a Swift CGFloat that seemingly makes it incompatible with everything else? It’s a structure. Cmd-RightClick is your friend here. I ended up with this piece of slightly non-obvious code, there’s probably three other ways to do it. import Cocoa let font = NSFont(name: "Helvetica", size: 29 ); let rs = NSNumber( double: font!.pointSize.native ) An example of the ‘fiddling about’ I was talking about, before I got to those lines, I thought I’d just check I had made the font I wanted by constructing an NSAttributedString with it, I had this let str = NSAttributedString(string: "test string", attributes: [ NSFontAttributeName : font ] ) which gives an error message that there isn’t an initializer which accepts string: String, attributes : [ String, NSFont? ]. I split the line up to construct the attributes separately and defined it to be [ NSObject : AnyObject ] (which is what that initializer takes) and eventually stumbled on the realization I had to unwrap font in order for it to work. I spent a month nearly doing nothing but Swift and I never really got much better at it. Perhaps I’m too ancient and my brain is wired up wrong from years of C but I don’t find Swift an easy language to use at all and spend lots of unproductive time trying to sort out silly things like the above. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Convert CGFloat to NSNumber
I’m surprised how painful it is to do trivial things in Swift. All I want to do is convert NSFont.pointSize to an NSNumber, but I can’t figure out any syntax the Swift compiler will accept. My latest fruitless attempt has involved trying to simply cast the value into something for which NSNumber has a corresponding init(): let size:Float = font.pointSize as Float let points = NSNumber( float: size ) Neither Float nor Double works. What the heck is a Swift CGFloat that seemingly makes it incompatible with everything else? — Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Package/folder confusion
Yep, I was literally Doing It Wrong. I thought the extension was the link. Use the ID instead, and the packages are packages. Doesn’t look like that magically fixed the other issues, but at least it’s one less bug to squash. — Charles On February 17, 2015 at 12:34:52 PM, Quincey Morris (quinceymor...@rivergatesoftware.com) wrote: On Feb 17, 2015, at 06:31 , Charles Jenkins wrote: In my target’s Info tab, I have one Document Type: I filled in its Name, Class (the class of my Document window controller), and Extension. I selected Editor as the Role and made sure “Document is distributed as a bundle” is checked. I also have one Exported UTI: I filled in the same extension as the Document Type, added a Description, and indicated it Conforms To com.apple.package. If this is literally what you’ve done, you’re Doing It Wrong™. The Exported UTI and the File Type are linked by the UTI itself (the string in the “Identifier” field), not by the extension. You should copy the UTI from the “Identifier” field of the Exported UTI into the “Identifier” field of the File Type. In that case, the File Type’s extension and “is bundle” flag are ignored. The fact that you have two conflicting definitions of the document type may account for the results you’re seeing in the Finder. It’s also possible that the cause is different, that you have a leftover built app lying around somewhere that has incomplete file type information. If the above doesn’t fix your problem, you’ll need to go on a search-and-destroy mission to find copies of your app on any mounted disc. (Or, if you have tools to examine the LS database, look in it to find the path(s) to the wayward app bundles.) ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Package/folder confusion
I’ve got a goofy issue that’s been with me for a while, but I had more important things to work on. Months ago, members of this list told me how to set up my project so the document would be stored as a package. I tried it, it worked, and all was great. But at that time I was developing different parts of the app separately and saving them off as I got each bit working—so I’d have a separate working example to come back to later and compare with if I screwed things up. At some point in my iterations, I think I must’ve confused Yosemite, because my document packages now usually appear in Finder as directories. That has been very convenient for testing and inspecting my file format, since it saves me the step of opening the package, but now I’d like to cure the issue. Mostly because I have a couple of other problems I think may be related: My Recent documents menu isn’t populating, and sometimes after saving, when I open a file inside the package-directory to inspect it, I see the *old* contents. I somehow get an old Version of the file until I Force Quit Finder. (I’m using TextWrangler to inspect my files, and when Finder gets in a mood to serve up old Versions, sometimes TextWrangler blows up even trying to read them. Then after a Force Quit, Finder shows the proper content again and the new file can be read.) In my target’s Info tab, I have one Document Type: I filled in its Name, Class (the class of my Document window controller), and Extension. I selected Editor as the Role and made sure “Document is distributed as a bundle” is checked. I also have one Exported UTI: I filled in the same extension as the Document Type, added a Description, and indicated it Conforms To com.apple.package. I examined the Info.plist file viewing raw keys and values to confirm that LSTypeIsBundle = YES for my document type, and I’ve triple-checked that I typed the extension exactly the same in both places. I also compared against the old version of the app I was working on back when my packages always appeared as packages. I was coding in Swift then and using a different extension name, but the settings are virtually the same. Now if I use Onyx to rebuild Launch Services, after a reboot my documents show up as packages. But then the second I start debugging my app in Xcode, the documents revert to being plain directories. Any ideas how to fix this? — Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Idea for Improving Vibrancy
I have an idea for improving vibrancy, but right now it’s just a thought experiment. I don’t know how to accomplish it, so I wonder if you guys could provide any advice. I just posted this suggestion to Apple’s OS X feedback site: "Please consider adding NSVisualEffectBlendingModeDesktop and making it the default for objects like the Source View which reside in an app's main or document window. A window with that visual effect mode would use the desktop image ONLY for vibrancy blending. Doing so would be kind to users: they have chosen the desktop image presumably because it and its colors are pleasing. Blending with other randomly intervening windows due to the current default of NSVisualEffectBlendingModeBehindWindow is unkind to users because (a) it ignores the user's clearly expressed preference for the desktop image (b) without conveying any useful information whatsoever.” Well, I’m not going to hold my breath. But it did occur to me that an app’s main/document window could accomplish something similar by creating its own secondary window that would somehow “stick” behind it. The secondary window’s only purpose would be to replicate the portion of the desktop image occluded by its bounds. That way, no matter what apps are running, it would show a portion of the desktop image, and though users would never actually see this secondary window, the main/document window would blend with it, giving the user pleasing vibrancy using the desktop image he has chosen. Is this possible, do you think, to open a window that always hides directly behind the working window? — Charles ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com