Date   

How to get DOMDocument from WkWebView

Gerriet M. Denkmann
 

WebView is sort of deprecated.
“In apps that run in OS X 10.10 and later, use the WKWebView class instead of using WebView”

But: how can I get the DOMDocument of a WkWebView?

I navigate (using WebView) the DOM hierarchy to get the interesting stuff.

Gerriet.


Handling of (shift-)cmd-backquote

Richard Kennaway
 

Applications on macOS respond to command-backquote and
shift-command-backquote by bringing one of the application's non-frontmost
windows to the front. I have these questions about how this works:

1. Where can I find a definitive account of which window is brought to
the front? It isn't simply second-front or rearmost respectively, it's
history-dependent. For example, if there are three windows in the order
ABC from front to back, repeated command-backquote gives the succession of
orderings

ABC -> BAC -> CBA -> ACB -> BAC

after which it cycles through the last three of these. The rule seems to
be that cmd-` brings forward the window that is nextmost relative to the
ordering they had at the beginning of the sequence, and sh-cmd-` the
previous relative to the original ordering. But I'd rather find an
authoritative statement than reverse engineer this.

There is also the issue of which operations by the user in between these
keystrokes will reset the "original" ordering to be the current ordering.
For example clicking in any window does, scrolling with the mouse doesn't.

I've searched Google, developer,apple.com, and forums.developer.apple.com,
but haven't turned up anything.

2. Does this functionality come by default for every application, or does
the developer have to do something to obtain it? All applications I've
looked at, except one, do this in the same way, so I expect it's
automatic. In the exception, the developer has presumably programmed their
own handling of these keystrokes.

3. If it is automatic, but the developer wants to do something different
with these keystrokes, how would they override the automatic processing?

-- Richard Kennaway


Re: Can I advantage of Swift availability features in a UITableVIewDelegate?

Rick Aurbach
 

I suspect you don't need to do that in the case you describe. Just implement both sets of delegate functions. When you compile against the iOS 11 SDK, everything will compile fine. The new delegate methods won't be called in iOS 10.x. You may need to "availability wrap" the code inside the implementation of tableView(_:editActionsForRowAt:) so that when the app is running under iOS 11+, both sets of delegate methods don't compete with each other.
Thank you, Bernie; you're absolutely right.

All that is actually needed is to implement tableView(_:editActionsForRowAt:) and tableView(_:trailingSwipeActionsConfigurationForRowAt:) [and the corresponding leading-edge function if needed]. The swipe-action functions need to annotated with @available(iOS 11, *) to prevent compiler issues.

Then, when running 10.3, the Swipe-action functions are ignored (as we expect). What I am pleased to report (and didn't expect -- hence the original question--) was that in iOS 11.x, if the Swipe-action functions are present, the editActions API is not called, so there no conflicts to worry about.

As usual, I am guilty of too much worrying and not enough trying.

Thanks again,

Rick Aurbach


Re: Can I advantage of Swift availability features in a UITableVIewDelegate?

Bernie Maier
 

Rick Aurbach:

I don't understand how to use @availabiltiy and/or #availability to
implement the above requirement when I am implementing optional protocol
functions. (I think I understand what to do when the conditional code is
mine, but I'm not sure how this applies to implementation of optional
protocol functions in system-defined protocols.)
If I understand you correctly, you are asking whether you can wrap entire function implementations inside availability guards, vs just a section of code within a function.

I suspect you don't need to do that in the case you describe. Just implement both sets of delegate functions. When you compile against the iOS 11 SDK, everything will compile fine. The new delegate methods won't be called in iOS 10.x. You may need to "availability wrap" the code inside the implementation of tableView(_:editActionsForRowAt:) so that when the app is running under iOS 11+, both sets of delegate methods don't compete with each other.

Bernie


Can I advantage of Swift availability features in a UITableVIewDelegate?

Rick Aurbach
 

I am working on an app which I would like to support 10.x for the next release. The problem I have is in a UITableViewDelegate:
I have two actions which I'd like to implement for cells. In 10.x, I have to implement tableView(_:editActionsForRowAt:) and both action buttons show up on the same side of the cell. But in 11+, I can use tableView(_:leadingSwipeActionsConfigurationForRowAt:) and tableView(_:trailingSwipeActionsConfigurationForRowAt:) and the two action buttons on opposite sides of the cell.

I don't understand how to use @availabiltiy and/or #availability to implement the above requirement when I am implementing optional protocol functions. (I think I understand what to do when the conditional code is mine, but I'm not sure how this applies to implementation of optional protocol functions in system-defined protocols.)

