There seem to be lots of changes at IG. Many OAuth2 repos, all seem to have bugs, or really not easily converted to Swift3. Wondering if anyone has a solution for moving to Swift3 and working with the latest changes at Instagram?
Solutions most welcome. OAuth2 implementation seems to one of the more complicated things out there. Surprised that IG has not offered their own example docs on how to do this with iOS. They only have docs for web based solutions.
Maybe something brewing there? Zillions of coders they have on staff. But for now, on the hunt for a (dare I say?) simple solution.
thanks a million. :-)
For Swift 3:
Update: April 17 2017: Because of broken dependencies, the installation by Pods is no longer working. Therefore I have ripped the needed content and created a new Github project using a Bridging Header and stored all the needed files within the project. If you clone or download the github project, you'll instantly be able to login to Instagram.
To use those files in your project, simply drag and drop all the files from the SimpleAuth folder to your project, make sure to mark copy item if needed
Also you need to disable Disable implicit oAuth within the Instagram developer console.
Then you either copy/paste my code from the Bridging Header into your or you use mine. Set the Bridging Header at the Target's Build Settings.
Everything else works as before:
I have a struct for the Instagram Account:
struct InstagramUser {
var token: String = ""
var uid: String = ""
var bio: String = ""
var followed_by: String = ""
var follows: String = ""
var media: String = ""
var username: String = ""
var image: String = ""
}
The function to receive the token:
typealias JSONDictionary = [String:Any]
var user: InstagramUser?
let INSTAGRAM_CLIENT_ID = "16ee14XXXXXXXXXXXXXXXXXXXXXXXXX"
let INSTAGRAM_REDIRECT_URI = "http://www.davidseek.com/just_a_made_up_dummy_url" //just important, that it matches your developer account uri at Instagram
extension ViewController {
func connectInstagram() {
let auth: NSMutableDictionary = ["client_id": INSTAGRAM_CLIENT_ID,
SimpleAuthRedirectURIKey: INSTAGRAM_REDIRECT_URI]
SimpleAuth.configuration()["instagram"] = auth
SimpleAuth.authorize("instagram", options: [:]) { (result: Any?, error: Error?) -> Void in
if let result = result as? JSONDictionary {
var token = ""
var uid = ""
var bio = ""
var followed_by = ""
var follows = ""
var media = ""
var username = ""
var image = ""
token = (result["credentials"] as! JSONDictionary)["token"] as! String
uid = result["uid"] as! String
if let extra = result["extra"] as? JSONDictionary,
let rawInfo = extra ["raw_info"] as? JSONDictionary,
let data = rawInfo["data"] as? JSONDictionary {
bio = data["bio"] as! String
if let counts = data["counts"] as? JSONDictionary {
followed_by = String(describing: counts["followed_by"]!)
follows = String(describing: counts["follows"]!)
media = String(describing: counts["media"]!)
}
}
if let userInfo = result["user_info"] as? JSONDictionary {
username = userInfo["username"] as! String
image = userInfo["image"] as! String
}
self.user = InstagramUser(token: token, uid: uid, bio: bio, followed_by: followed_by, follows: follows, media: media, username: username, image: image)
} else {
// this handles if user aborts or the API has a problem like server issue
let alert = UIAlertController(title: "Error!", message: nil, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
if error != nil {
print("Error during SimpleAuth.authorize: \(error)")
}
}
}
}
Instagram also says:
Important
Even though our access tokens do not specify an expiration time, your
app should handle the case that either the user revokes access, or
Instagram expires the token after some period of time. If the token is
no longer valid, API responses will contain an
“error_type=OAuthAccessTokenException”. In this case you will need to
re-authenticate the user to obtain a new valid token. In other words:
do not assume your access_token is valid forever.
So handle the case of receiving the OAuthAccessTokenException
This Code bellow I use for facebook and google+, I think it'ill work for Instagram too, maybe some adjusts.
import UIKit
class Signup: UIViewController, UIWebViewDelegate {
let GOOGLE_ID = "xxxxxx.apps.googleusercontent.com"
let GOOGLE_SECRET = "xxxxxxx";
let GOOGLE_REDIRECT_URI="http://yourdomain.com/api/account/googlecallback"
let GOOGLE_TOKEN_URL = "https://accounts.google.com/o/oauth2/token";
let GOOGLE_OAUTH_URL = "https://accounts.google.com/o/oauth2/auth";
let GOOGLE_OAUTH_SCOPE = "profile email";
let GOOGLE_GET_PROFILE = "https://www.googleapis.com/userinfo/v2/me";
let FACEBOOK_ID = "xxxxx";
let FACEBOOK_REDIRECT_URI = "http://yourdomain.com/api/account/facebookcallback";
let FACEBOOK_OAUTH_URL = "https://www.facebook.com/dialog/oauth?client_id=";
let FACEBOOK_OAUTH_SCOPE = "public_profile,email"
let FACEBOOK_GET_PROFILE = "https://graph.facebook.com/me?access_token="
var currentURL: String = ""
var queryString: String = ""
var receivedToken: String = ""
var authCode: String = ""
var authComplete = false
var webV:UIWebView = UIWebView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
#IBAction func google(_ sender: AnyObject) {
AppVars.Provider = "Google"
webV.delegate = self
let url = GOOGLE_OAUTH_URL + "?redirect_uri=" + GOOGLE_REDIRECT_URI + "&response_type=code&client_id=" + GOOGLE_ID + "&scope=" + GOOGLE_OAUTH_SCOPE
let urlString :String = url.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
webV.loadRequest(URLRequest(url: URL(string:urlString)!))
self.view.addSubview(webV)
}
#IBAction func facebook(_ sender: AnyObject) {
AppVars.Provider = "Facebook"
webV.delegate = self
let url = FACEBOOK_OAUTH_URL + FACEBOOK_ID + "&redirect_uri=" + FACEBOOK_REDIRECT_URI + "&scope=" + FACEBOOK_OAUTH_SCOPE + "&display=popup&response_type=token"
let urlString :String = url.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
webV.loadRequest(URLRequest(url: URL(string:urlString)!))
self.view.addSubview(webV)
}
func webView(_ webView: UIWebView, didFailLoadWithError error: Error) {
self.showAlert(self, message: "Internet is not working")
}
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
return true;
}
func webViewDidStartLoad(_ webView: UIWebView) {
}
func webViewDidFinishLoad(_ webView: UIWebView) {
currentURL = (webView.request?.url!.absoluteString)!
if AppVars.Provider == "Google" {
googleSignup((webView.request?.url!)!)
} else {
facebookSignup((webView.request?.url!)!)
}
}
func googleSignup (_ returnCode: URL) {
let url = String(currentURL)
if (url?.range(of: "?code=") != nil && authComplete != true) {
authCode = getQueryItemValueForKey("code", url: returnCode)!
authComplete = true
let paramString = "code=" + authCode + "&client_id=" + GOOGLE_ID + "&client_secret=" +
GOOGLE_SECRET + "&redirect_uri=" + GOOGLE_REDIRECT_URI + "&grant_type=authorization_code"
self.requestServer(urlSource: GOOGLE_TOKEN_URL, params: paramString, requestType: "POST") { (dataResult, errorResult) -> () in
if errorResult != nil {
self.showAlert(self, message: "Internet is not working")
} else {
let dataString:NSString = NSString(data: dataResult as! Data, encoding: String.Encoding.utf8.rawValue)!
let dataResult2 = dataString.data(using: String.Encoding.utf8.rawValue, allowLossyConversion: false)!
do {
let jsonDict = try JSONSerialization.jsonObject(with: dataResult2, options: .allowFragments) as! [String:Any]
if let token = jsonDict["access_token"] as? String {
self.requestServerSignup(self.GOOGLE_GET_PROFILE, param: token, requestType: "GET") { (dataResult, errorResult) -> () in
if errorResult != nil {
self.showAlert(self, message: "Internet is not working")
} else {
let dataString:NSString = NSString(data: dataResult as! Data, encoding: String.Encoding.utf8.rawValue)!
let dataResult2 = dataString.data(using: String.Encoding.utf8.rawValue, allowLossyConversion: false)!
do {
let jsonDict = try JSONSerialization.jsonObject(with: dataResult2, options: .allowFragments) as! [String:Any]
if let name = jsonDict["name"] as? String {
AppVars.NameLogin = name
AppVars.PictureLogin = jsonDict["picture"] as! String
AppVars.EmailLogin = jsonDict["email"] as! String
self.performSegue(withIdentifier: "externalLoginSegue", sender: self)
// show picture, email and name for checking profile
}
} catch {
self.showAlert(self, message: "Internet is not working")
}
}
}
}
} catch {
self.showAlert(self, message: "Internet is not working")
}
}
}
self.webV.removeFromSuperview()
}
}
func facebookSignup(_ returnCode: URL) {
let url = String(currentURL)
if (url?.range(of: "access_token=") != nil && authComplete != true) {
let url2: String = returnCode.absoluteString.replacingOccurrences(of: "#access_token", with: "access_token")
let url3: URL = URL(string: url2)!
authCode = getQueryItemValueForKey("access_token", url: (url3))!
authComplete = true
let paramString = "code=" + authCode + "&client_id=" + GOOGLE_ID + "&client_secret=" +
GOOGLE_SECRET + "&redirect_uri=" + GOOGLE_REDIRECT_URI + "&grant_type=authorization_code"
self.requestServer(urlSource: self.FACEBOOK_GET_PROFILE + authCode + "&fields=name,picture,email", params: paramString, requestType: "GET") { (dataResult, errorResult) -> () in
if errorResult != nil {
self.showAlert(self, message: "Internet is not working")
} else {
let dataString:NSString = NSString(data: dataResult as! Data, encoding: String.Encoding.utf8.rawValue)!
let dataResult2 = dataString.data(using: String.Encoding.utf8.rawValue, allowLossyConversion: false)!
do {
let jsonDict = try JSONSerialization.jsonObject(with: dataResult2, options: .allowFragments) as! [String:Any]
if let name = jsonDict["name"] as? String {
AppVars.NameLogin = name
if let picture = jsonDict["picture"] as? [String:Any] {
if let dataPicture = picture["data"] as? [String:Any] {
if let url = dataPicture["url"] as? String {
AppVars.PictureLogin = url
}
}
}
AppVars.EmailLogin = jsonDict["email"] as! String
self.performSegue(withIdentifier: "externalLoginSegue", sender: self)
// show picture, email and name for checking profile
}
} catch {
self.showAlert(self, message: "Internet is not working")
}
}
}
self.webV.removeFromSuperview()
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func getQueryItemValueForKey(_ key: String, url: URL) -> String? {
guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false) else {
return nil
}
guard let queryItems = components.queryItems else { return nil }
return queryItems.filter {
$0.name == key
}.first?.value
}
func requestServer(urlSource:String, params:String, requestType:String, result:#escaping (_ dataResult:NSData?, _ errorResult:NSError?) -> ()) {
let url: URL = URL(string: urlSource)!
var request = URLRequest(url:url)
request.httpMethod = requestType
request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
if params.characters.count > 0 {
request.httpBody = params.data(using: String.Encoding.utf8)
}
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) -> Void in
DispatchQueue.main.async(execute: { () -> Void in
if error == nil {
result(data as NSData?, nil)
} else {
result(nil, error as NSError?)
}
})
}.resume()
}
}
Related
I am using amazon product advertising api for search product. Installed awscore and alamofire cocopods. Done functionality for getting signature and added parameters for item search to get product images, title and description in table view list.
Here is the code i tried for getting amazon search:
private func signedParametersForParameters(parameters: [String: String]) -> [String: String] {
let sortedKeys = Array(parameters.keys).sorted(by: <)
let query = sortedKeys.map { String(format: "%#=%#", $0, parameters[$0] ?? "") }.joined(separator: "&")
let stringToSign = "GET\nwebservices.amazon.in\n/onca/xml\n\(query)"
print("stringToSign::::\(stringToSign)")
let dataToSign = stringToSign.data(using: String.Encoding.utf8)
let signature = AWSSignatureSignerUtility.hmacSign(dataToSign, withKey: CameraViewController.kAmazonAccessSecretKey, usingAlgorithm: UInt32(kCCHmacAlgSHA256))!
var signedParams = parameters;
signedParams["Signature"] = urlEncode(signature)
print("urlencodesignature::\(urlEncode(signature))")
return signedParams
}
public func urlEncode(_ input: String) -> String {
let allowedCharacterSet = (CharacterSet(charactersIn: "!*'();:#&=+$,/?%#[] ").inverted)
if let escapedString = input.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) {
return escapedString
}
return ""
}
func send(url: String) -> String {
// activityIndicator.startAnimating()
guard let url = URL(string: url) else {
print("Error! Invalid URL!") //Do something else
// activityIndicator.stopAnimating()
return ""
}
print("send URL: \(url)")
let request = URLRequest(url: url)
let semaphore = DispatchSemaphore(value: 0)
var data: Data? = nil
URLSession.shared.dataTask(with: request) { (responseData, _, _) -> Void in
data = responseData
print("send URL session data: \(String(describing: data))")
let parser = XMLParser(data: data!)
parser.delegate = self as? XMLParserDelegate
if parser.parse() {
print(self.results ?? "No results")
}
semaphore.signal()
}.resume()
// activityIndicator.stopAnimating()
semaphore.wait(timeout: .distantFuture)
let reply = data.flatMap { String(data: $0, encoding: .utf8) } ?? ""
return reply
}
public func getSearchItem(searchKeyword: String) -> [String:AnyObject]{
let timestampFormatter: DateFormatter
timestampFormatter = DateFormatter()
timestampFormatter.timeZone = TimeZone(identifier: "GMT")
timestampFormatter.dateFormat = "YYYY-MM-dd'T'HH:mm:ss'Z'"
timestampFormatter.locale = Locale(identifier: "en_US_POSIX")
// let responsegroupitem: String = "ItemAttributes"
// let responsegroupImages:String = "Images"
// activityIndicator.startAnimating()
let operationParams: [String: String] = [
"Service": "AWSECommerceService",
"Operation": "ItemSearch",
"ResponseGroup": "Images,ItemAttributes",
"IdType": "ASIN",
"SearchIndex":"All",
"Keywords": searchKeyword,
"AWSAccessKeyId": urlEncode(CameraViewController.kAmazonAccessID),
"AssociateTag": urlEncode(CameraViewController.kAmazonAssociateTag),
"Timestamp": urlEncode(timestampFormatter.string(from: Date()))]
let signedParams = signedParametersForParameters(parameters: operationParams)
let query = signedParams.map { "\($0)=\($1)" }.joined(separator: "&")
let url = "http://webservices.amazon.in/onca/xml?" + query
print("querydata::::\(query)")
let reply = send(url: url)
print("reply::::\(reply)")
// activityIndicator.stopAnimating()
return [:]
}
Created bridging header file #import .
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
getSearchItem(searchKeyword: searchKeyword)
}
Here is my console output:
My issue is when tapping search button product searched was not listing. What mistake done i don't know. Can anyone help me out of this pls..
According to the documentation:
The HTTPRequestURI component is the HTTP absolute path component of the URI up to, but not including, the query string. If the HTTPRequestURI is empty, use a forward slash ( / ).
HTTPRequestURI is always "/onca/xml" for Product Advertising API. HTTPVerb is either GET or POST.
Try just setting requestURL to "/onca/xml" instead of the full URL you shouldn't be sending the full URL or the query string in this part.
Also you need to percent encode the values that you are sending. You are sending commas in the response group property which should be percent encoded
let operationParams: [String: String] = [
"Service": "AWSECommerceService",
"Operation": "ItemSearch",
"ResponseGroup": urlEncode("Images,ItemAttributes"),
"IdType": "ASIN",
"SearchIndex":"All",
"Keywords": urlEncode(searchKeyword),
"AWSAccessKeyId": urlEncode(CameraViewController.kAmazonAccessID),
"AssociateTag": urlEncode(CameraViewController.kAmazonAssociateTag),
"Timestamp": urlEncode(timestampFormatter.string(from: Date()))]
let stringToSign = "GET\n/onca/xml\n\(query)"
Note: You should be using https instead of http
I am relatively new to integrating APIs into Swift. I have a login page and I am trying to authenticate a user and create a session when they sign in. I found a code online that supposedly works for a lot of people, but I am having trouble actually getting the whole thing to work. I have concluded that something is going wrong beginning near this line which you will see in the code below because at the line before it I am able to get the auth token.
if let data_block = server_response["accessToken"] as? NSDictionary
I am including all of the relevant code and I would like to know what is going wrong, how to successfully authenticate and create the session, and get the segue to actually work.
override func viewDidLoad() {
super.viewDidLoad()
_login_button = "Login"
let preferences = UserDefaults.standard
if(preferences.object(forKey: "session") != nil)
{
LoginDone()
}
else
{
LoginToDo()
}
}
#IBAction func signIn() {
let username = emailLoginTextField.text
let password = passwordLoginTextField.text
if(username == "" || password == "")
{
return
}
if(_login_button == "Logout")
{
let preferences = UserDefaults.standard
preferences.removeObject(forKey: "session")
LoginToDo()
return
} else {
DoLogin(username!, password!)
}
}
func DoLogin(_ user:String, _ psw:String)
{
let url = URL(string: "http://agile-castle-10059.herokuapp.com/authentication")
let session = URLSession.shared
let request = NSMutableURLRequest(url: url!)
request.httpMethod = "POST"
let paramToSend = "username=" + user + "&password=" + psw + "&strategy=" + "local"
request.httpBody = paramToSend.data(using: String.Encoding.utf8)
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(data, response, error) in
guard let _:Data = data else
{
return
}
let json:Any?
do
{
json = try JSONSerialization.jsonObject(with: data!, options: [])
}
catch
{
return
}
guard let server_response = json as? NSDictionary else
{
return
}
//problem occurs around here, nothing happens (assuming the data_block isn't being created for some reason)
if let data_block = server_response["data"] as? NSDictionary
{
if let session_data = data_block["session"] as? String
{
let preferences = UserDefaults.standard
preferences.set(session_data, forKey: "session")
DispatchQueue.main.async (
execute:self.LoginDone
)
}
}
})
task.resume()
}
func LoginToDo()
{
_login_button = "Login"
}
func LoginDone()
{
self.shouldPerformSegue(withIdentifier: "showHomeViewControllerFromSignIn", sender: self)
_login_button = "Logout"
}
I fixed a few things and figured it out
guard let server_response = json as? NSDictionary else
{
return
}
if let session_data = server_response["accessToken"] as? String
{
let preferences = UserDefaults.standard
preferences.set(session_data, forKey: "accessToken")
DispatchQueue.main.async (
execute:self.LoginDone
)
}
})
task.resume()
}
Im New to Swift and I'm Integrating PayUmoney IOS SDK in swift, Im getting trouble When I'm doing in live its showing hash mismatch (Hash mismatch1) If I'm doing in test its showing invalid merchant key (Invalid key) I struck here from 2 weeks Did so many things and didn't get any solution for this can any one help it would be awesome. Below is my code, Thank you in Advance.
var params : PUMRequestParams = PUMRequestParams.shared()
var utils : Utils = Utils()
params.environment = PUMEnvironment.test;
params.firstname = txtFldName.text;
params.key = "bZf4AOjj";
params.merchantid = "5745303";
params.logo_url = "";
params.productinfo = "Product Info";
params.email = txtFldEmail.text;
params.phone = "";
params.surl = "https://www.payumoney.com/mobileapp/payumoney/success.php";
params.furl = "https://www.payumoney.com/mobileapp/payumoney/failure.php";
if(params.environment == PUMEnvironment.test){
generateHashForProdAndNavigateToSDK()
}
else{
calculateHashFromServer()
}
// assign delegate for payment callback.
params.delegate = self;
}
func generateHashForProdAndNavigateToSDK() -> Void {
let txnid = params.txnid!
let hashSequence : NSString = "\(params.key)|\(txnid)|\(params.amount)|\(params.productinfo)|\(params.firstname)|\(params.email)|||||||||||2uIsGhXWVw" as NSString
let data :NSString = utils.createSHA512(hashSequence as String!) as NSString
params.hashValue = data as String!;
startPaymentFlow();
}
// MARK:HASH CALCULATION
func prepareHashBody()->NSString{
return "SHA-512key=\(params.key!)&amount=\(params.amount!)&txnid=\(params.txnid!)&productinfo=\(params.productinfo!)&email=\(params.email!)&firstname=\(params.firstname!)" as NSString;
}
func calculateHashFromServer(){
let config = URLSessionConfiguration.default // Session Configuration
let session = URLSession(configuration: config) // Load configuration into Session
let url = URL(string: "https://test.payumoney.com/payment/op/v1/calculateHashForTest")!
var request = URLRequest(url: url)
request.httpBody = prepareHashBody().data(using: String.Encoding.utf8.rawValue)
request.httpMethod = "POST"
let task = session.dataTask(with: request, completionHandler: {
(data, response, error) in
if error != nil {
print(error!.localizedDescription)
} else {
do {
if let json = try JSONSerialization.jsonObject(with: data!, options: []) as? [String: Any]{
print(json)
let status : NSNumber = json["status"] as! NSNumber
if(status.intValue == 0)
{
self.params.hashValue = json["result"] as! String!
OperationQueue.main.addOperation {
self.startPaymentFlow()
}
}
else{
OperationQueue.main.addOperation {
self.showAlertViewWithTitle(title: "Message", message: json["message"] as! String)
}
}
}
} catch {
print("error in JSONSerialization")
}
}
})
task.resume()
}
Hello Vinny do with webview its working for me. Before I also used this PayUmoney IOS SDK but faced so many problems so based on objective-c I did this so I think its useful to you. create a weak var webview and create class UIwebviewdelegate
class PayumoneyViewController: UIViewController, UIWebViewDelegate, UIAlertViewDelegate {
#IBOutlet weak var Webview: UIWebView!
and for test use below credentials
//test
var merchantKey = "40747T"
var salt = "ur salt"
var PayUBaseUrl = "https://test.payu.in"
For live
//Production
var merchantKey = “xxxxxx”
var salt = “xxxxx”
var PayUBaseUrl = "https://secure.payu.in"
let productInfo = “Myapp” //It can be Project name or anything else
let firstName = “Santoshi” //Details of user whose is purchasing order
let email = “santoshi#app.com" //Details of user whose is purchasing order
let phone = "xxxxxxxxx" //Details of user whose is purchasing order
let sUrl = "www.google.com" //By this URL we match whether payment got success or failure
let fUrl = "www.google.com" //By this URL we match whether payment got success or failure
let service_provider = "payu_paisa"
var txnid1: String! = "" //Its an unique id which can give order a specific order number.
let totalPriceAmount = "1.0"
Above viewdidload do like this
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
initPayment()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(true)
}
In viewdidload do like this
override func viewDidLoad() {
super.viewDidLoad()
Webview.delegate = self
// Do any additional setup after loading the view.
}
Create payment and Generate Hash key
func initPayment() {
txnid1 = “Myapp\(String(Int(NSDate().timeIntervalSince1970)))"
//Generating Hash Key
let hashValue = String.localizedStringWithFormat("%#|%#|%#|%#|%#|%#|||||||||||%#",merchantKey,txnid1,totalPriceAmount,productInfo,firstName,email,salt)
let hash = self.sha1(string: hashValue)
let postStr = "txnid="+txnid1+"&key="+merchantKey+"&amount="+totalPriceAmount+"&productinfo="+productInfo+"&firstname="+firstName+"&email="+email+"&phone="+phone+"&surl="+sUrl+"&furl="+fUrl+"&hash="+hash+"&service_provider="+service_provider
let url = NSURL(string: String.localizedStringWithFormat("%#/_payment", PayUBaseUrl))
let request = NSMutableURLRequest(url: url! as URL)
do {
let postLength = String.localizedStringWithFormat("%lu",postStr.characters.count)
request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Current-Type")
request.setValue(postLength, forHTTPHeaderField: "Content-Length")
request.httpBody = postStr.data(using: String.Encoding.utf8)
Webview.loadRequest(request as URLRequest)
}
catch let error as NSError
{
print(error)
}
}
Finally Do this
func sha1(string:String) -> String {
let cstr = string.cString(using: String.Encoding.utf8)
let data = NSData(bytes: cstr, length: string.characters.count)
var digest = [UInt8](repeating: 0, count:Int(CC_SHA512_DIGEST_LENGTH))
CC_SHA512(data.bytes, CC_LONG(data.length), &digest)
let hexBytes = digest.map { String(format: "%02x", $0) }
return hexBytes.joined(separator: "")
}
func webViewDidFinishLoad(_ webView: UIWebView) {
let requestURL = self.Webview.request?.url
let requestString:String = (requestURL?.absoluteString)!
if requestString.contains("https://www.payumoney.com/mobileapp/payumoney/success.php") {
print("success payment done")
}else if requestString.contains("https://www.payumoney.com/mobileapp/payumoney/failure.php") {
print("payment failure")
}
}
func webView(_ webView: UIWebView, didFailLoadWithError error: Error) {
let requestURL = self.Webview.request?.url
print("WebView failed loading with requestURL: \(requestURL) with error: \(error.localizedDescription) & error code: \(error)")
if error._code == -1009 || error._code == -1003 {
showAlertView(userMessage: "Please check your internet connection!")
}else if error._code == -1001 {
showAlertView(userMessage: "The request timed out.")
}
}
func showAlertView(userMessage:String){
}
I have Faced Same problem and i have got solution of this problem.
In my code this line generate optional values --> let hashSequence : NSString = "(params.key!)|(txnid)|(params.amount!)|(params.productinfo!)|(params.firstname!)|(params.email!)|||||||||||(params.merchantid!)" as NSString
remove optional from the values.
i tried build login authentication without oauth is work and then i build other project only oauth code for request roken is work too, and now i want to make project authentication login with oauth swift. im really stuck what must i do.
this is my code im trying :
import UIKit
import OAuthSwift
class ViewController: UIViewController {
#IBOutlet weak var passwordTxt: UITextField!
#IBOutlet weak var phonenumberTxt: UITextField!
var oauthswift: OAuth1Swift?
let dataShared = UserDefaults.standard
let fileUrl = NSURL(string: "8villages://app/oauth-callback")
override func viewDidLoad() {
super.viewDidLoad()
requestToken()
}
#IBAction func doLogin(_ sender: Any) {
let phonenumber = phonenumberTxt.text
let password = passwordTxt.text
if(phonenumber == "" || password == "")
{
return
}
login(phonenumber!, password!)
}
func login(_ number:String, _ pswrd:String) {
let url = URL(string: "https://accounts.8villages.com/authentication")
let session = URLSession.shared
let request = NSMutableURLRequest(url: url!)
request.httpMethod = "POST"
let paramToSend = "identifier=" + number + "&password=" + pswrd
request.httpBody = paramToSend.data(using: String.Encoding.utf8)
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(data, response, error) in
guard let _:Data = data else
{
return
}
let json:Any?
do {
json = try JSONSerialization.jsonObject(with: data!, options: [])
}
catch {
return
}
guard let server_response = json as? NSDictionary else {
return
}
if let data_block = server_response["data"] as? NSDictionary {
if let session_data = data_block["session"] as? String {
let preference = UserDefaults.standard
preference.set(session_data, forKey: "session")
DispatchQueue.main.async(
execute:self.LoginDone
)//
}
}
})
task.resume()
}
func LoginDone() {
self.performSegue(withIdentifier: "loginView", sender: self)
}
func requestToken() {
print ("hei")
var is8VillagesInstalled: Bool = {
let appUrl = URL(string: "8villages://app")
return UIApplication.shared.canOpenURL(appUrl!)
}()
self.oauthswift = OAuth1Swift.init(consumerKey: "**********",
consumerSecret: "**********",
requestTokenUrl: "https://oauth.8villages.com/tokens/request-token",
authorizeUrl: "8villages://app/?oauth_token_secret=",
accessTokenUrl: "https://accounts.8villages.com/tokens/access-token")
self.oauthswift?.authorizeURLHandler = OAuthSwiftOpenURLExternally.sharedInstance
self.oauthswift?.allowMissingOAuthVerifier = true
self.oauthswift?.postOAuthRequestToken(
callbackURL: fileUrl as! URL,
success: { credentials, response, parameters in
print("credentials", credentials)
print("response =", response!)
print("parameters =", parameters)
// request ke api login
}, failure: { error in
print("the error is", error.description, error.errorCode)
});
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
so, i dont know how to authentication login with oauth. how to make them work.
Attempting to read our web service into a UITableViewController and it only returns the first record to the simulator. So hoping that someone will be able to look at the code and guide me down the correct path. Ultimate goal is to get it into a UITableViewCell so I can format nicely but just looking to get all the records.
Here is a view of the partial json file that will be returned.
{
"Count":11518,
"Result":[
{
"cuName": "#1",
"charter_Num":
"16328","City":
"Jonesboro",
"State_id": "GA",
"cuName_location": "#1 - Jonesboro, GA"
},
{
"cuName": "#lantec Financial",
"charter_Num": "7965",
"City": "Virginia Beach",
"State_id": "VA",
"cuName_location": "#lantec Financial - Virginia Beach, VA"
}]
}
Here is the code that reads in the json web service and attempts to parse and put in the table.
func get_data_from_url(_ link:String)
{
let url:URL = URL(string: link)!
let session = URLSession.shared
let request = NSMutableURLRequest(url: url)
request.httpMethod = "GET"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(
data, response, error) in
guard let _:Data = data, let _:URLResponse = response , error == nil else {
return
}
self.extract_json(data!)
})
task.resume()
}
func extract_json(_ data: Data)
{
let json: Any?
do
{
json = try JSONSerialization.jsonObject(with: data, options: [])
}
catch
{
return
}
//Commented out the following lines because it doesn't return anything when using the modified code that works
//
// guard let data_list = json as? NSArray else
// {
// return
// }
//This code works but only gives me the 1st record back
if let cu_list = try? json as? [String:Any],
let result = cu_list?["Result"] as? [[String:Any]],
let charter_num = result[0]["charter_Num"] as? String,
let value = result[0]["cuName_location"] as? String, result.count > 0 {
TableData.append(value + " (" + charter_num + ")")
} else {
print("bad json - do some recovery")
}
DispatchQueue.main.async(execute: {self.do_table_refresh()})
}
You are referring the 0th index element from result object and it will only return the 1st record from JSON data. You need to run thru the loop and append the data to array which you need to use for populating the data in UITableView.
func GetCategoryData(){
//get_high_score.php?from=1472409001482&number=10&to=1493657787867
let checklaun = UserDefaults.standard.integer(forKey: "Language")
if checklaun == 1 {
EZLoadingActivity.show("Loading...", disableUI: false)
}else{
EZLoadingActivity.show("جار التحميل...", disableUI: false)
}
DispatchQueue.global(qos: .background).async {
let myUrl = URL(string: GlobleUrl.BASEURL + "advertise_list.php");
var request = URLRequest(url:myUrl!)
request.httpMethod = "GET"
// let fromvalue = 1472409001482
// let numbervalue = 10
// let tovalue = 1493657787867
let postString = ""//"from=" + fromvalue + "&" + "number=" + numbervalue + "&" + "to=" + tovalue
request.httpBody = postString.data(using: String.Encoding.utf8);
let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
if error != nil
{
EZLoadingActivity.hide(false, animated: true)
print("error=\(error)")
let checklaun = UserDefaults.standard.integer(forKey: "Language")
var titlemsga : String = String()
var okmsg : String = String()
if checklaun == 1 {
titlemsga = "Something going wrong"
okmsg = "Ok"
}else{
titlemsga = "حدث خطأ ما"
okmsg = "حسنا"
}
let alert = UIAlertController(title: "", message: titlemsga, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: okmsg, style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
return
}
print("response = \(response)")
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
DispatchQueue.main.async {
if let parseJSON = json {
print(parseJSON)
let status = parseJSON["status"] as! Bool
if status == true{
EZLoadingActivity.hide(true, animated: false)
self.categoryDataArray = parseJSON["data"] as! NSMutableArray
print("\(self.categoryDataArray)")
self.filterarray = parseJSON["fixed_cat"] as! NSMutableArray
let teamp = self.categoryDataArray .value(forKey: "main_image") as AnyObject
print("\(teamp)")
self.categoryImageArray.setArray(teamp as! [Any])
print("\( self.categoryImageArray)")
// let teamp = self.data .value(forKey: "name") as AnyObject
// print("\(teamp)")
// self.categoryNameArray.setArray(teamp as! [Any])
self.allcategoryTableViewCell.reloadData()
self.allcategoryfilterlistview.reloadData()
// self.tblscoreList.reloadData()
}else{
EZLoadingActivity.hide(false, animated: true)
}
}
}
}
catch {
EZLoadingActivity.hide(false, animated: true)
let checklaun = UserDefaults.standard.integer(forKey: "Language")
var titlemsga : String = String()
var okmsg : String = String()
if checklaun == 1 {
titlemsga = "Something going wrong"
okmsg = "Ok"
}else{
titlemsga = "حدث خطأ ما"
okmsg = "حسنا"
}
let alert = UIAlertController(title: "", message: titlemsga, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: okmsg, style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
print(error)
}
}
task.resume()
}
}