In change of Swift 2 Extra argument ' error' in call - swift2

Upgrade to Xcode 7 Swift 2 and SDK for iOS 9. I get the error "extra argument" error "in call" my code is:
let myUrl = NSURL(string: "http://localhost/SwiftAppAndMySQL/scripts/registerUser.php");
let request = NSMutableURLRequest(URL:myUrl!);
request.HTTPMethod = "POST";
let postString = "userEmail=\(userEmail)&userFirstName=\(userFirstName)&userLastName=\(userLastName)&userPassword=\(userPassword)";
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data:NSData!, response:NSURLResponse!, error:NSError!) -> Void in
dispatch_async(dispatch_get_main_queue())
{
spinningActivity.hide(true)
if error != nil {
self.displayAlertMessage(error.localizedDescription)
return
}
var err: NSError?
var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: &err) as? NSDictionary
if let parseJSON = json {
var userId = parseJSON["userId"] as? String
if( userId != nil)
{
var myAlert = UIAlertController(title: "Alert", message: "Registration successful", preferredStyle: UIAlertControllerStyle.Alert);
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default){(action) in
self.dismissViewControllerAnimated(true, completion: nil)
}
myAlert.addAction(okAction);
self.presentViewController(myAlert, animated: true, completion: nil)
} else {
let errorMessage = parseJSON["message"] as? String
if(errorMessage != nil)
{
self.displayAlertMessage(errorMessage!)
}
}
}
}
}).resume()

NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler ) asks you for 3 optionals arguments and you're giving 3 forceds unwrapping arguments.
try change
NSURLSession.sharedSession().dataTaskWithRequest(request) { (data:NSData!, response:NSURLResponse!, error:NSError!)
to
NSURLSession.sharedSession().dataTaskWithRequest(request) { (data:NSData?, response:NSURLResponse?, error:NSError?)

Now is working, I replaced the previous code with this::
let myUrl = NSURL(string: "http://dcapp1.testingview.com/DryCleanAppClientes/scripts/registerUser.php");
let request = NSMutableURLRequest(URL:myUrl!);
request.HTTPMethod = "POST";
let postString = "userEmail=\(userEmail)&userFirstName=\(userFirstName)&userLastName=\(userLastName)&userPassword=\(userPassword)";
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
print(postString)
NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
dispatch_async(dispatch_get_main_queue())
{
spinningActivity.hide(true)
if error != nil {
self.displayAlertMessage(error!.localizedDescription)
return
}
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary
if let parseJSON = json {
let userId = parseJSON["userId"] as? String
if( userId != nil)
{
let myAlert = UIAlertController(title: "Mensaje", message: "¡Registro exitoso!", preferredStyle: UIAlertControllerStyle.Alert);
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default){(action) in
self.dismissViewControllerAnimated(true, completion: nil)
}
myAlert.addAction(okAction);
self.presentViewController(myAlert, animated: true, completion: nil)
} else {
let errorMessage = parseJSON["message"] as? String
if(errorMessage != nil)
{
self.displayAlertMessage(errorMessage!)
}
}
}
} catch _ as NSError {
}
}
}).resume()
}

Related

Parsing JSON Swift 3 with error Code=3840

I have this error.
Error Domain=NSCocoaErrorDomain Code=3840 "Garbage at end." UserInfo={NSDebugDescription=Garbage at end.}
Here is my swift code.
let request = NSMutableURLRequest(url: NSURL(string: "http://example.org/file.php")! as URL)
request.httpMethod = "POST"
let task = URLSession.shared.dataTask(with: request as URLRequest) {
old_data, response, error in
//Error Checking
if error != nil {
print("error=\(error)")
return
}
print("response = \(response)")
//Response string built up
let responseString = NSString(data: old_data!, encoding: String.Encoding.utf8.rawValue)
print("responseString = \(responseString)")
//Manipulating the JSON data
var names = [String]()
do {
if let new_data = old_data,
let json = try JSONSerialization.jsonObject(with: new_data) as? [String: Any],
let buildings = json["buildings"] as? [[String: Any]] {
for building in buildings {
if let name = building["BuildingName"] as? String {
names.append(name)
}
}
}
} catch {
print(error)
}
print("Names: \(names)")
}
task.resume()
The error is happening in my 'do' statement where 'let buildings = json["buildings"]'
And below is what I get when I print the response string.
responseString = Optional({"buildings":[{"BuildingID":"2","BuildingName":"School of Informatics and Comp","Info":"School of higher learning.","Latitude":"39.172085","Longitude":"-86.522908"}]}Successfully Retrieved. SELECT * FROM Buildings;)
Any questions or advice is appreciated

