LinkedIn framework for ios cannot log in - objective-c

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?

Related

WKWebview cookie issue?

Background:
I'm upgrading my app to use WKWebview from UIWebview as it will no longer be accepted by App Store
The App Store will no longer accept new apps using UIWebView as of April 2020 and app updates using UIWebView as of December 2020.
Issue:
What happen is, I'm getting cookie return from Webview (WKWebview) after logged in. I will retrieve a token I need for API firing, however I'm constantly hitting HTTP 401 status for all the API(s) fired.
If I revert back to UIWebview, and repeat the same for login but re-using the SAME TOKEN from WKWebview. I'm getting HTTP 200 status. Purpose of re-using same token is to prove that is a valid token.
Noted that, I have not make any changes to the method calling API. It remains the same for both WKWebview and UIWebview. (Including the object request for POST method)
Am I missing something in WKWebview?
Do I need to set cookie or allow anything in specific?
Code snippet:
<WebView
style={{ width: this.state.webviewWidth }}
ref={(component) => {
this.webviewRef = component;
}}
source={{ uri: this.state.url }}
onLoadStart={this.webviewOnLoadStart}
onLoad={this.webviewOnLoadEnd}
onNavigationStateChange={this.onNavigationStateChange}
useWebKit={true}
sharedCookiesEnabled={true}
/>
Pacakge.json
"react-native": "0.61.5",
"react-native-webview": "^10.3.2",
"#react-native-community/cookies": "^3.0.0",
Apparently the issue is that WKWebview does not handle cookie passing into the request header for us. Hence I received 401 authentication failure every time when I reach the server.
Unfortunately React-Native-Webview does not has a way to handle this cookie header passing out of the box (Please correct me if I'm wrong). I'm fully aware of this 'custom header' function provided within the lib, unfortunately it didn't work as expected. The cookie is still not part of the request header.
My solution to this is as follow, did under method decidePolicyForNavigationAction:
Dive into native lib (React-Native-Webview)
Loop through all existing cookies within websiteDataStore.httpCookieStore
Look for my cookie (of course, you should know your cookie name)
Append the cookie into the HTTPHeaderField to your http request
Load the http request again!
if (#available(iOS 11.0, *)) {
[webView.configuration.websiteDataStore.httpCookieStore getAllCookies:^(NSArray<NSHTTPCookie *> * _Nonnull cookies) {
NSLog(#"All cookies in websiteDataStore %#", cookies);
for(NSHTTPCookie *cookie in cookies){
if([cookie.name isEqualToString:#"coookieName"]){
if([navigationAction.request valueForHTTPHeaderField:#"Cookie"] != nil ){
}else{
NSMutableURLRequest *req = [request mutableCopy];
NSString *newCookie = [NSString stringWithFormat:#"cookieName=%#" , cookie.value];
// As you can see, I'm appending the cookie value into header myself
[req addValue:newCookie forHTTPHeaderField:#"Cookie"];
[req setHTTPShouldHandleCookies:YES];
[webView loadRequest:req];
return;
}
}
}
}];
} else {
// Fallback on earlier versions
}

Facebook login (xcode8) Swift3 Not working

I try every solution from internet for this problem .
I use : Version 8.0 beta 6 (8S201h) Swift 3
I setup :
Info.plist from facebook dev site with current app data ,
AppDelegate ,
Put FBlogin btn (also try custom FB login btn) ,
import FB SDK (last) ,
Single Sign On YES - facebook dev
set localhost for App domain
I add also web login component (in ios ap i put webview), to try alternative solution . Not working...
Please go to repo :
this is the link of project :
https://github.com/zlatnaspirala/FBLoginSwift3
I post this question on facebook dev help page and they tell me to
turn on KayChain Sharing . This help me to move from dead point.
I have some success with fbsdkloginmanager with popup login windows.
After entering email and pass in popup app show -already authorized ...
I press confirm i got my user name , friends (logged in )etc.
But this login.loginBehavior = FBSDKLoginBehavior.native and native button (delegate) not woking ..
New error log :
-canOpenURL: failed for URL: "fbauth2:/" - error: "(null)"
screenshoot1 :
This is working code but works slow also error log and popup(screenshoot1) are still here :
var login = FBSDKLoginManager()
// login.loginBehavior = FBSDKLoginBehavior.native
login.loginBehavior = FBSDKLoginBehavior.web
// login.logOut()
login.logIn(withReadPermissions: ["public_profile", "email", "user_friends"], from: self ) {
(loginResult: FBSDKLoginManagerLoginResult?, error: Error?) in
if (error != nil) {
print("Process error2")
}
else if (loginResult?.isCancelled)! {
print("Cancelled2")
}
else {
print("Logged in2")
self.showUserData()
}
}

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

Google login in PHP backend and JS frontend

Front end is 100% JS. User click on sign in button and an authResult['code'] is received and send via ajax to localhost/api/user/login which has the following content:
$code = $data['code'];
require_once 'Google/Client.php';
$client = new Google_Client();
$client->setClientId('xxxxxx');
$client->setClientSecret('xxxxx');
$client->setRedirectUri('http://localhost:8080');
$client->setScopes('email'); //Why do I need this? I already set scope in JS.
$client->authenticate($code); //It fails here. with no error. just 400 bad request.
$token = json_decode($client->getAccessToken());
$reqUrl = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=' .
$token->access_token;
$req = new Google_HttpRequest($reqUrl);
$tokenInfo = json_decode(
$client::getIo()->authenticatedRequest($req)->getResponseBody());
//Check errors.
//Save user personal info in database
//Set login sessions
Why do I need to set scopes if I already set them in javascript?
Why is it failing when authenticate function is called? Im getting no erros.
Why do I need a setRedirectUri() when it is on the backend?
You don't need to set scopes in this case.
(see answer 3, but also): Check your client ID matches the one used in the Javascript, and that the client secret is exactly as in the console (no trailing/leading spaces).
Changing your redirecturi to 'postmessage' - this is the string used when the code was generated via the Javascript process.
You can also try manually constructing the URL and calling it with curl to make sure everything is as you expect: https://developers.google.com/accounts/docs/OAuth2WebServer#handlingtheresponse

Using SBApplication to open a URL in Safari?

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?