Can you help?? Thanks,

Rick


Re: Can I Generate a Segue This Way?

Ben Kennedy
 

On Jun 6, 2018, at 10:57 PM, Rick Aurbach <rlaurb@me.com> wrote:

Working with a storyboard, I add a Tap Gesture Recognizer, connect it to the label, and connect the segue to the gesture recognizer. I think I've set everything up correctly, but tapping on the label does not trigger the segue.
You might need to verify that “user interaction” is enabled for the label (which, if I recall correctly, it is not by default).

b


Can I Generate a Segue This Way?

Rick Aurbach
 

I have a situation where I want a user tap on a UILabel to generate a segue. (Yes, it sounds a bit strange, but it makes sense in context.)

Working with a storyboard, I add a Tap Gesture Recognizer, connect it to the label, and connect the segue to the gesture recognizer. I think I've set everything up correctly, but tapping on the label does not trigger the segue.

Before I spend even more time double-checking my setup, I would like to ask if this is possible. I.e., should I be able to trigger a segue from a gesture recognizer? (IB lets me do it...) and if so, is my approach correct? I figure I ought to be able to do this programmatically, but working in the storyboard is just so much nicer... By the way (if this makes a difference), the segue is connected to a Storyboard Reference, rather than to a scene in the current storyboard. Could this be the problem?

What do you think?

Rick Aurbach


Re: Replacement for Launch Services API

Jon Gotow
 

