LinkedIn login using LinkedinSwift not working suddenly - ios

i am using LinkedinSwift last one year but now redirect to app is not working got no valid session error.but browser working fine.any solutions available.thanks in advance.My code is below
linkedinHelper.authorizeSuccess({ [unowned self] (lsToken) -> Void in
self.linkedinHelper.requestURL("https://api.linkedin.com/v2/me", requestType: LinkedinSwiftRequestGet, success: { (response) -> Void in
print("Request success with response: \(response)")
DispatchQueue.main.async() {
//let data: NSData = response.data.data(using: String.Encoding.utf8)! as NSData
do {
let json = response.jsonObject
if let dictionaryJson = json as NSDictionary?{
print(dictionaryJson)
}
} catch {
print(error)
}
// print(response?.statusCode)
}
// self.writeConsoleLine("Request success with response: \(response)")
}) { [unowned self] (error) -> Void in
// self.writeConsoleLine("Encounter error: \(error.localizedDescription)")
}
// self.writeConsoleLine("Login success lsToken: \(lsToken)")
}, error: { [unowned self] (error) -> Void in
// self.writeConsoleLine("Encounter error: \(error.localizedDescription)")
}, cancel: { [unowned self] () -> Void in
// self.writeConsoleLine("User Cancelled!")
})
}

LinkedIn is closed support for SDK from march1,2019 onwards.
Visit https://engineering.linkedin.com/blog/2018/12/developer-program-updates

here is simple solution
import UIKit
import LinkedinSwift
class ViewController: UIViewController {
private let linkedinHelper = LinkedinSwiftHelper(configuration: LinkedinSwiftConfiguration(clientId: "Your client id", clientSecret: "yout clientSecret", state: "DLKDJF46ikMMZADfdfds", permissions: ["r_basicprofile", "r_emailaddress"], redirectUrl: "your project or your company any project url"))
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func btnClicked(_ sender: UIButton) {
linkedinHelper.authorizeSuccess({ (token) in
print(token)
//This token is useful for fetching profile info from LinkedIn server
self.linkedinHelper.requestURL("https://api.linkedin.com/v1/people/~:(id,first-name,last-name,email-address,picture-url,picture-urls::(original),positions,date-of-birth,phone-numbers,location)?format=json", requestType: LinkedinSwiftRequestGet, success: { (response) -> Void in
print(response)
//parse this response which is in the JSON format
// self.linkedinHelper.logout() //logout session
let cookie = HTTPCookie.self
let cookieJar = HTTPCookieStorage.shared
for cookie in cookieJar.cookies! {
// print(cookie.name+"="+cookie.value)
cookieJar.deleteCookie(cookie)
}
}) {(error) -> Void in
print(error.localizedDescription)
//handle the error
}
}, error: { (error) in
print(error.localizedDescription)
//show respective error
}) {
//show sign in cancelled event
}
}
}
and add method in Appdelegate
import LinkedinSwift
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
if LinkedinSwiftHelper.shouldHandle(url) {
return LinkedinSwiftHelper.application(app, open: url, sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String, annotation: options[UIApplication.OpenURLOptionsKey.annotation])
}
return true
}
just need to add pod:-
pod 'LinkedinSwift'

Related

How to handle the redirect URLs for the PianoID SDK iOS?

