Using SBApplication to open a URL in Safari? - objective-c

I'm trying to use SBApplication to tell a couple of browsers (Safari and Chrome) to open a given URL. However, the apps just treat it like a file url. Here's the pseudo/JSTalk code I'm using:
var safari = [SBApplication applicationWithBundleIdentifier:#"com.apple.Safari"];
var url = [NSURL URLWithString:#"http://apple.com/"];
[safari open:url]; // results in opening "file:///http/::apple.com:"
Any hints? Making a Safari.h file with sdp ( sdef /Applications/Safari.app | sdp -fh --basename "Safari" ) doesn't really help much to see what I can do.

Just read that you wish to open an URL using multiple browsers. Thus, my answer isn't of help here:
I'd propose to ask NSWorkspace to open the URL:
// make an URL
NSURL *someUrl = [NSURL URLWithString:#"http://my.server.vom/" ];
if ([[NSWorkspace sharedWorkspace] openURL:someURL]) {
NSLog(#"Fine. URL opened.");
} else {
// shouldn't happen
}
Regarding your problem: Did you try to pass a string to Safari, not an NSURL?

Related

WKWebView does not actually follow redirects

I have a simple WKWebView in macOS. I'm facing issues with redirection when visiting a page without www that then redirects to the subdomain www.
As far as I could find out I'd simply have to allow the navigation request and the webView should handle everything itself. But the redirect never actually happens. The webView ends up in a redirect loop, calling didReceiveServerRedirectForProvisionalNavigation: over and over again until finally failing with Error Domain=NSURLErrorDomain Code=-1007 "too many HTTP redirects"
Safari, other browsers and clients do indeed succeed, what makes me believe that it's not a server issue.
Also when I enter the address redirected to directly, it does work without any issues.
I implemented the WKNavigationDelegate protocol as follows:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
if ([navigationAction navigationType] == WKNavigationTypeOther) {
if ([[[[navigationAction request] URL] host] isEqualToString:[[[self webView] URL] host]]) {
decisionHandler(WKNavigationActionPolicyAllow);
NSLog(#"allowed");
return;
}
decisionHandler(WKNavigationActionPolicyCancel);
NSLog(#"cancelled: %#", [navigationAction request]);
}
else {
decisionHandler(WKNavigationActionPolicyAllow);
}
}
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
NSLog(#"provisional navigation started");
}
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation; {
NSLog(#"provisional navigation received redirect");
}
I'm expecting the webView to accept and actually follow the redirect after I answered using WKNavigationActionPolicyAllow.
When I execute a request the following happens:
decidePolicyForNavigationAction: for main domain name
I respond with allow
didStartProvisionalNavigation:
decidePolicyForNavigationAction: for redirect with subdomain
I respond with allow
didReceiveServerRedirectForProvisionalNavigation:
Back to 6.
Do I have to somehow "commit" the redirect or do it manually myself?
Any ideas or did I miss something completely?
Stupid me. Really. Embarrassingly stupid.
My table now has my face embossed.
My original code was cut down for overview until a point where I deleted my issue...
I'm working on a special use case where the host name is not in the URL. I connect to a multi-site web server via it's IP and set the Host header accordingly to get the desired page.
When redirected I copy the request, set the header accordingly and resend the request. Guess what? Responding to a redirect by sending the same Host: header will result in another redirect. Grr.
I'll leave this here for public amusement to a day or two

How to get thumbnails for shared OneDrive files to unauthorized users? This useful OneDrive feature provided in the old API is broken now

My app uses OneDrive API feature to let unauthorized users get thumbnails for shared OneDrive files using old API request:
https:// apis.live.net/v5.0/skydrive/get_item_preview?type=normal&url=[shared_link_to_OneDrive_file]
This feature is broken now (any such links return XMLHttpRequest connection error 0x2eff).
And my Windows Store app can not longer provide this feature.
Anyone can try to check it, link to shared OneDrive file:
https://onedrive.live.com/redir?resid=AABF0E8064900F8D!27202&authkey=!AJTeSCuaHMc45eY&v=3&ithint=photo%2cjpg
links to a preview image for shared OneDrive file (according to old OneDrive API
"Displaying a preview of a OneDrive item" - https:// msdn.microsoft.com/en-us/library/jj680723.aspx):
https://apis.live.net/v5.0/skydrive/get_item_preview?type=normal&url=https%3A%2F%2Fonedrive.live.com%2Fredir%3Fresid%3DAABF0E8064900F8D!27202%26authkey%3D!AJTeSCuaHMc45eY%26v%3D3%26ithint%3Dphoto%252cjpg
generates error: SCRIPT7002: XMLHttpRequest: Network error 0x2eff
Сurrent OneDrive API thumbnail feature:
GET /drive/items/{item-id}/thumbnails/{thumb-id}/{size}
is just for authorized users and can not provide access to thumbnails for shared OneDrive files to unauthorized users
How can a Windows Store app let unauthorized users get thumbnails for shared OneDrive files (videos etc.) using the current OneDrive API?
Any ideas?
You need to make a call to the following API:
GET /drive/items/{item-id}/thumbnails/{thumb-id}/{size}/content
This call needs to use authorization and returns a redirect to a cache-safe thumbnail location. You can then use this new url to serve thumbnails to unauthenticated users.
e.g.
Request:
GET https://api.onedrive.com/v1.0/drive/items/D094522DE0B10F6D!152/thumbnails/0/small/content
Authorization: bearer <access token>
Response:
HTTP/1.1 302 Found
Location: https://qg3u2w.bn1302.livefilestore.com/y3m1LKnRaQvGEEhv_GU3mVsewg_-aizIXDaVczGwGFIqtNcVSCihLo7s2mNdUrKicuBnB2sGlSwMQTzQw7v34cHLkchKHL_5YC3IMx1SMcpndtdb9bmQ6y2iG4id0HHgCUlgctvYsDrE24XALwXv2KWRUwCCvDJC4hlkqYgnwGBUSQ
You can now use the link in the Location header to access the thumbnail without signing in. This url will change only if the contents of the file change.
You can read more in the documentation here.
I just figured it out. It is based on the information in this article from Microsoft...
https://learn.microsoft.com/en-ca/onedrive/developer/rest-api/api/driveitem_list_thumbnails?view=odsp-graph-online
... look at the section, "Getting thumbnails while listing DriveItems." It shows you the relevant JSON return structure from a call such as:
GET /me/drive/items/{item-id}/children?$expand=thumbnails
Basically, the JSON return structure gives you string URL's for each of the thumbnail formats. You then create URLSession's to upload these URL's (once you've converted them from String to URL)
Here is an excerpt of code using Swift (Apple):
////////////////////////////////////////////////////////////////////////////////
//
// Download a thumbnail with a URL and label the URLSession with an ID.
//
func downloadThumbnail(url: URL, id: String) {
// Create a URLSession. This is an object that controls the operation or flow
// control with respect to asynchronous operations. It sets the callback delegate
// when the operation is complete.
let urlSession: URLSession = {
//let config = URLSessionConfiguration.default
let config = URLSessionConfiguration.background(withIdentifier: id)
config.isDiscretionary = true
config.sessionSendsLaunchEvents = true
//config.identifier = "file download"
return URLSession(configuration: config, delegate: self as URLSessionDelegate, delegateQueue: OperationQueue.main)
}()
// Create the URLRequest. This is needed so that "Authorization" can be made, as well
// as the actual HTTP command. The url, on initialization, is the command... along
// with the "GET" setting of the httpMethod property.
var request = URLRequest(url: url)
// Set the Authorization header for the request. We use Bearer tokens, so we specify Bearer + the token we got from the result
request.setValue("Bearer \(self.accessToken)", forHTTPHeaderField: "Authorization")
request.httpMethod = "GET"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
// This initiates the asynchronous data task
let backgroundTask = urlSession.downloadTask(with: request)
//backgroundTask.earliestBeginDate = Date().addingTimeInterval(60 * 60)
backgroundTask.countOfBytesClientExpectsToSend = 60
backgroundTask.countOfBytesClientExpectsToReceive = 15 * 1024
backgroundTask.resume()
}
... of course you need to have the correct "accessToken," (shown above) but you also have to have written the generic callback function for URLSession, which is:
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask,
didFinishDownloadingTo location: URL) {
Swift.print("DEBUG: urlSession callback reached")
// This was the identifier that you setup URLSession with
let id = session.configuration.identifier
// "location" is the temporary URL that the thumbnail was downloaded to
let temp = location
// You can convert this URL into any kind of image object. Just Google it!
}
Cheers, Andreas

View HTTPS page with WebView in Mac OS X application

I'm trying to use the implicit authentication of the StackExchange API, and therefor I need to send the user to https://www.stackexchange.com/oauth?client_id=...&scope=...&redirect_uri=... (with actual values instead of '...'). Easy, just drag out a WebView in Interface Builder and implement -webView:didFinishLoadForFrame: from the WebFrameLoadDelegate protocol to track if we are at the redirect_uri already. That works exactly as I want it to. But the WebView internals don't. An error page from stackexchange.com/oauth:
Application Login Failure
An error occurred while login into an application.
Error Details:
error: invalid_request
error description: OAuth request must be over HTTPS
But I started the URL with https://:
- (void)awakeFromNib {
NSString *oauthAddress = #"https://www.stackexchange.com/oauth?client_id=...&scope=...&redirect_uri=...";
[loginWebView setMainFrameURL:oauthAddress];
}
I can't find any source that says you have to do something else to enable HTTPS on a standard WebView.
It is caused by the WebView internals: in -webView:didFinishLoadForFrame: I NSLog()' the current URL:
- (void)webView:(WebView *)webView didFinishLoadForFrame:(WebFrame *)webFrame {
NSString *currentURL = [[[[webFrame dataSource] request] URL] absoluteString];
NSLog(#"-webView:didStartProvisionalLoadForFrame:");
NSLog(#"Current URL: %#", currentURL);
if ([currentURL hasPrefix:#"https://stackexchange.com/oauth/login_success"]) {
NSLog(#"We did login!");
}
}
Output:
2013-03-05 15:31:55.493 MacOverflow[2164:a0f] -webView:didStartProvisionalLoadForFrame:
2013-03-05 15:31:55.495 MacOverflow[2164:a0f] Current URL: http://stackexchange.com/oauth?client_id=...scope=...&redirect_uri=...
What the?! WebKit removed the 's' from the protocol part of the URL! How to stop WebKit from doing so? I searched Apple's documentation on WebView (with Cmd+f) for 'https' (0 matches), 'ssl' (0 matches) and even 'secure' (again 0 matches). I'm kinda stuck here, but it must be possible. It would be ridiculous to provide such a sophisticated browser control, but force the developer to write a copy for supporting https (which is quite common nowadays IMO)!
How to make an HTTPS request using WebKit's WebView?
This is not related to WebKit.
Remove www. from your URL like so https://stackexchange.com/oauth and you should be fine. At least that works for me.

iTunes Search API - HTTPS artworkUrl?

When I run a query against the iTunes Search API over SSL, most of the URL's returned are provided via HTTPS:
https://itunes.apple.com/search?term=rihanna
However, the artworkUrl results are served over HTTP and updating them manually throws an error since the SSL certificate doesn't match on the domain they're using.
Is there a way to grab these images over HTTPS instead of HTTP?
You have to replace the sub domain:
http://is<n> with https://is<n>-ssl
Example:
http://is5.mzstatic.com/image/thumb/Music117/v4/dd/48/4a/dd484afb-2313-0a1a-ccf1-ff28a02ae2ca/source/100x100bb.jpg
to
https://is5-ssl.mzstatic.com/image/thumb/Music117/v4/dd/48/4a/dd484afb-2313-0a1a-ccf1-ff28a02ae2ca/source/100x100bb.jpg
iTunes does not support the album art or song previews over HTTPS (yet).
The change over of the tools and links to HTTPS was recent (only four months ago):
http://www.apple.com/itunes/affiliates/resources/blog/secure-links-to-itunes---content-and-tools.html
New to SO and Swift - stumbled over this problem until finding this Q, and the answers above. The following worked for me:
func withHTTPS() -> URL? {
var components = URLComponents(url: self, resolvingAgainstBaseURL: true)
components?.scheme = "https"
let host = (components?.host)!
components?.host = host.replacingOccurrences(of: ".", with: "-ssl.", options: .caseInsensitive, range: host.range(of: "."))
return components?.url
}
called using:
guard let url = item.artworkURL.withHTTPS() else { return }

LinkedIn framework for ios cannot log in

I have to integrate linkedIn sharing in my app, I will be using this framework.
It has a sample project. I open it, set up my apikey and secret key but the authorisation doesn't happen. Login window is opened and immediately closed,when I click get linkedIn profile. Also when I set up my linkedIn app, what should I put into JavaScript API domain? Now I put:
<script type="text/javascript" src="http://platform.linkedin.com/in.js">
api_key: myapikey
authorize: true
</script>
- (void)initLinkedInApi
{
apikey = #"myapikeys";
secretkey = #"mysecretkey";
self.consumer = [[OAConsumer alloc] initWithKey:apikey
secret:secretkey
realm:#"http://api.linkedin.com/"];
requestTokenURLString = #"https://api.linkedin.com/uas/oauth/requestToken";
accessTokenURLString = #"https://api.linkedin.com/uas/oauth/accessToken";
userLoginURLString = #"https://www.linkedin.com/uas/oauth/authorize";
linkedInCallbackURL = #"hdlinked://linkedin/oauth";
requestTokenURL = [[NSURL URLWithString:requestTokenURLString] retain];
accessTokenURL = [[NSURL URLWithString:accessTokenURLString] retain];
userLoginURL = [[NSURL URLWithString:userLoginURLString] retain];
}
And also I get this error:
Unbalanced calls to begin/end appearance transitions for .
You shouldn't need to put any javascript in the file at all. The sample client (I just checked to make sure it works in the latest XCode and with IOS5. All you need to do is put in your key and secret and it should just run in the simulator and on a dev device.
Why are you adding javascript into the code?