Why is the base 64 encoding not working? - swift

I am trying to post username and password to a php script, it works fine when it is not encoded, but I am having trouble encoding on the ios end. When I print crypt I get <64584e6c 636d3568 6257566b 59585268 50556377 4e444134 4d546335 4a6e4268 63334e33 62334a6b 5a474630 59543172 6448526e 4e6a5935 4d673d3d>, but based on the tutorials I should be getting a string along the lines of bXkgcGxhbmkgdGV4dA==
var bodyData = "usernamedata=\(self.username.text!)&passworddata=\(self.password.text!)"
request.HTTPMethod = "POST"
let encodeString = (bodyData.dataUsingEncoding(NSUTF8StringEncoding)!);
let crypt = encodeString.base64EncodedDataWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
request.HTTPBody = crypt
print(crypt)

I wouldn't recommend using encodeString as a variable name for something whose type is NSData (not a String).
The function base64EncodedDataWithOptions returns NSData. If you want a string like bXkgcGxhbmkgdGV4dA==, you can use base64EncodedStringWithOptions.

You should have to write it like,
let crypt = encodeString.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))

Related

Conversion from String to binary and then to base64 format

Trying to create a signature by using RFC 2104-compliant HMAC with the SHA256 hash algorithm. I am half-way done but stuck in converting a string to binary and then to base64 format.
Here is the instruction I am following.
Here is the code I made
let stringToSign = "GET\nwebservices.amazon.com\n/onca/xml\nAWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&AssociateTag=mytag-20&ItemId=0679722769&Operation=ItemLookup&ResponseGroup=Images%2CItemAttributes%2COffers%2CReviews&Service=AWSECommerceService&Timestamp=2014-08-18T12%3A00%3A00Z&Version=2013-08-01"
let beforeCoversion = stringToSign.hmac(algorithm: .SHA256, key: "1234567890")
let binary = beforeCoversion.data(using: .utf8, allowLossyConversion: false)
let afterCoversion = binary?.base64EncodedString(options: [.lineLength64Characters])
print(beforeCoversion)
print(afterCoversion!)
Print
8fb6d93342d767d797799aee4ea5a6d8322f0d8554537c313cfa69fa25f1cd07
OGZiNmQ5MzM0MmQ3NjdkNzk3Nzk5YWVlNGVhNWE2ZDgzMjJmMGQ4NTU0NTM3YzMx
M2NmYTY5ZmEyNWYxY2QwNw==
I can see that I get 8fb6d93342d767d797799aee4ea5a6d8322f0d8554537c313cfa69fa25f1cd07 so my conversion is failed in converting a string to binary and then to base64 format. I believe beforeCoversion.data(using: .utf8, allowLossyConversion: false) can be used for converting a string to binary and binary?.base64EncodedString(options: [.lineLength64Characters]) can be used for converting to base64 format. Is that correct? sAny suggestions?
Easy way to solve this if you use amazon-api
pod 'AWSAPIGateway'
Then
let dataToSign = stringToSign.data(using: String.Encoding.utf8)
let conversion = AWSSignatureSignerUtility.hmacSign(dataToSign, withKey: "1234567890", usingAlgorithm: UInt32(kCCHmacAlgSHA256))!
Thanks Roozbeh Zabihollahi for the answer in Amazon Product Advertising API Signature in iOS

Swift base64 not ok

I'm using the Vapor framework to download a PDF file :
let logpw = "myLogin:passWord"
let url = "https://someRESTsite/invoices/1.pdf"
let utf8str = logpw.data(using: String.Encoding.utf8)
let base64Encoded = utf8str?.base64EncodedString()
let response = try drop.client.get(url, headers:["Authorization":"Basic " + base64Encoded!])
this works fine. Note that I'm base64 encoding the login/pw for basic auth and this works for logging in and getting the file. Now I have to embed that PDF into an XML file in base64 using similar code:
if let bodyBytes = response.body.bytes {
let bodyByteString = try String(bytes: bodyBytes)
let utf8String = bodyByteString(using: String.Encoding.utf8)
let base64String = utf8String?.base64EncodedString()
}
the result is a string that actually really looks like a base64 string, but it's different than converting the same PDF using an online tool (I tried 2 which gave the same result).
Where is my mistake?

How to send '&' character in HTTP request body?