When I try to connect to Facebook in my iOS application, the app redirects me to the Facebook app and then there is a loop between the two apps, meaning that the user is being sent back and forth between the two apps without being able to complete the login process. I suspect that there is something missing in my code to properly handle the redirect URLs for the PianoID SDK and I would like to know what needs to be done to fix this issue.
this is my appDelegate class :
#objc class AppDelegate: FlutterAppDelegate, PianoIDDelegate {
private var flutterResult: FlutterResult? = nil
#Published private(set) var initialized = false
#Published private(set) var token: PianoIDToken?
var cookiessseion = ""
var startdate = ""
var enddate = ""
var pianoToken=""
func pianoID(_ pianoID: PianoOAuth.PianoID, didSignInForToken token: PianoOAuth.PianoIDToken!, withError error: Error!) {}
func pianoID(_ pianoID: PianoOAuth.PianoID, didSignOutWithError error: Error!) {}
func pianoIDSignInDidCancel(_ pianoID: PianoOAuth.PianoID) {}
override func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
PianoID.shared.endpointUrl = Settings.endpoint.api
PianoID.shared.aid = Settings.aid
PianoID.shared.isSandbox = true
PianoID.shared.signUpEnabled = true
PianoID.shared.googleClientId = Settings.clientId
PianoID.shared.delegate = self
PianoOAuth.PianoIDApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
GeneratedPluginRegistrant.register(with: self)
let name = Bundle.main.infoDictionary?["CFBundleName"]
let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"]
GEMConfig.sharedInstance().setAppInfo(name as? String, version: version as? String)
//FirebaseApp.configure()
guard let controller = window?.rootViewController as? FlutterViewController else {
fatalError("rootViewController is not type FlutterViewController")
}
let Channel = FlutterMethodChannel(name: "flutter.native/helper", binaryMessenger: controller.binaryMessenger)
Channel.setMethodCallHandler({
[weak self] (call: FlutterMethodCall, result: #escaping FlutterResult) -> Void in
if(call.method == "testpiano"){
self?.initPianoID()
self?.flutterResult = result
} else {
result(FlutterMethodNotImplemented)
}
})
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
/// Sign In callback
func signIn(result: PianoIDSignInResult!, withError error: Error!) {
if let r = result {
token = r.token
do {
let PianoIDTokenString = try JSONParserSwift.getJSON(object: token)
self.flutterResult?(PianoIDTokenString)
} catch {
print("Unexpected data error: \(error)")
}
} else {
}
}
/// Sign Out callback
func signOut(withError error: Error!) {
token = nil
}
/// Cancel callback
func cancel() {
}
private func initPianoID() {
PianoID.shared.signIn()
}
func openSettings(alert: UIAlertAction!) {
if let url = URL.init(string: UIApplication.openSettingsURLString) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}
override public func applicationDidBecomeActive(_ application: UIApplication) {
debugPrint("applicationDidBecomeActive")
if #available(iOS 14, *) {
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
ATTrackingManager.requestTrackingAuthorization { status in
}
}
}
}
}
extension Date {
func currentTimeMillis() -> Int64 {
return Int64(self.timeIntervalSince1970)
}
}
And this is the documentation : link

How to Show Firebase Auth User UID and also my Firestore doc uid as Stripe customer id