Swift Alamofire + Promise catching

Folks, The following works except for the catch, xcode errors out with expected member name following '.'
Is this the proper way to promisify with PromiseKit?
All suggestions welcome! Thanks!
#IBAction func loginButtonTapped(sender: AnyObject) {
let email = userEmail.text!
let password = userPassword.text!
func onSuccess(success:Bool, message:String, token: String) -> Promise<Void> {
if success {
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "isUserLoggedIn")
NSUserDefaults.standardUserDefaults().synchronize()
self.dismissViewControllerAnimated(true, completion: nil)
} else {
let myAlert = UIAlertController(title: "Alert", message: message, preferredStyle: UIAlertControllerStyle.Alert)
let okAction = UIAlertAction(title: "Try Again", style: UIAlertActionStyle.Default, handler: nil)
myAlert.addAction(okAction)
self.presentViewController(myAlert, animated: true, completion: nil)
}
return Promise { resolve, reject in
return resolve()
}
}
func onFailure(error:NSError) -> Promise<Void> {
return Promise { resolve, reject in
return reject(error)
}
}
Login(email, password: password).then(onSuccess).catch(onFailure)
}
private func Login(email: String, password: String) -> Promise<(success:Bool, message:String, token: String)> {
let parameters: [String: String] = [
"username" : email,
"password" : password
];
let endpoint = "https://api.foo.bar/login"
return Promise { resolve, reject in
Alamofire.request(.POST, endpoint, parameters: parameters, encoding: .JSON)
.validate()
.responseJSON { (response) in
guard response.result.error == nil else {
logger.debug(response)
let result:(success:Bool, message:String, token: String) = (false, "Login Failed", "")
return resolve(result)
}
if let value = response.result.value {
let apiResponseJSONBody = JSON(value)
let result:(success:Bool, message:String, token: String) = (true, "", token: apiResponseJSONBody["token"].string!)
return resolve(result)
}
}
}
}

PayU Money Gateway iOS Swift