I have these parameters saved as string :
title=Culture, sport & recreation (1 day)&useremail=ammar#gmail.com&days=2&ispredefined=false&languageid=1&websiteid=1&node=item&languageid=1&websiteid=1&moduletype=Accommodation&moduleuniquename=abu.dhabi.plaza.hotel.apartments&dayindex=1
and I am passing it to a request body using the below code:
let request = NSMutableURLRequest(URL: URL.getURL(url)!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
request.HTTPBody = params.dataUsingEncoding(NSASCIIStringEncoding)
but the problem is that the title in the string title=Culture, sport & recreation has '&'character and i am getting 400 bad Request from the server
please any advice how to solve this problem?
As you can read in the attached links you have to encode the ampersand sign.
encodeURIComponent('&') gives "%26"
Thus, you have to replace all ampersands with %26 or use encodeURIComponent(str) in your code.
escaping ampersand in url
How can I send the "&" (ampersand) character via AJAX?

Why won't NSURL accept a valid string that contains quotes or braces?

EDIT
https://www.someurl.com/search?&access_token=1,84,848473938;848483,83&_json={"key1":"value1","key2":"value2"}
When declaring a URL that has a JSON string, I obviously need to use braces _json={ } and qoutes \"key1\":\"value1\"
NSURL(string: String), however, magically becomes nil if either of these characters are included in the string.
So as answered correctly here: NSURL is returning nil for a valid URL, I tried using:
let url = NSURL(string: url.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!)
But I believe that's deprecated since it was before Swift 2 was released and I am getting the error: cannot convert value of Type NSCharacterSet to expected argument type NSStringEncoding (aka UInt)
So I tried using
let url = NSURL(string: url.stringByAddingPercentEncodingWithAllowedCharacters(NSUTF8StringEncoding)!)!
and while that did allow NSURL to have a value instead of nil, it did not return the expected results, so something is still wrong.
I know that the format is correct, because if I type the URL string manually in a browser, I get the expected result. If i copy/paste the encoded version from Xcode, it gives me the wrong result as did Swift when encoding as shown above.
Any insight would be much appreciated.
You can modify a mutable character set to remove an allowed character: since you want the commas to be encoded, remove the comma from the URLQueryAllowedCharacterSet before using it.
In Swift 2, we need to dance with NSMutableCharacterSet like this:
let sourceURL = "https://www.someurl.com/search?&access_token=1,84,848473938;848483,83&_json={\"key1\":\"value1\",\"key2\":\"value2\"}"
let charSet = NSMutableCharacterSet()
charSet.formUnionWithCharacterSet(NSCharacterSet.URLQueryAllowedCharacterSet())
charSet.removeCharactersInString(",")
let url = NSURL(string: sourceURL.stringByAddingPercentEncodingWithAllowedCharacters(charSet)!)
print(url!)
Prints:
https://www.someurl.com/search?&access_token=1%2C84%2C848473938;848483%2C83&_json=%7B%22key1%22:%22value1%22%2C%22key2%22:%22value2%22%7D
To do the same thing with Swift 3 we're using the CharacterSet struct instead of NSMutableCharacterSet but it's the same idea:
var charSet = CharacterSet()
charSet.formUnion(.urlQueryAllowed)
charSet.remove(",")
if let encoded = sourceURL.addingPercentEncoding(withAllowedCharacters: charSet) {
if let url = URL(string: encoded) {
print(url)
}
}

How to encode special character like ’ (NSWindowsCP1250StringEncoding) in Swift2

As in Swift2 stringByAddingPercentEscapesUsingEncoding() is deprecated instead of stringByAddingPercentEncodingWithAllowedCharacters() is used.
But how to encode the especial character like ' % & in swift2
For example in iOS8(swift1.2) i used following code for encoding
NSURL(string: "myurl.php?deviceName=name’phone".stringByAddingPercentEscapesUsingEncoding(NSWindowsCP1250StringEncoding)!)
it work fine i.e. on server it decode correctly.
But in iOS9(Swift2.0) i used following code
NSURL(string: "myurl.php?deviceName=name ’phone".stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLFragmentAllowedCharacterSet())!)
It will not decode properly.
please tell me how i can encode special charater in swift2.0 ?
EDIT :
Eric D answer is right but when i encode below stringURL it will not encode properly.
Why?
let stringURL = "https://my.server.com/login.php?e=email&dn=my’s iPad&d=5&er=D550772E-34BB-4DCB-89C9-E746FAD83D24&tz=330"
print(stringURL)
let charSet = NSCharacterSet.URLPathAllowedCharacterSet()
let encoded = stringURL.stringByAddingPercentEncodingWithAllowedCharacters(charSet)!
let url = NSURL(string: encoded.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLFragmentAllowedCharacterSet())!)!
print(url) //https%253A//my.server.com/login.php%253Fe=email&dn=my%25E2%2580%2599s%2520iPad&d=5&er=D550772E-34BB-4DCB-89C9-E746FAD83D ... 4&tz=330
EDIT 2:
How to encode NSWindowsCP1250StringEncoding in swift2.0 ?
Use URLPathAllowedCharacterSet() as character set:
let stringURL = "myurl.php?deviceName=name'phone"
let charSet = NSCharacterSet.URLPathAllowedCharacterSet()
let encoded = stringURL.stringByAddingPercentEncodingWithAllowedCharacters(charSet)!
let url = NSURL(string: encoded)!
print(url) // "myurl.php%3FdeviceName=name'phone"
Note that ' doesn't have to be encoded, it's a valid URL character.
Update: in the comments you state that it's still not working because your encoded URL is truncated and contains ..., but actually this is likely to be just a printed description truncated by NSURL; the actual URL contained by the NSURL object should be ok. Otherwise it would be nil. You should check on your server side for problems with very long but correct URLs.
let newURLEncodedString = urlString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())