I am trying to Show Firestore doc uid as Stripe custommer id.and to link Stripe to Firestore cloud but it show error - "error loading page: failed to decode response from the server" as shown in the image -
My cloud function i.e. index.js -
const admin = require('firebase-admin');
const express = require('express')
admin.initializeApp();
const functions = require('firebase-functions');
const stripe = require('stripe') ("sk_________");
// When a user is created, register them with Stripe
exports.createStripeCustomer = functions.auth.user().onCreate(async (user) => {
const customer = await stripe.customers.create({email: user.email});
return admin.firestore().collection('stripe_customers').doc(user.uid).set({customer_id: customer.id});
});
exports.createPaymentIntent = functions.https.onCall(async (req, res) => {
const amount = req.amount;
const customer = req.customer;
console.log(customer)
const paymentIntent = await stripe.paymentIntents.create({
amount: 1099,
currency: 'usd',
});
const clientSecret = paymentIntent.clientSecret
console.log(clientSecret)
return clientSecret
});
exports.getPaymentMethods = functions.https.onCall(async (req, res) => {
const customer = req.customer;
const type = "card"
stripe.paymentMethods.list({customer : customer, type: type}, function(err, paymentMethods) {
if (err !== null) {
console.log("ERROR")
} else {
return paymentMethods
}
return
})
});
exports.createEphemeralKey = functions.https.onCall(async(data, context) => {
const stripeVersion = data.stripe_version;
const customerId = data.customer_id;
return stripe.ephemeralKeys.create(
{customer: customerId},
{stripe_version: stripeVersion}
).then((key) => {
return key
}).catch((err) => {
console.log(err)
})
})
My CheckoutViewController -
import UIKit
import Stripe
import Firebase
let backendUrl = "https://fireupgoods-a0036.firebaseio.com/"
class CheckoutViewController: UIViewController {
var paymentIntentClientSecret: String?
lazy var cardTextField: STPPaymentCardTextField = {
let cardTextField = STPPaymentCardTextField()
return cardTextField
}()
lazy var payButton: UIButton = {
let button = UIButton(type: .custom)
button.layer.cornerRadius = 5
button.backgroundColor = .systemBlue
button.titleLabel?.font = UIFont.systemFont(ofSize: 22)
button.setTitle("Pay now", for: .normal)
button.addTarget(self, action: #selector(pay), for: .touchUpInside)
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
StripeAPI.defaultPublishableKey = "pk_test_TYooMQauvdEDq54NiTphI7jxpk_test_51HmAsMFzRM1fSBZ2tTT1SxPxRBzParFfjm6s0aXD0F5dYLeOSVCKtiZ4lq0TGwJxPhHpsq6Hga7I0QzRWisPYMdj00bDxAMTKf"
view.backgroundColor = .white
let stackView = UIStackView(arrangedSubviews: [cardTextField, payButton])
stackView.axis = .vertical
stackView.spacing = 20
stackView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(stackView)
NSLayoutConstraint.activate([
stackView.leftAnchor.constraint(equalToSystemSpacingAfter: view.leftAnchor, multiplier: 2),
view.rightAnchor.constraint(equalToSystemSpacingAfter: stackView.rightAnchor, multiplier: 2),
stackView.topAnchor.constraint(equalToSystemSpacingBelow: view.safeAreaLayoutGuide.topAnchor, multiplier: 2),
])
startCheckout()
}
func displayAlert(title: String, message: String, restartDemo: Bool = false) {
DispatchQueue.main.async {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .cancel))
self.present(alert, animated: true, completion: nil)
}
}
func startCheckout() {
// Create a PaymentIntent as soon as the view loads
let url = URL(string: backendUrl + "create-payment-intent")!
let json: [String: Any] = [
"items": [
["id": "xl-shirt"]
]
]
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try? JSONSerialization.data(withJSONObject: json)
let task = URLSession.shared.dataTask(with: request, completionHandler: { [weak self] (data, response, error) in
guard let response = response as? HTTPURLResponse,
response.statusCode == 200,
let data = data,
let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any],
let clientSecret = json["clientSecret"] as? String else {
let message = error?.localizedDescription ?? "Failed to decode response from server."
self?.displayAlert(title: "Error loading page", message: message)
return
}
print("Created PaymentIntent")
self?.paymentIntentClientSecret = clientSecret
})
task.resume()
}
#objc
func pay() {
guard let paymentIntentClientSecret = paymentIntentClientSecret else {
return;
}
// Collect card details
let cardParams = cardTextField.cardParams
let paymentMethodParams = STPPaymentMethodParams(card: cardParams, billingDetails: nil, metadata: nil)
let paymentIntentParams = STPPaymentIntentParams(clientSecret: paymentIntentClientSecret)
paymentIntentParams.paymentMethodParams = paymentMethodParams
// Submit the payment
let paymentHandler = STPPaymentHandler.shared()
paymentHandler.confirmPayment(paymentIntentParams, with: self) { (status, paymentIntent, error) in
switch (status) {
case .failed:
self.displayAlert(title: "Payment failed", message: error?.localizedDescription ?? "")
break
case .canceled:
self.displayAlert(title: "Payment canceled", message: error?.localizedDescription ?? "")
break
case .succeeded:
self.displayAlert(title: "Payment succeeded", message: paymentIntent?.description ?? "")
break
#unknown default:
fatalError()
break
}
}
}
}
extension CheckoutViewController: STPAuthenticationContext {
func authenticationPresentingViewController() -> UIViewController {
return self
}
}
screenshot of the error -
Firebase code which writes my Firebase Auth User UID to Firestore Document ID is -
import UIKit
import Firebase
import FirebaseFirestore
class UserIdtoFirestoreViewController: UIViewController {
let db = Firestore.firestore()
var ref: DocumentReference? = nil
let email = Auth.auth().currentUser!.email
let id = Auth.auth().currentUser!.uid
let fullName = Auth.auth().currentUser!.displayName
#IBAction func GetUserId(_ sender: UIButton) {
db
.collection("users")
.document(id)
.setData([
"email":email,"fullName":fullName])
}
}
The above code writes my Auth User UIDfrom here (see image below):-
to here (see image below):-
As you can see in the 2 images above, the Auth User UID (which begins with 2k3k) gets written to Firestore Document ID. I want the same ID to be shown in Stripe customer ID and logs and events in Stripe, but as you can see below, there is nothing on the Stripe Dashboard: -
How to sort it out ?
I know I am missing out on many things, but my immediate issue is to make the error go away and the Firestore Document ID to be added as Stripe customer id. programmatically.
Any help will be appreciated.
Edit: I am also adding AppDelegate code and MyAPIClient code below:-
AppDelegate code -
import UIKit
import GoogleSignIn
import Firebase
import CoreData
import Stripe
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Stripe.setDefaultPublishableKey( "pk_test_51HmAsMFzRM1fSBZ2tTT1SxPxRBzParFfjm6s0aXD0F5dYLeOSVCKtiZ4lq0TGwJxPhHpsq6Hga7I0QzRWisPYMdj00bDxAMTKf")
FirebaseApp.configure()
// Override point for customization after application launch.
GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID
GIDSignIn.sharedInstance().delegate = self
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return GIDSignIn.sharedInstance().handle(url as URL?)
}
func sign(_ signIn: GIDSignIn!,
didSignInFor user: GIDGoogleUser!,
withError error: Error!) {
// Check for sign in error
if let error = error {
if (error as NSError).code == GIDSignInErrorCode.hasNoAuthInKeychain.rawValue {
print("The user has not signed in before or they have since signed out.")
} else {
print("\(error.localizedDescription)")
}
return
}
// Get credential object using Google ID token and Google access token
guard let authentication = user.authentication else {
return
}
let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken,
accessToken: authentication.accessToken)
// Authenticate with Firebase using the credential object
Auth.auth().signIn(with: credential) { (authResult, error) in
if let error = error {
print("Error occurs when authenticate with Firebase: \(error.localizedDescription)")
}
// Post notification after user successfully sign in
// NotificationCenter.default.post(name: .signInGoogleCompleted, object: nil)
}
}
func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!, withError error: Error!) {
// Perform any operations when the user disconnects from app here.
print("User has disconnected")
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
MyAPIClient code:-
import Stripe
import UIKit
class MyAPIClient: NSObject, STPCustomerEphemeralKeyProvider {
let baseURL = URL(string: "https://api.stripe.com")!
func createCustomerKey(withAPIVersion apiVersion: String, completion: #escaping STPJSONResponseCompletionBlock) {
let url = self.baseURL.appendingPathComponent("ephemeral_keys")
var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false)!
urlComponents.queryItems = [URLQueryItem(name: "api_version", value: apiVersion)]
var request = URLRequest(url: urlComponents.url!)
request.httpMethod = "POST"
let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
guard let response = response as? HTTPURLResponse,
response.statusCode == 200,
let data = data,
let json = ((try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any]) as [String : Any]??) else {
completion(nil, error)
return
}
completion(json, nil)
})
task.resume()
}
}
Thanks.

