"Failed to updated [sic] bookmark for item" on [NSOpenPanel openPanel] invocation - objective-c

My Mac app is designed to edit and analyse graphs, which users can create and store in files anywhere on the file system. I go to user to let them open a previously created file with [NSOpenPanel openPanel] and an inline completion handler block. During the menu processing I get this console error message several times:
2017-02-25 13:42:47.394433 pasteurnet3[32901:1263849] [default] Failed to updated bookmark for item (null) [60AF512E-6072-427D-8624-C406B0EF7D5A] - URL:file:///AirDrop with error Error Domain=NSCocoaErrorDomain Code=260 "The file couldn’t be opened because it doesn’t exist."
This happens just in the creation of the NSOpenPanel, even before sending it the beginWithCompletionHandler: message. FWIW, the menu nonetheless does comes up when eventually requested, allows file selection, and otherwise seems to work. There does seem to be a long delay in the initialisation of the menu object.
I haven't paid attention to this app in a long time but the appearance of the message apparently owes to a MacOS change. I immediately suspected sandboxing, but sandboxing was turned off for the app. If I turn on sandboxing and request the "User-selected file" entitlement it seems to make no difference.
There is nothing special about the object creation except it is done inside a #try block:
#try {
// Create the File Open Dialog class.
openDialog_ = [NSOpenPanel openPanel]; // error occurs here
}
#catch (NSException *e){
NSLog(#"innocuous exception(1) in -initForOpenWithDefaultFile:callBackTo:");
}
#catch (NSString *s){
NSLog(#"innocuous exception(2) in -initForOpenWithDefaultFile:callBackTo: \"%#\"", s);
}
#catch (...) {
NSLog(#"innocuous exception(3) in -initForOpenWithDefaultFile:callBackTo: probably a layout error");
}
#finally {
;
}
I am not doing anything with bookmarks from within the program nor, for that matter, with AirDrop.
Xcode 8.2.1, Macbook MacOS 10.12.3.

For me, "Failed to updated bookmark for item (null)" was logged at launch when my app's File > Open Recent menu contained items for files I had opened, then later deleted in the Finder. I don't know if there's a way to get the menu to just remove the items, but I got rid of the messages by choosing File > Open Recent > Clear Menu while running my app.
My app does not use NSDocument. I am adding items to Open Recent using -noteNewRecentDocumentURL.

Related

Making App default handler on OSX 10.10 with sandbox enabled

I wasn't able to find anything online about this, but LSSetDefaultHandlerForURLScheme will return -54 when the sandbox is enabled. I'm not sure what entitlement needs to be turned on for this to work as it does without the sandbox on.
To see this in effect, create a new project with this in the appdelegate:
-(void)applicationWillFinishLaunching:(NSNotification *)notification {
// Become default handler
CFStringRef bundleID = (CFStringRef)CFBridgingRetain([[NSBundle mainBundle] bundleIdentifier]);
OSStatus result = LSSetDefaultHandlerForURLScheme(CFSTR("maxel"), bundleID);
if (result != 0) {
assert(0);
}
}
It will work. Next turn on sandbox. It will fail with -54 in result.
Built on OSX 10.10 Yosemite. Anyone else run into this?
According to Apple's developer forums, you can't do this anymore in the sandbox--the behavior you are seeing is expected. It's really aggravating, because no alternative API exists to implement this functionality, short of stepping outside of the sandbox.

MCSession multipeer in background