I want to integrate the payU Money sdk in my app using swift2.0
I am using this sdk: https://github.com/payu-intrepos/Documentations/wiki/8.1-NEW-iOS-Seamless-SDK-integration
Where to create the test account for testing.
import UIKit
var merchantKey="your live merchant key"
var salt="your live merchant salt"
var PayUBaseUrl="https://secure.payu.in"
class PaymentScreen: UIViewController,UIWebViewDelegate {
#IBOutlet weak var myWebView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
self.initPayment()
}
func initPayment() {
var i = arc4random()
let amount = "1"
let productInfo = "Order"
let firstName = "Sample name"
let email = "abc#gmail.com"
let phone = "9999119911"
let sUrl = "https://www.google.com"
let fUrl = "https://www.bing.com"
let service_provider = "payu_paisa"
let strHash:String = self.sha1(String.localizedStringWithFormat("%d%#", i, NSDate()))
let rangeOfHello = Range(start: strHash.startIndex,
end: strHash.startIndex.advancedBy(20))
let txnid1 = strHash.substringWithRange(rangeOfHello)
let hashValue = String.localizedStringWithFormat("%#|%#|%#|%#|%#|%#|||||||||||%#",merchantKey,txnid1,amount,productInfo,firstName,email,salt)
let hash=self.sha1(hashValue)
let postStr = "txnid="+txnid1+"&key="+merchantKey+"&amount="+amount+"&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))
print("check my url", url, postStr)
let request = NSMutableURLRequest(URL: 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.dataUsingEncoding(NSUTF8StringEncoding)
myWebView.loadRequest(request)
} catch {
}
}
func webViewDidStartLoad(webView: UIWebView) {
}
func webViewDidFinishLoad(webView: UIWebView) {
let requestURL = self.myWebView.request?.URL
let requestString:String = (requestURL?.absoluteString)!
if requestString.containsString("https://www.google.com") {
print("success payment done")
}
else if requestString.containsString("https://www.bing.com") {
print("payment failure")
}
}
func webView(webView: UIWebView, didFailLoadWithError error: NSError?) {
print("double failure")
}
func sha1(toEncrypt:String) -> String {
let data = toEncrypt.dataUsingEncoding(NSUTF8StringEncoding)!
var digest = [UInt8](count:Int(CC_SHA512_DIGEST_LENGTH), repeatedValue: 0)
CC_SHA512(data.bytes, CC_LONG(data.length), &digest)
let hexBytes = digest.map { String(format: "%02x", $0) }
return hexBytes.joinWithSeparator("")
}
}
// Swift 4
import UIKit
import SystemConfiguration
import Foundation
class PayUMoneyViewController: UIViewController, UIWebViewDelegate, UIAlertViewDelegate {
#IBOutlet weak var webView: UIWebView!
var merchantKey = "YOUR_MARCHANT_KEY"
var salt = "YOUR_SALT_KEY"
var PayUBaseUrl = "https://secure.payu.in"
var SUCCESS_URL = "https://www.payumoney.com/payments/guestcheckout/#/success"
var FAILED_URL = "https://www.PayUmoney.com/mobileapp/PayUmoney/failure.php"
#IBOutlet weak var activityIndicator: UIActivityIndicatorView!
var request = NSMutableURLRequest()
override func viewDidLoad() {
super.viewDidLoad()
self.webView.delegate = self
self.payPayment()
self.navigationItem.hidesBackButton = true
let newBackButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.plain, target: self, action: #selector(PayUMoneyViewController.back(sender:)))
self.navigationItem.leftBarButtonItem = newBackButton
}
#objc func back(sender: UIBarButtonItem) {
let alert = UIAlertController(title: "Cancel !", message: "Do you really want to cancel the transaction ?", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.default, handler: cancelTransaction))
alert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
func cancelTransaction( action : UIAlertAction)
{
_ = navigationController?.popToRootViewController(animated: true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func payPayment() {
var i = arc4random()
let amount = "1"
let productInfo = "Transport"
let firstName = USER_FIRST_NAME // Geet
let email = USER_EMAIL // geetbasakare#gmail.com
let phone = USER_MOBILE_NO // 1234567890
let sUrl = "https://www.google.com"
let fUrl = "https://www.bing.com"
let service_provider = "payu_paisa"
let strHash:String = self.sha1(toEncrypt: String.localizedStringWithFormat("%d%#", i, NSDate()));
let r1 = strHash.range(of: strHash)!
// String range to NSRange:
let n1 = NSRange(r1, in: strHash)
print((strHash as NSString).substring(with: n1)) //
// NSRange back to String range:
let r2 = Range(n1, in: strHash)!
print(strHash.substring(with: r2))
let rangeOfHello = Range(n1, in: strHash)!
let txnid1 = strHash.substring(with: rangeOfHello)
let hashValue = String.localizedStringWithFormat("%#|%#|%#|%#|%#|%#|||||||||||%#",merchantKey,txnid1,amount,productInfo,firstName,email,salt)
let hash = self.sha1(toEncrypt: hashValue)
let postStr = "txnid="+txnid1+"&key="+merchantKey+"&amount="+amount+"&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))
print("check my url", url as Any, postStr)
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 {
print(error)
}
}
func webViewDidFinishLoad(_ webView: UIWebView) {
let requestURL = self.webView.request?.url
let requestString:String = (requestURL?.absoluteString)!
if (requestString == SUCCESS_URL) {
print("success payment done")
}
else if (requestString == FAILED_URL) {
print("payment failure")
}
}
func webView(_ webView: UIWebView, didFailLoadWithError error: Error) {
print("double failure")
}
func sha1(toEncrypt: String) -> String {
var digest = [UInt8](repeating: 0, count: Int(CC_SHA512_DIGEST_LENGTH))
if let data = toEncrypt.data(using: String.Encoding.utf8) {
let value = data as NSData
CC_SHA512(value.bytes, CC_LONG(data.count), &digest)
}
var digestHex = ""
for index in 0..<Int(CC_SHA512_DIGEST_LENGTH) {
digestHex += String(format: "%02x", digest[index])
}
return digestHex
}
/*
func sha1(toEncrypt:String) -> String {
var data = toEncrypt.data(using: String.Encoding.utf8)!
var digest = [UInt8](repeating: 0, count:Int(CC_SHA512_DIGEST_LENGTH))
_ = data.withUnsafeBytes {messageBytes in
CC_SHA512(messageBytes, CC_LONG(data.count), &digest)
}
let hexBytes = digest.map { String(format: "%02x", $0) }
return hexBytes.joined(separator: "")
}
*/
}
You can create a test account as described in the following help documentation, and you need not perform KYC in this regard. Later, you can use the Key and Salt on the Payment Gateway page of the Dashboard.
https://devguide.payu.in/low-code-web-sdk/getting-started-low-code-web-sdk/register-for-a-test-merchant-account/

NSURL error for broken links in Swift

I coded a function for OSX 10.10 that is willing to open a text file from an URL and display its content.
Everything is working but if the URL cannot be reach then the App will crash. How could I handle this type of Error?
I guess it comes from the completionHandler closure but I am not sure.
here is my code
#IBAction func checkAdminMessage(sender: NSMenuItem) {
let messageURL = NSURL(string: "http://www.xxxxxx.com/text.txt")
// The Network stuff will be handled in a background thread
let sharedSession = NSURLSession.sharedSession()
let downloadTask: NSURLSessionDownloadTask = sharedSession.downloadTaskWithURL(messageURL!,
completionHandler: {
(location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in
var urlContents = NSString(contentsOfURL: location, encoding: NSUTF8StringEncoding, error: nil)
// Check if text.txt has NULL as content
if urlContents! == "NULL" {
// Have to use Grand Central Dispatch to put NSAlert in the main thread
let noMessage = NSLocalizedString("Nothing there", comment: "Text to dislay when the file is empty" )
dispatch_async(dispatch_get_main_queue()) { () -> Void in
self.displayAlertNotification(notification: noMessage)
}
} else {
// If the file is not empty then we display the content of this file
dispatch_async(dispatch_get_main_queue()) { () -> Void in
self.displayAlertNotification(notification: urlContents!)
}
}
})
downloadTask.resume()
}
Thank you
EDIT: Here is the updated code but the App still crashed
#IBAction func checkAdminMessage(sender: NSMenuItem) {
if let messageURL = NSURL(string: "http://www.xxxxxx.com/text.txt") {
let sharedSession = NSURLSession.sharedSession()
let downloadTask: NSURLSessionDownloadTask = sharedSession.downloadTaskWithURL(messageURL,
completionHandler: {
(location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in
var urlContents = NSString(contentsOfURL: location, encoding: NSUTF8StringEncoding, error: nil )
if urlContents == "NULL" {
println(urlContents)
// Have to use Grand Central Dispatch to put NSAlert in the main thread
let noMessage = NSLocalizedString("Nothing there", comment: "Text to dislay when the file is empty" )
dispatch_async(dispatch_get_main_queue()) { () -> Void in
self.displayAlertNotification(notification: noMessage)
}
}
else {
dispatch_async(dispatch_get_main_queue()) { () -> Void in
self.displayAlertNotification(notification: urlContents!)
}
}
})
downloadTask.resume()
}
else {
println("Error")
}
}
NSURL(string: ...) returns an optional, so the result may be nil due to several reasons.
Wrap your code in a conditional unwrap:
if let messageURL = NSURL(string: "http://www.xxxxxx.com/text.txt") {
// success
...
}
else {
// error
}
I figured it out with the helps of the people that commented my question.
I was getting a nil from 'location' in downloadTaskWithUrl, then the var urlContents was receiving a nil as well.
The solution is to check if 'location' is nil :
let downloadTask: NSURLSessionDownloadTask = sharedSession.downloadTaskWithURL(messageURL,
completionHandler: {
(location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in
**if (location != nil) {**
var urlContents = NSString(contentsOfURL: location, encoding: NSUTF8StringEncoding, error: nil ) ...

NSURLSessionDataTask: func receives but returns no data

I've tried to create a simple function which receives URL and simply returns the HTML of the webpage. the NSURLSessionDataTask itself seems to work, I can see the whole html when I println(data). But the func only returns the initial value "#!?". I suspect that the DataTask works asynchronous? How can I handle this?
func loadHTML(targetURL: String) -> String {
var theTargetURL = NSURL(string:targetURL)
var theResult = "#!?"
var request: NSURLRequest = NSURLRequest(URL:theTargetURL)
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config)
let task : NSURLSessionDataTask = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
println(NSString(data: data, encoding: NSASCIIStringEncoding))
if error != nil {
println(error.localizedDescription)
theResult = "error"
}
if data != nil {
theResult = NSString(data: data, encoding: NSASCIIStringEncoding)
println("RECEIVED\t\t\(countElements(theResult)) CHARS")
}
});
task.resume()
return theResult
}
Here is an example how you would do it using a completion handler.
typealias CompletionBlock = (NSData!, NSURLResponse!, NSError!) -> Void
func loadHtml(targetUrlString: String, completion: CompletionBlock){
let targetUrl = NSURL(string: targetUrlString)
let request = NSURLRequest(URL: targetUrl)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request, completionHandler: completion)
task.resume()
}
Then, call it from your method where it is needed,
func viewDidLoad(){
super.viewDidLoad()
loadHtml("http://google.com", completion: { (responseData: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
if responseData != nil{
let resultString = NSString(data: responseData, encoding: NSASCIIStringEncoding)
println(resultString)
/*
do some task or update on the main thread
dispatch_async(dispatch_get_main_queue){
myActivityIndicator.stopAnimating()
}
*/
}else if error != nil{
println("Error occurred: \(error.localizedDescription)")
}
})

Resources