Resend Code using Firebase Authentication in Swift

As there is no direct method to resend code once the code has already been sent , I am trying to resend it once again with following method :
func sendOTPGetVerfID(phoneNum: String, completion: #escaping((_ verificationID: String?, _ error: Error?) -> Void)) {
PhoneAuthProvider.provider().verifyPhoneNumber( phoneNum , uiDelegate: nil) { (verificationID, error) in
if let error = error {
QL1(error.localizedDescription)
completion(nil, error)
return
}
// Sign in using the verificationID and the code sent to the user
// ...
QL1("VerificationID : \(verificationID ?? "")")
completion(verificationID,nil)
}
}
Issue here is, I am not able to receive the verificationID second time, calling the above method
Any help appreciated
Call requestOtp() method on resend OTP button click.
import FirebaseAuth
func requestOtp() {
let phNo = "Your phone number"
PhoneAuthProvider.provider().verifyPhoneNumber(phNo, uiDelegate: nil) { (verificationID, error) in
if let error = error {
print(error.localizedDescription)
return
}
// Sign in using the verificationid and the code sent to the user
// ...
UserDefaults.standard.set(verificationID, forKey: "authVerificationID")
}
}
Verify Code with Auth:
func verifyNumberWith(verificationCode: String) {
let verificationID=UserDefaults.standard.string(forKey:"authVerificationID")
let credential = PhoneAuthProvider.provider().credential(
withVerificationID: verificationID ?? "",
verificationCode: verificationCode)
Auth.auth().signIn(with: credential) { (authResult, error) in
//Do your actions.
}
}