You can use the Service Management framework to add items to open at login (though they don't appear in System Preferences > Users & Groups > Login Items, which is a pet peeve of mine). See this answer on SO: https://stackoverflow.com/questions/35339277/make-swift-cocoa-app-launch-on-startup-on-os-x-10-11/35356972#35356972

I don't know of an alternate way to add items to the Finder's sidebar, though.

I'm still using LSSharedFileList even though it's deprecated.

- Jon

On May 31, 2018, at 5:58 AM, Sak Wathanasin <sw@network-analysis.ltd.uk> wrote:

Is there a replacement for LSSharedFileListCreate, LSSharedFileListInsertItemURL &c that have been
deprecated in
the latest SDKs? Or is there another way to add something to the Finder's sidebar or to login items?
AppleScript?


Replacement for Launch Services API

Sak Wathanasin
 

Is there a replacement for LSSharedFileListCreate, LSSharedFileListInsertItemURL &c that have been
deprecated in
the latest SDKs? Or is there another way to add something to the Finder's sidebar or to login items?
AppleScript?

Thanks
--
Sak Wathanasin
Network Analysis Limited http://www.network-analysis.ltd.uk


Re: Repeating timer firing way to fast

Jonathan Taylor
 

Thankyou both for your replies. I'm as sure as I can be that I'm not creating multiple timers, but I certainly checked for that. I appreciate that this is probably not the best design, due to the blocking issue. Thanks for your suggestion of NSTimer, though. That might be a nice quick fix until I can face a proper redesign!


Re: Crash with "illegal opcode" - how to debug this issue?

Graham Cox
 

No other response so far…

That particular crash is just one example. There are numerous crash reports with the same basic crash, but not always in a CATransaction callback, though that is a very common one.

Perhaps it’s simply a memory issue with something freed prematurely. It’s the most straightforward explanation, if not the most straightforward thing to track down. I’ll proceed on that basis - it’s just that such bugs don’t usually show up in this form.

—Graham

On 26 May 2018, at 4:37 am, Jack Brindle <jackbrindle@me.com> wrote:

Graham - did you ever get a response?
This looks to me like you are doing an animation which has completed and is trying to call back to your completion block. For some reason the completion block is mis-formed and is resulting in the execution of bad or non-code. I would look at your animation methods and make sure the completion blocks are formed and set up properly.

Jack


Re: Crash with "illegal opcode" - how to debug this issue?

Jon Gotow
 

On May 25, 2018, at 12:37 PM, Jack Brindle <jackbrindle@me.com> wrote:

Graham - did you ever get a response?
This looks to me like you are doing an animation which has completed and is trying to call back to your completion block. For some reason the completion block is mis-formed and is resulting in the execution of bad or non-code. I would look at your animation methods and make sure the completion blocks are formed and set up properly.
And that the block isn't being deallocated prematurely somehow.

- Jon


Re: Crash with "illegal opcode" - how to debug this issue?

Jack Brindle
 

Graham - did you ever get a response?
This looks to me like you are doing an animation which has completed and is trying to call back to your completion block. For some reason the completion block is mis-formed and is resulting in the execution of bad or non-code. I would look at your animation methods and make sure the completion blocks are formed and set up properly.

Jack

On May 24, 2018, at 5:30 PM, Graham Cox <graham@mapdiva.com> wrote:

Hi all,

We’ve received a number of reports from users of a crash due to a SIGILL as follows:

Exception Type: SIGILL
Exception Codes: ILL_ILLOPC at 0x7fff32837454
Crashed Thread: 0


Thread 0 Crashed:
0 com.apple.AppKit 0x00007fff32837454 -[NSApplication _crashOnException:] + 109
1 com.apple.AppKit 0x00007fff32e03cb1 __65+[CATransaction(NSCATransaction) NS_setFlushesWithDisplayRefresh]_block_invoke + 858
2 com.apple.CoreFoundation 0x00007fff34f8f467 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23

This seems to be an “illegal opcode” being encountered.

I’m at a loss to reproduce it so far, and I’m not sure why our latest build should be experiencing this given the few changes it has compared to the previous version.

What’s a good way to start trying to investigate this issue? Is it possible it’s a compiler issue? I’m using Xcode 9.3.1. ‘illegal opcode’ suggests bad code at the CPU level, but I can’t see how that can happen by writing high-level code or by memory corruption at runtime, since code is protected. Only an errant compiler could write a bad opcode, surely? And if so, that would explain why it’s suddenly an issue, since this is the only build we’ve shipped built in this version of Xcode.

—Graham





Crash with "illegal opcode" - how to debug this issue?

Graham Cox
 

Hi all,

We’ve received a number of reports from users of a crash due to a SIGILL as follows:

Exception Type: SIGILL
Exception Codes: ILL_ILLOPC at 0x7fff32837454
Crashed Thread: 0


Thread 0 Crashed:
0 com.apple.AppKit 0x00007fff32837454 -[NSApplication _crashOnException:] + 109
1 com.apple.AppKit 0x00007fff32e03cb1 __65+[CATransaction(NSCATransaction) NS_setFlushesWithDisplayRefresh]_block_invoke + 858
2 com.apple.CoreFoundation 0x00007fff34f8f467 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23

This seems to be an “illegal opcode” being encountered.

I’m at a loss to reproduce it so far, and I’m not sure why our latest build should be experiencing this given the few changes it has compared to the previous version.

What’s a good way to start trying to investigate this issue? Is it possible it’s a compiler issue? I’m using Xcode 9.3.1. ‘illegal opcode’ suggests bad code at the CPU level, but I can’t see how that can happen by writing high-level code or by memory corruption at runtime, since code is protected. Only an errant compiler could write a bad opcode, surely? And if so, that would explain why it’s suddenly an issue, since this is the only build we’ve shipped built in this version of Xcode.

—Graham


Re: Repeating timer firing way to fast

Quincey Morris
 

On May 22, 2018, at 04:15 , Jonathan Taylor <jonathan.taylor@...> wrote:

and therefore the timer callback blocks

It seems to me that this could be regarded as a bug in your design. The consequence of blocking, at a higher conceptual level, is that it destroys the concept of timing which is essential to your task.

One alternative is to use the timer callback *only* to decide whether it has been 4 or more seconds since the last time the secondary process action finished (or, more than 4 seconds since it last started, *and* that it has finished), and, if so, to trigger the action asynchronously. The precise details will depend on how you want the system to behave in the face of delays.

Or, you could switch to a recurring NSTimer. That has an API contract about what happens when scheduled firings are missed:

"After a repeating timer fires, it schedules the next firing for the nearest future date that is an integer multiple of the timer interval after the last scheduled fire date, within the specified tolerance. If the time taken to call out to perform a selector or invocation is longer than the specified interval, the timer schedules only the next firing; that is, the timer doesn't attempt to compensate for any missed firings that would have occurred while calling the specified selector or invocation.”


Re: Repeating timer firing way to fast

Jon Gotow
 

Not knowing how your code is structured, this may be a dumb question, but just to check:

Are you certain that you're not creating multiple timers somehow? I've mistakenly done this when creating timers in response to an event and the event occurs in extra, unexpected circumstances.

- Jon

On May 22, 2018, at 5:15 AM, Jonathan Taylor <jonathan.taylor@glasgow.ac.uk> wrote:

Hi all,


I’ve been trying to figure out what happened on an overnight run of the code that drives our scientific experiment, and I’m seeing logs that imply that a timer has been firing much more rapidly than intended. I’m hoping somebody can help me figure out why, and what I should be changing.

The calls that set up the timer can be condensed down to:

timerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, DISPATCH_TIMER_STRICT, dispatch_get_main_queue());
dispatch_source_set_event_handler(timerSource, myHandler);
dispatch_source_set_timer(timerSource, dispatch_time(DISPATCH_TIME_NOW, repeatIntervalNs), repeatIntervalNs, flexibilityNs);

