Webview not showing loaded content - macos

I'm trying to experiment with web view by using swift. I created a simple Xcode project, placed a web view within my application interface and connected it to my app delegate.swift with an outlet called "myview". By executing
self.myview.mainFrameURL = "http://www.google.com"
from within applicationDidFinishLaunching(), I would expect the Google's homePage to be loaded. However, this doesn't happen: the web view does not show anything. What am I doing wrong?

1) Add the NSAppTransportSecurity in your plist https://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/
2) check in your project settings that "Sandbox" is enabled and that internet connections are allowed

You will have to call loadRequest() to make it load a page.
So basically:
[self.myWebView loadRequest: [NSURLRequest requestWithURL:
[NSURL URLWithString: #"http://www.google.com"]]]

After digging into the console logs, I found the solution to my problem. I'm not sure if I can share it though, since I'm using a beta OS X version and this restriction could have been introduced to improve apps' security, even if from what I can see it can be disabled.

Related

iOS 11: Force UIWebView to use cache (NSURLCache) when offline

Since iOS 11, when the device is offline, network requests are most often fail quickly with a “The Internet connection appears to be offline.” error message (code -1009). Previously – as was the case for iOS version < 11 – request would first try and go through (parts of) the URL loading system.
To serve content to UIWebViews while offline, I rely on a custom subclass of NSURLCache, that returns cached data first, and requests the actual resource from the server afterwards in the background (only if needed/updated), to store for the next request.
I would like to force my app – particular my UIWebViews I’d like to work offline – to still go through the URL loading system, so that my custom NSURLCache is asked for a cached response every time (as was the case before iOS 11). Is this possible?
More background
While the request attempt fails immediately on iOS 11 when the device doesn’t have an internet connection, the OS also introduced the waitsForConnectivity-flag to NSURLSession. This does exactly what I want. However, this only works for my simpler requests that load a single file and that I was able to easily port from a NSURLConnection-request to a NSURLSession-request.
UIWebView still uses NSURLConnection, and so I can’t use NSURLSession and waitsForConnectivity. But: is there another way to force going through the URL loading system and hit my custom NSURLCache implementation?
In my web views, I simply request pages like this:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#“some/url.html" relativeToURL:[NSURL URLWithString:#“https://www.example.com/"]] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
[self.webView loadRequest:request];
So, the above used to work and still works for iOS versions < 11. No luck with iOS 11.
I tried several values for the cachePolicy parameter, including NSURLRequestReturnCacheDataDontLoad. Still no luck.
And it’s not as simple as loading/requesting a single HTML file. The pages have lots of resources: CSS files, JS, images etc. And this was all transparently cached by my custom NSURLCache. Sadly no more with iOS 11.
(Now: I’m using a custom subclass of NSURLCache in the first place, because I couldn’t rely on the standard NSURLCache implementation, no matter what configuration and cachePolicy settings. If anyone has a suggestion for a different solution (without a custom NSURLCache) to my problem, I’m definitely listening.)

wxWebView Page Load Fails with no Internet Connection

I am writing a windows application that uses a wxWebView (Trident) to display pages served from an internal server that binds to the localhost interface on an ephemeral port. I have run into a problem where, if the host computer does not have any active external IP interfaces enabled (such as a laptop in airplane mode), the wxWebView instance refuses to load the page and sends a page load failure event with a string of "INET_E_DOWNLOAD_FAILURE". When this happens, I can make an external browser (including internet explorer) load the page from my web server so I know that the loopback interface(s) are working. Is there any way to configure the wxWebView instance so that it WILL load the page?
When I try this in the webview sample application, i can see the following in the log window:
13:33:33: Navigation request to 'res://ieframe.dll/navcancl.htm#http://www.wxwidgets.org/' (target='')
13:33:33: Title changed; title='http://www.wxwidgets.org/'
13:33:33: Navigation complete; url='http://www.wxwidgets.org/'
13:33:33: Title changed; title='Navigation Canceled'
13:33:33: Document loaded; url='http://www.wxwidgets.org/'
13:34:12: Navigation request to 'http://localhost:57588/stations.html' (target='')
13:34:12: Error; url='http://localhost:57588/stations.html', error='wxWEBVIEW_NAV_ERR_CONNECTION (INET_E_DOWNLOAD_FAILURE)'
After searching in vain for methods that could be used to configure the iWebBrowser2 instance, I have decided to dump the Trident engine altogether and managed to get wxWebViewChromium to work. If anyone faces something similar to this, they need to be aware that the current version of wxWebViewChromium do not appear to work with the latest version of CEF.
Note: not an answer, but a comment/question to #Jon Trauntvein, because I don't have enough reputation to comment
I too decided to drop the wxWebView IE engine because it does not render Google Maps polygons.
discussed here, if you want to know
https://forums.wxwidgets.org/viewtopic.php?f=1&t=43186
so, I am trying to build a current CEF build
https://bitbucket.org/chromiumembedded/cef
into wxWebViewChromium
https://github.com/sjlamerton/wxWebViewChromium
but this project is 4 years old and the CEF API changed.
Would you care to post here the changes you made to wxWebViewChromium ?
thanks

NSURLSession with share extension returns -995 on OSX

I'm trying to upload data using NSURLSession with a background task from an OSX share extension.
As soon as I start the task, by delegate is called back with the world's least helpful error message:
The operation couldn’t be completed. (NSURLErrorDomain error -995.)
There's no other information in the NSError object, nor in the console.
After scouring the internet, the only clue I have is to make sure that I've set up the configuration.sharedContainerIdentifier correctly, however I've already done that:
let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier(uniqueId)
configuration.sharedContainerIdentifier = Config.appGroupName
urlSession = NSURLSession.init(configuration: configuration, delegate: self, delegateQueue: nil)
I then prepare the request and create the task:
let task = self.urlSession!.dataTaskWithRequest(request)
self.tasks.append(task)
task.resume()
Note that everything works perfectly when from my main app. It's just the sharing extension that fails.
What other problems could cause error -995?
(Bear with me, I don't have rep yet for a comment so I have to answer, and notwithstanding the possibility you've found a bug, the last part I'm adding might help others)
When you're using an NSURLSession any background upload/download that completes will launch your main application. This is detailed in the Common Scenarios page.
As you show you've done, you need to set the NSURLSessionConfiguration with a sharedContainerIdentifier:
let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier(uniqueId)
configuration.sharedContainerIdentifier = Config.appGroupName
urlSession = NSURLSession.init(configuration: configuration, delegate: self, delegateQueue: nil)
You also need to ensure that both your app extension and your main app are all triple-checked in the 'App Groups' option in Xcode (I'm looking at Xcode 8.1), which means:
The app group name is the same for both app and extension(!)
the check beside Add the App Group entitlements in the entitlement file
the check beside Add the App Groups feature to your App ID
the check beside Add App Groups to your App ID
And the checks need to be there on both app and extension.
I'm a bit rusty on adding these but my recollection is these aren't listed in the right order, e.g. you have to 'Add App Groups to your ID' before you can check them in both app and extension, but I could be wrong.
Advanced - Thirdparty libraries in app extensions.
Looking at the github project nst/STTwitter, a third-party Twitter REST library, they needed to add a configurable group ID to allow setting the NSURLSessionConfiguration sharedContainerIdentifier to the library user's group ID.
I may again be mistaken but this seems like it would be a general problem when using thirdparty libraries in an app extension - e.g. I've just now come across this error when trying to use the ChromeCast SDK and this could be the kick in the pants.

XPCServices not updating the code

I create project for os x application with xpcservices that run by loginItems. that's mean the service is founded in the app in the path:{APP_NAME}.app/Contents/Library/LoginItems
and who is responsible for run the service is the the main app:
NSXPCConnection *connection = [[NSXPCConnection alloc] initWithLoginItemName:#"{SERVICE_NAME}.app" error:&error];
I used the class :NSXPCConnection+LoginItem.h from apple's docs example :
https://developer.apple.com/library/mac/samplecode/AppSandboxLoginItemXPCDemo/Listings/iDecide_NSXPCConnection_LoginItem_h.html
Q:
Why when I update the service code (even just logs) it's not changed?
you should know:
I deleted all the files that related to this projects and service
( I don't used LaunchAgents or LaunchDaemons folders)
I did remove the service by: launchctl remove {SERVICE_LABLE}
I used the Console App for seeing the difference between the version that I'm running
I even bought "cleanMyMac3.app" and did restart and still I run from Xcode the app and still show logs from previous version.
I searched file on the system that related to the service name, and I find few folders that created and I deleted them:
~/Library/Group Containers/{SERVICE_NAME}
~/Library/Containers/{SERVICE_NAME}
~/Library/Caches/{SERVICE_NAME}
~/Library/Saved Application State/{SERVICE_NAME}
I'm not work sandbox
Do you reference the service (XPC service) properly?
i.e. (as per Apples Example)
`NSXPCConnection *connection = [[NSXPCConnection alloc] initWithLoginItemName:#"XYZABC1234.com.example.iDecideHelper.app" error:&error];`
Also as this example is pretty old, if you traverse the XPC requirements you'll notice that some changes need to be made:
Both the containing project (the iOS or OSX App) and the XPC service App ned to be sandboxed
Ideally, the XPC service should be named as: com.theMainApp.identifier.com.whateverServiceName.
So in the Apple example you've listed IDecideHelpers identifier would be: com.example.iDecide.WhateverServiceName. iDecide (the main app) would be com.example.iDecide

OS X App Sandboxing and arbitrary files access - Update to Document-based?

My OS X app (currently not sandboxed) accesses files contained inside a directory set by the user (one chooses the path with a NSOpenPanel and a reference to this path is kept throughout execution). The list of files is generated via NSDirectoryEnumerator and I then read from and write to those files using AVAsset and taglib (in C++ with a bridging header) respectively.
As expected, enabling Sandboxing in Xcode rendered the app useless, the list of files given by NSDirectoryEnumerator is empty and even if it weren't, I would not be able to read from and write to the files. What are the steps I need to take to make my app sandbox-compliant?
Does my app need to be document based? Can my app really be "document-based" since I don't really have proper documents (as in: I don't have a window per file, it doesn't seem to comply to the standard document-based app model)? My app is basically just a table view with files references as rows.
Another important point: can I still use taglib to write to my files if my app is document-based ? I need to pass taglib the path to my file as a string pointer in order for it to work.
Thanks a lot, this topic is quite confusing at the moment.
You don't have to convert your app to be document-based to gain access to user selected files and security scoped bookmarks.
I can think of 2 reasons why your current code does not work in a sandboxed environment:
You don't have the "User Selected File Access" capability set (Xcode > target > Capabilities > App Sandbox > File Access)
You are using the path/NSString based API of the directory enumerator instead of the URL NSURL based one.
A vanilla Xcode project with Sandboxing enabled and the User selected files capabilities set, should enumerate any path obtained via NSOpenPanel:
NSOpenPanel* panel =[NSOpenPanel openPanel];
panel.canChooseDirectories = YES;
[panel beginSheetModalForWindow:self.view.window completionHandler:^(NSInteger result) {
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSURL *directoryURL = panel.URL;
NSDirectoryEnumerator *enumerator = [fileManager
enumeratorAtURL:directoryURL
includingPropertiesForKeys:nil
options:0
errorHandler:nil];
for (NSURL *url in enumerator) {
NSLog(#"url:%#", url);
}
}];
If you want to store the ability to access specific folders from the sandbox across app launch/quit cycles, you will need to store a security scoped bookmark.
This post contains information persisting user selected file/directory access via app scoped bookmark:
Trouble creating Security-Scoped Bookmark
It sounds like the current functionality will convert to Sandboxing just fine.
The user selects the directory via NSOpenPanel (which will invoke something called Powerbox in the Sandboxed environment).
This directory is now writable, as the user has explicitly selected it.
You can even maintain write access to this directory by creating a Security Scoped Bookmark and storing it away between sessions.
This has got nothing at all to do with being Document based; that is an internal design that is unrelated to Sandboxing.

Resources