getAllVoiceShortcuts function returns twice

I'm fetching voiceShortcurts related with my app. Below function goes into completion block twice. It returns true at first, then false which true is the right one. Why It goes into completion block twice?
public static func updateVoiceShortcuts(completion: #escaping ((_ haveShortcutAlready: Bool) -> Void)) {
INVoiceShortcutCenter.shared.getAllVoiceShortcuts { (voiceShortcutsFromCenter, error) in
if let voiceShortcutsFromCenter = voiceShortcutsFromCenter {
self.voiceShortcuts = voiceShortcutsFromCenter
completion(true)
} else {
if let error = error as NSError? {
print(error)
}
completion(false)
}
}
}

Callback in ios not returning for authentication

I'm using swifter to grab the access token
swifter.authorize(with: URL(string: "callback://")!, presentFrom: self, success: { accessToken, response in
print("HELLO")
print(accessToken)
// ...
}, failure: { error in
// ...
})
I can log in successfully because the app opens up SFSafariViewController, but then I'm not directed back to my app, and the success callback is never being called
here's the code for swifter, I see that presentFrom is suppose to be SFSafariViewController, but the delgate methods for SFSafariViewController aren't being triggered
public func authorize(with callbackURL: URL, presentFrom presentingViewController: UIViewController? , success: TokenSuccessHandler?, failure: FailureHandler? = nil) {
self.postOAuthRequestToken(with: callbackURL, success: { token, response in
var requestToken = token!
NotificationCenter.default.addObserver(forName: .SwifterCallbackNotification, object: nil, queue: .main) { notification in
NotificationCenter.default.removeObserver(self)
presentingViewController?.presentedViewController?.dismiss(animated: true, completion: nil)
let url = notification.userInfo![CallbackNotification.optionsURLKey] as! URL
let parameters = url.query!.queryStringParameters
requestToken.verifier = parameters["oauth_verifier"]
self.postOAuthAccessToken(with: requestToken, success: { accessToken, response in
self.client.credential = Credential(accessToken: accessToken!)
success?(accessToken!, response)
}, failure: failure)
}
let authorizeURL = URL(string: "oauth/authorize", relativeTo: TwitterURL.oauth.url)
let queryURL = URL(string: authorizeURL!.absoluteString + "?oauth_token=\(token!.key)")!
if #available(iOS 9.0, *) , let delegate = presentingViewController as? SFSafariViewControllerDelegate {
let safariView = SFSafariViewController(url: queryURL)
safariView.delegate = delegate
presentingViewController?.present(safariView, animated: true, completion: nil)
} else {
UIApplication.shared.openURL(queryURL)
}
}, failure: failure)
}
does it just wait and say "redirecting you back to the application" but never actually goes back to application?
You need to add both of these functions to the Appdelegate
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
Swifter.handleOpenURL(url)
return true
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
Swifter.handleOpenURL(url as URL)
return true
}
also try look at this for further assistance: How to Authorize Twitter with Swifter

Resources