where repeatIntervalNs is 4*NSEC_PER_SEC and flexibilityNs is 2*NSEC_PER_SEC. The CPU is under fairly high load from multithreaded code all night, but normally the timer fires on average every 4 seconds. Note that I have specified DISPATCH_TIMER_STRICT in a perhaps-misguided attempt to protect against the fact that occasionally, under unusually high load I presume, the timer was not firing for 30 seconds or more at a time. However, the problem that I am seeing in practice is that (in this overnight run, at least) the timer was firing at a rate of up to 200 times per second! All I am trying to achieve with this periodic timer is to check in with the secondary process and provide it with a status update.

The perhaps-unusual thing here is that the timer callback makes a function call via an NSConnection to a secondary process. Sometimes that secondary process is busy (for seconds at a time) and therefore the timer callback blocks. My theory is that what is happening is that the OS is building up a “backlog” of timer callbacks that it wants to make - many more, indeed, than than it would make if it really was firing every ~4secs.

None of this is a huge problem (except that it’s led to an enormous log file!), but it makes me worry that I am going about all of this the wrong way. What do people think? Is this a terrible way to achieve what I want to achieve, for some reason? Does it seem plausible that the number of timer callbacks would be disproportionately high like this? Any suggestions most welcome!

Cheers
Jonny



Repeating timer firing way to fast

Jonathan Taylor
 

Hi all,


I’ve been trying to figure out what happened on an overnight run of the code that drives our scientific experiment, and I’m seeing logs that imply that a timer has been firing much more rapidly than intended. I’m hoping somebody can help me figure out why, and what I should be changing.

The calls that set up the timer can be condensed down to:

timerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, DISPATCH_TIMER_STRICTdispatch_get_main_queue());
dispatch_source_set_event_handler(timerSource, myHandler);
dispatch_source_set_timer(timerSource, dispatch_time(DISPATCH_TIME_NOWrepeatIntervalNs), repeatIntervalNs, flexibilityNs);

