HTTP2 does not work with AVPlayer in Swift - ios

Currently I'm trying to send the token via headers in Swift but looks like the problem consist in HTTP2.
Example:
AVURLAsset
let headers: [AnyHashable : Any] = [
"content-type": "application/json",
"authorization": "Bearer \(token)"
]
let videoAsset = AVURLAsset(url: videoUrl)
let subtitleAsset = AVURLAsset(url: vttURL, options: ["AVURLAssetHTTPHeaderFieldsKey": headers])
Error
Task <B2755FA5-132C-4EE2-A72F-269EAEA8035C>.<5> finished with error [100] Error Domain=NSPOSIXErrorDomain Code=100 "Protocol error" UserInfo={_NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <B2755FA5-132C-4EE2-A72F-269EAEA8035C>.<5>, _kCFStreamErrorDomainKey=1, NSErrorPeerAddressKey=<CFData 0x600000ff2300 [0x7fff80617cb0]>{length = 16, capacity = 16, bytes = 0x100201bb0de06a770000000000000000}, _kCFStreamErrorCodeKey=100, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <B2755FA5-132C-4EE2-A72F-269EAEA8035C>.<5>"
Related issues
https://forums.developer.apple.com/thread/105771
https://developer.apple.com/documentation/network/debugging_https_problems_with_cfnetwork_diagnostic_logging

Related

Alamofire post method in iOS Swift 4?

For getting push notification here i am sending postitem, token, like count and currentname using alamofire post method(pod version alamofire 4.5). I did not get any response when post method called and it does not show any errors.
I tried keeping breaking points in alamofire function, it call alamofire.requestion then it goes out function.
Here is the code tried to send post method to backend:
func postNotification(postItem: String, post: Post) {
print("Get token from post:::",post.token)
print(postItem)
let token = UserDefaults.standard.string(forKey: "token")
let headers: HTTPHeaders = ["Content-Type" :"application/x-www-form-urlencoded"]
let parameters : [String:Any] = ["count":post.likeCount!, "likedby":currentName, "postId=":postItem, "token": post.token!]
Alamofire.request("http://highavenue.co:9000/likesnotification/", method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: nil).responseJSON { (response:DataResponse<Any>) in
switch(response.result) {
case .success(_):
if let data = response.result.value{
print(data)
}
break
case .failure(_):
print(response.result.error as Any)
break
}
}
}
Getting console error like this
2018-07-10 14:21:07.980212+0530 HighAvenue[10584:4236493] Task <B5FC98AB-C3FE-
4D4F-9A93-72D3FFE35DF7>.<1> finished with error - code: -1001
Optional(Error Domain=NSURLErrorDomain Code=-1001 "The request timed out."
UserInfo={NSUnderlyingError=0x1c0e478f0 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=http://highavenue.co:9000/likesnotification/, NSErrorFailingURLKey=http://highavenue.co:9000/likesnotification/, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-2102, NSLocalizedDescription=The request timed out.})
That is because you are not setting request time in your network call, by default your request time is a small interval, so please increase request timeout time. something like this,
let request = NSMutableURLRequest(url: URL(string: "")!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.timeoutInterval = 120 // 120 secs
let values = ["key": "value"]
request.httpBody = try! JSONSerialization.data(withJSONObject: values, options: [])
Alamofire.request(request as! URLRequestConvertible).responseJSON {
response in
// do whatever you want here
}
Second mistake in your code is you are trying to access http url which are by default are not allowed so you have to by pass this security from your app, Please refer to this answer in order to remove this security layer from your app.
The resource could not be loaded because the App Transport Security policy requires the use of a secure connection

Can not fetch data using Alamofire?

I am trying to fetch data in my iOS app from my Django backend. In postman if I perform a GET request on the following URL http://127.0.0.1:8000/api/places/categories with the params being Key:"Authorization" Value: "Bearer access_token".I get a JSON response.
Inside my app I am doing something like this with the help of Alamofire:
let access_token = "123"
let headers = ["Authorization": "Bearer" + access_token]
Alamofire.request(self.categoriesUrl, method: .get, parameters:nil,encoding: JSONEncoding.default,headers: headers).response { response in
print("Request: \(response.request)")
print("Response: \(response.response)")
print("Error: \(response.error)")
if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
print("Data: \(utf8Text)")
}
}
I get an error saying Authorization Credentials were not provided. I understand this and it asks me to pass in the parameters but the parameters just need a token. So I do something like this:
let access_token = "123"
let params = ["Authorization": "Bearer" + access_token]
Alamofire.request(self.categoriesUrl, method: .get, parameters:params,encoding: JSONEncoding.default,headers: nil).response { response in
print("Request: \(response.request)")
print("Response: \(response.response)")
print("Error: \(response.error)")
if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
print("Data: \(utf8Text)")
}
}
It waits for a while but fails to fetch the data with the following error:
Response: nil
Error: Optional(Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={NSUnderlyingError=0x61800004b0d0 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=http://127.0.0.1:8000/api/places/categories/, NSErrorFailingURLKey=http://127.0.0.1:8000/api/places/categories/, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-2102, NSLocalizedDescription=The request timed out.})
Data:
EDIT1:
This is very simple to fix, I guess you are using iOS10 or later version of OS. So instead of calling http , just call https, which means the API calling protocol has been changed to http to https in iOS10 and later.
You have a typo here :
let params = ["Authorization": "Bearer" + access_token]
You're missing a space after Bearer.

Self-signed certificate iOS

I am trying to configure my iOS app to accept self-signed certificates.
I am trying to fetch the data on a button click. Below is the code that I am using currently:
private var manager : SessionManager?
func setManager(url: String) {
let serverTrustPolicies: [String: ServerTrustPolicy] = [
url: .disableEvaluation
]
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders
manager = Alamofire.SessionManager(
configuration: configuration,
serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
)
}
#IBAction func nonCertifiedClick(_ sender: UIButton) {
outputText.text = ""
setManager(url: "sand.xxx.int:16443")
manager?.request("https://sand.xxx.int:16443/version").response { response in
debugPrint("R: \(response)")
if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
print("Data: \(utf8Text)")
self.outputText.text = utf8Text
}
}
}
My Info.plist file has the below configuration:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
But when the request is executed, I get the following response:
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
"R: DefaultDataResponse(request: Optional(https://sand.xxx.int:16443/version), response: nil, data: Optional(0 bytes),
error: Optional(Error Domain=NSURLErrorDomain Code=-1202 \"The certificate for this server is invalid. You might be connecting to a server that is pretending to be “sand.xxx.int” which could put your confidential information at risk.\"
UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x600000105730>,
NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?,
_kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9813,
NSErrorPeerCertificateChainKey=(\n \"<cert(0x7fcf8b81e800) s: sand i: sand>\"\n),
NSUnderlyingError=0x60000005f440 {Error Domain=kCFErrorDomainCFNetwork Code=-1202 \"(null)\" UserInfo={_kCFStreamPropertySSLClientCertificateState=0,
kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x600000105730>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9813,
_kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9813,
kCFStreamPropertySSLPeerCertificates=(\n \"<cert(0x7fcf8b81e800) s: sand i: sand>\"\n)}},
NSLocalizedDescription=The certificate for this server is invalid. You might be connecting to a server that is pretending to be “sand.xxx.int” which could put your confidential information at risk.,
NSErrorFailingURLKey=https://sand.xxx.int:16443/version,
NSErrorFailingURLStringKey=https://sand.xxx.int:16443/version, NSErrorClientCertificateStateKey=0}),
_metrics: Optional((Task Interval) <_NSConcreteDateInterval: 0x600000224e40> (Start Date) 2016-11-02 14:13:57 +0000 + (Duration) 0.381569 seconds = (End Date) 2016-11-02 14:13:58 +0000\n(Redirect Count) 0\n(Transaction Metrics) (Request) <NSURLRequest: 0x600000200120> { URL: https://sand.xxx.int:16443/version }\n(Response) (null)\n(Fetch Start) 2016-11-02 14:13:57 +0000\n(Domain Lookup Start) (null)\n(Domain Lookup End) (null)\n(Connect Start) (null)\n(Secure Connection Start) (null)\n(Secure Connection End) (null)\n(Connect End) (null)\n(Request Start) 2016-11-02 14:13:57 +0000\n(Request End) 2016-11-02 14:13:57 +0000\n(Response Start) 2016-11-02 14:13:57 +0000\n(Response End) (null)\n(Protocol Name) (null)\n(Proxy Connection) NO\n(Reused Connection) YES\n(Fetch Type) Unknown\n\n))"
Data:
I am testing this on Xcode 8.1 with Swift3 and Alamofire4.
What am I misisng here to make it work right?
Update (Answer)
If incase someone encounters the same issue, the problem was the server's SSL certificate. The certificate needs to be signed with at least SHA256 algorithm but mine was signed with SHA1.
I faced the same problem. But using your question, i found the solution. Tnx..
Here is my solution. it works with swift 3
create a class SecurityCertificateManager
import Foundation
import Alamofire
class SecurityCertificateManager {
static let sharedInstance = SecurityCertificateManager()
let defaultManager: Alamofire.SessionManager = {
let serverTrustPolicies: [String: ServerTrustPolicy] = [
"272.73.41.156": .disableEvaluation
]
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders
return Alamofire.SessionManager(
configuration: configuration,
serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
)
}()
}
call it like this in viewDIdLoad
let baseUrl ="https://272.73.41.156/cas/tickets?"+"username="+userEmail.text!+"&password="+userPassword.text!
print("Base url : \(baseUrl)")
let params2 = ["nostring": "nodata", "nostring": "nodata",]
SecurityCertificateManager.sharedInstance.defaultManager.request(baseUrl, method: .post, parameters: params2, encoding: JSONEncoding.default, headers: ["Content-Type":"application/x-www-form-urlencoded"]).responseJSON { (response:DataResponse<Any>) in
switch(response.result) {
case .success(_):
if response.result.value != nil{
print("response : \(response.result.value)")
}
break
case .failure(_):
print("Failure : \(response.result.error)")
break
}
}
It Works in Swift3

Multipart-form data POST to upload image not working after boundary is added in Swift

So I'm trying to do a multi-part post request in Swift using the following format:
user_id 3232424234
photo *PHOTO DATA*
I set up my request as shown at the bottom of this post and am getting the following error:
Optional(Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={NSUnderlyingError=0x7f86235cfe40 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={_kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=ENDPOINTURL, NSErrorFailingURLKey=ENDPOINTURL, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-4, NSLocalizedDescription=The network connection was lost.})
This error seems extremely odd to me because I can make it go away by omitting the boundary requirements for the POST request, but the server than explodes with a 500 and lets the client know it omitted the boundary reqs, so yah. I am probably doing something wrong in Swift. Below is my code to make the request. Let me know if more info is needed, thx guru's of the world.
//Inputs in this scope are an "id" and a "photo"
let url = NSURL(string: "**URL**")
let boundary = NSUUID()
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
request.setValue("multipart/form-data; boundary=--\(boundary)", forHTTPHeaderField: "Content-Type")
let parameterBody:NSDictionary = [
"user_id": id,
]
let data:NSMutableData = NSMutableData()
parameterBody.enumerateKeysAndObjectsUsingBlock { (parameterKey: AnyObject, parameterValue: AnyObject, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
data.appendData(NSString(string: "--\(boundary)\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
data.appendData(NSString(string: "\(parameterKey) \(parameterValue)\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
}
data.appendData(NSString(string: "--\(boundary)\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
data.appendData(NSString(string: "photo").dataUsingEncoding(NSUTF8StringEncoding)!)
data.appendData(photo.imageData as! NSData)
data.appendData(NSString(string: "--\(boundary)--\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
request.setValue("\(data.length)", forHTTPHeaderField: "Content-Length")
let task = NSURLSession.sharedSession().uploadTaskWithRequest(request, fromData: data) { (responseJSON: AnyObject?, response: NSURLResponse?, error: NSError?) -> Void in
//Here I handle the response and check for errors.
}
task.resume()
There are a ton of issues here:
The boundary should be NSUUID().UUIDString.
When you add the boundary to the Content-Type header, you should not add -- there.
The individual parts of the multipart request are not well-formed. For example, you're missing the Content-Disposition.
It's not critical, but you do not need to set Content-Length of the request. That's done for you.
I'd suggest you refer to this answer which provides example of how to form multipart request: Upload image with parameters in Swift. Or consider using Alamofire, which takes care of all of this for you.

Why am I getting this error posting a request to the Uber Sandbox? NSURLErrorDomain error -1012

I can get product ID's from the products path but I get this error when trying to post a request to the sandbox schedule a ride. Trying to figure out what I'm doing wrong here. I have the bearer token added. I'm not sure what it wants or what is missing.
Error Domain=NSURLErrorDomain Code=-1012 "The operation couldn’t be completed. (NSURLErrorDomain error -1012.)" UserInfo=0x7f8c13939ed0 {NSErrorFailingURLStringKey=https://sandbox-api.uber.com/v1/requests, NSUnderlyingError=0x7f8c0ac78410 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1012.)", NSErrorFailingURLKey=https://sandbox-api.uber.com/v1/requests}
func performPostUberRequest(url: NSURL, prodId: String) {
let params:[String: AnyObject] = [
"start_latitude" : "39.955715",
"start_longitude" : "-75.1680298",
"end_latitude" : "39.9542675",
"end_longitude" : "-75.1409609",
"product_id": prodId
]
var error: NSError?
var request: NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.addValue("Bearer \(uberToken)", forHTTPHeaderField: "Authorization")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions.allZeros, error: &error)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()){
response, data, error in
if let error = error {
println(error)
} else if data != nil {
if let json: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) as? NSDictionary {
println(json)
}
}
}
}
According to your comments: { code = unauthorized; message = "Missing scope: request"; }, you may miss the scope, which can be specified on your Uber developer dashboard where you registered the app and got the secret and client id and stuff.
If you have done this you should have added the necessary scopes into the parameters when you requested authorization code and access token through OAuth2.0 at the beginning.
In my imeplementation, the scopes were specified as the following:
[[NXOAuth2AccountStore sharedStore] setClientID:_clientID
secret:_clientSecret
scope:[NSSet setWithObjects:#"request", #"history_lite", #"profile", #"request_receipt", nil]
authorizationURL:[NSURL URLWithString:#"https://login.uber.com/oauth/authorize"]
tokenURL:[NSURL URLWithString:#"https://login.uber.com/oauth/token"]
redirectURL:[NSURL URLWithString:_redirectURL]
keyChainGroup:nil
forAccountType:_applicationName];

Resources