I am sending through multi peer in ios7 a file using this method:
_progressSend = [session sendResourceAtURL:imageUrl withName: info toPeer:peerID withCompletionHandler:^(NSError *error) {
// Implement this block to know when the sending resource transfer completes and if there is an error.
if (error) {
NSLog(#"Send resource to peer [%#] completed with Error [%#]", peerID.displayName, error);
}
else {
// Create an image transcript for this received image resource
}
}];
The problem is very strange. This is what happens:
The device starts sending the resource, the progress bar starts filling up. When I put the app in the background, and check my email for example, the transfer is still going on (I can see that from the progress bar of the other device). If the transfer has finished, and I go back in the app, everything works just fine, but if I enter the app while the resource is still being transferred (for e.g. I exit 1/3 of the way and open it at 2/3) the app freezes completely and needs to be closed from the multitask bar. But Xcode doesn't show a crash. It is as iff the app keeps running but the user interface is just totally frozen. Does anyone have an idea??
Have you tried wrapping your code that sends the data in a dispatch_async block?
That might help.
Also how do you get the imageurl? Maybe it somehow can't be read when leaving and then re-entring you app
I had this issue also in a different type of way. On the portion of code that updates the progress bar you need to make it call the main thead by putting the code inside this block:
dispatch_async(dispatch_get_main_queue(), ^{
//insert progress bar code here
});
I don't know why this happens but this seems to have fixed it for me.

UIWebView and unload event

I'm loading local html contents into a UIWebView.
The javascript code of the loaded contents includes this event listener:
window.addEventListener("unload", function(){
// do something here;
});
That javascript code it is only executed when (before) the UIWebView component is released (e.g. when navigating back to another view controller) but it is not executed when another page is loaded. For example:
document.addEventListener("click", function(){ document.location = "www.google.com"; });
window.addEventListener("unload", function(){ alert("bye bye"); });
If executing this piece of code in safari, when I click on the document, before navigating to google.com, it would display the alert box. If I run the same code in UIWebView, the unload listener it is not executed. However, If I delete the UIWebView, the code is then executed.
My need is to have the same as in Safari, that is the unload method to be executed also when navigating away from the page.
I too have had problems in the past with JavaScript code that doesn't behave the same way in a desktop browser than in a UIWebView. I honestly don't know why it isn't working the way you want it to, but here I offer you a work around:
Instead of using the unload listener you have in JavaScript, try using UIWebViewDelegate's method webView:shouldStartLoadWithRequest:navigationType:. This method gets called whenever the user requests to load a new page (or content).
If you then need to execute more JavaScript code you could use UIWebView's method stringByEvaluatingJavaScriptFromString:.
Hope this helps!
Thanks to LuisCien solution above (please vote his post if you like the solution), I managed to solve the issue by manually generating and dispatching the unload event from objective-c side. This does not require any modification on my client side code (javascript) that now behaves the same in UIWebView and any other web browser. Here is the piece of code to add to your view controller:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
[webView stringByEvaluatingJavaScriptFromString:#"var e=document.createEvent('Event'); e.initEvent('unload', true, true); window.dispatchEvent(e);"];
return YES;
}

How do I allow downloads from a WebView using the standard download system on a Mac app?

I am building a mac app and would like to able to include the ability to browse the web and download files from the sites using the standard downloads system like you see when using safari.
At the moment when I click a link to a .zip or .nzb in the app it does nothing! Is there a way of allowing this from the app?
Thanks in advance for any help :)
The download manager in Safari is implemented by Safari, not by WebKit, so you don't get that functionality "for free", just the tools to build it.
In order to be able to download files, you need to assign an object as the WebPolicyDelegate of the WebView and implement the webView:decidePolicyForMIMEType:request:frame:decisionListener: delegate method.
In that method, you must call one of the WebPolicyDecisionListener protocol methods on the object that is passed as the decisionlistener parameter to the method. The three WebPolicyDecisionListener protocol methods are ignore, use or download. For any MIME types that you want to download, you must call download on the object passed as the listener parameter:
- (void)webView:(WebView *)webView
decidePolicyForMIMEType:(NSString *)type
request:(NSURLRequest *)request
frame:(WebFrame *)frame
decisionListener:(id < WebPolicyDecisionListener >)listener
{
if([type isEqualToString:#"application/zip"])
{
[listener download];
}
//just ignore all other types; the default behaviour will be used
}
You then need to assign an object as the download delegate of your WebView. This object will be sent all of the NSURLDownloadDelegate protocol messages as well as the WebDownload
delegate messages. You can use these messages to choose where the file is downloaded, as well as to implement a download manager UI like Safari.
Off the top of my head I would think you could implement the WebView's delegates to detect when a user clicks on a link - then check the extension and if it's not html/php/whatever then manually download the file yourself
Here's a link to a question (and answer) for how to capture the link pressing:
Cocoa WebKit/WebView delegate for location change? (User clicked link, javascript action, etc)
Another option is to open the link in external browser. And the file will be downloaded using external browser's download manager.
Sample code in Swift 2.2 with XCode 7.3:
func webView(webView: WebView!, decidePolicyForNavigationAction actionInformation: [NSObject : AnyObject]!, request: NSURLRequest!, frame: WebFrame!, decisionListener listener: WebPolicyDecisionListener!) {
let url = request.URL!.absoluteString
if url.hasSuffix(".zip") || url.hasSuffix(".nzb") {
listener.ignore()
NSWorkspace.sharedWorkspace().openURL(request.URL!)
} else {
listener.use()
}
}
PS. method above comes from WebPolicyDelegate.

Can we know the contents of NSBundle in Xode project?

How to know the contents of NSbundle in XCode Porject??
bcoz issue is, I have placed a config.doc file in resource folder of my XCode project and i want to read the contents of that config.doc file, but it says that config.doc file is not found. How to solve this problem??
This is how my code looks like:
-(void)applicationDidFinishLaunching:(UIApplication*)application
{
if([NSBundle mainBundle]pathForResource;#"config" ofType:#"doc")!=nil)
{
NSLog(#"File Exists");
}
else
{
NSLog(#"File not found!!");
}
NSString *configContents = [[NSBundle mainBundle]pathForResource:#"config" ofType:#"doc"];
NSLog(#"Contents of config file : %#",configContents);
}
OUTPUT :
File not found!!
Contents of config file :(null)
how to solve this problem?? i'm not able to make where is the mistake..
plz help
Thank You
You can see the contents of the bundle in the following way :
Expand the "Products" group in xcode
Right click on your_prodcuct.app and click "Reveal in Finder"
In finder right click on your app and click "Show package contents"
Now you can check whether the file actually exists in the bundle or not.