where repeatIntervalNs is 4*NSEC_PER_SEC and flexibilityNs is 2*NSEC_PER_SEC. The CPU is under fairly high load from multithreaded code all night, but normally the timer fires on average every 4 seconds. Note that I have specified DISPATCH_TIMER_STRICT in a perhaps-misguided attempt to protect against the fact that occasionally, under unusually high load I presume, the timer was not firing for 30 seconds or more at a time. However, the problem that I am seeing in practice is that (in this overnight run, at least) the timer was firing at a rate of up to 200 times per second! All I am trying to achieve with this periodic timer is to check in with the secondary process and provide it with a status update.

The perhaps-unusual thing here is that the timer callback makes a function call via an NSConnection to a secondary process. Sometimes that secondary process is busy (for seconds at a time) and therefore the timer callback blocks. My theory is that what is happening is that the OS is building up a “backlog” of timer callbacks that it wants to make - many more, indeed, than than it would make if it really was firing every ~4secs. 

None of this is a huge problem (except that it’s led to an enormous log file!), but it makes me worry that I am going about all of this the wrong way. What do people think? Is this a terrible way to achieve what I want to achieve, for some reason? Does it seem plausible that the number of timer callbacks would be disproportionately high like this? Any suggestions most welcome!

Cheers
Jonny


Re: The Correct Place to Migrate my NSDocument

Bill Pitcher
 

I’m going to mark this as working now:

Set my DocumentController subclass as the main shared NSDocumentController
func applicationWillFinishLaunching(_ notification: Notification) {
_ = DocumentController.init()
}

class DocumentController: NSDocumentController {

override func makeDocument( withContentsOf contentsURL: URL,
ofType typeName: String) throws -> NSDocument {

if typeName == “CurrentVersion” {
return try super.makeDocument( withContentsOf: contentsURL, ofType: typeName)
}
let holdDocument = try self.makeUntitledDocument(ofType: "CurrentVersion") as! Document
try holdDocument.updateFromURL(fromURL: contentsURL)
return holdDocument
}
}

In the Document write the updateFromURL(fromURL: URL) that does the conversion and flag the document as self.hasBeenUpgraded = true
self.updateChangeCount(.changeDone) (this ensures the changes are saved if the user quits without saving)

when the document window has been displayed check hasBeenUpgraded and NSAlert the user that the Untiled Document has been upgraded.

NOTE: Document Type set to “Viewer" in Info.plist does NOT set NSDocument isInViewingMode, it does NOT open the document in an Untitled document. overriding isInViewingMode to true does disable Saving and messes with other options in the File menu, I gave up to this route.

Comments still very welcome!

cheers
Bill Pitcher
bill@ilike.co.nz

On 13/05/2018, at 11:46 AM, Bill Pitcher <bill@ilike.co.nz> wrote:

This works but it’s not right and throws a yucky message

let holdDoc = try NSDocumentController.shared.openUntitledDocumentAndDisplay(false) as! Document
// set the updated data
holdDoc.documentQuestions = self.documentQuestions
// show the new document
holdDoc.makeWindowControllers()
holdDoc.showWindows()
holdDoc.updateChangeCount(.changeDone)
// cancel
throw NSError(domain: "Application", code: 1002, userInfo: [NSLocalizedDescriptionKey : "File Updated", NSLocalizedRecoverySuggestionErrorKey : "The new Untitled document has the information for " + (self.fileURL?.path)! ] )

From Apple’s - Additional Document Type Considerations
"If you want to automatically convert them to be saved as your new type, you can override the readFrom... methods in your NSDocument subclass to call super and then reset the filename and type afterwards. You should use setFileType: and setFileURL: to set an appropriate type and name for the new document. When setting the filename, make sure to strip the filename extension of the old type from the original filename, if it is there, and add the extension for the new type.”

But from NSDocument
"You cannot use this property to change the document’s format after it has already been opened or saved. This property records only the initial document format used when first opening or saving the file."

Call super what??? "Expected '.' or '[' after ‘super'"

Bill Pitcher
bill@ilike.co.nz



On 12/05/2018, at 4:32 PM, Bill Pitcher <bill@ilike.co.nz> wrote:

I have an App that needs to be upgraded (thanks App Store) and I want the new App to Open and migrate it’s old documents to the new versions document. With the new File Type and Extension.

All good, I can open both types in "override func read(from data: Data, ofType typeName: String) throws”.
And the internal data is all good.

But when it saves (Including the automagical save when quitting) the new migrated data gets put into the old file, keeping the old DocumentType and Extension. (If I change the file extension manually in Finder it then opens fine)

I get the feeling that either I’m no doing this in the right place or I’m missing something obvious.

Any advice or examples greatly appreciated.

cheers
Bill Pitcher
bill@ilike.co.nz






Re: The Correct Place to Migrate my NSDocument

Bill Pitcher
 

This works but it’s not right and throws a yucky message

let holdDoc = try NSDocumentController.shared.openUntitledDocumentAndDisplay(false) as! Document
// set the updated data
holdDoc.documentQuestions = self.documentQuestions
// show the new document
holdDoc.makeWindowControllers()
holdDoc.showWindows()
holdDoc.updateChangeCount(.changeDone)
// cancel 
throw NSError(domain: "Application", code: 1002, userInfo: [NSLocalizedDescriptionKey : "File Updated", NSLocalizedRecoverySuggestionErrorKey : "The new Untitled document has the information for " + (self.fileURL?.path)! ] )

From Apple’s - Additional Document Type Considerations
"If you want to automatically convert them to be saved as your new type, you can override the readFrom... methods in your NSDocument subclass to call super and then reset the filename and type afterwards. You should use setFileType: and setFileURL: to set an appropriate type and name for the new document. When setting the filename, make sure to strip the filename extension of the old type from the original filename, if it is there, and add the extension for the new type.”

But from NSDocument
"You cannot use this property to change the document’s format after it has already been opened or saved. This property records only the initial document format used when first opening or saving the file."

Call super what??? "Expected '.' or '[' after ‘super'"

Bill Pitcher
bill@...



On 12/05/2018, at 4:32 PM, Bill Pitcher <bill@...> wrote:

I have an App that needs to be upgraded (thanks App Store) and I want the new App to Open and migrate it’s old documents to the new versions document. With the new File Type and Extension.

All good, I can open both types in "override func read(from data: Data, ofType typeName: String) throws”.
And the internal data is all good.

But when it saves (Including the automagical save when quitting) the new migrated data gets put into the old file, keeping the old DocumentType and Extension. (If I change the file extension manually in Finder it then opens fine)

I get the feeling that either I’m no doing this in the right place or I’m missing something obvious. 

Any advice or examples greatly appreciated.

cheers
Bill Pitcher
bill@...








Audio stops playing when screens goes dark after screen lock.

Antonio - SintraWorks
 

Hi,

I have a metronome app that is able to play audio in the background just fine. It even continues playing when the screens is locked. That is, until the screen goes dark after a few seconds. Playback stops, but it returns if I press any button that lights up the screen again.

I have Background Modes ON (Audio, Airplay and PiP checked), and set up my audio session with the following code:

    AVAudioSessionCategoryOptions option = flag ? AVAudioSessionCategoryOptionMixWithOthers : 0;
    if (![session setCategory:AVAudioSessionCategoryPlayback
                  withOptions:option
                        error:&setCategoryError]) {  }

A.f.a.i.k. this should be sufficient to ensure playback continues when the screen goes to sleep. I’ve had earlier incarnations of this app behave successfully with this feature since around 2010. I haven’t been able to figure out what caused this since its latest major release.

Any ideas what I might be overlooking or doing wrong?

- António

861 - 880 of 1454