xcode 10.3
swift 4.2
iPhone app
I'm hitting a post type API to upload image along with some string data from a form. I'm getting response result as success but there is an error parameters which indicates: CredStore - performQuery - Error copying matching creds. Error=-25300
I have tried doing some research and found that I've problem with URLCredentialStorage but I don't have any Credentials in API.
I looked at CredStore Perform Query error, I'm having very similar issue but can't find my solution there.
{
let url = route.asURL(constants: constants)
let parameters = route.asParameters(constants: constants)
let headers: HTTPHeaders = [
"authorization-name": APISession.token,
"Content-Type": "multipart/form-data"
]
Log(request: URLRequest(url: url))
Alamofire.upload(multipartFormData: { (multipartFormData) in
for (key, value) in parameters {
if let strValue = value as? String, let valueData = strValue.data(using: .utf8) {
multipartFormData.append(valueData, withName: key)
}
if let imgValue = value as? UIImage, let imgData = imgValue.jpegData(compressionQuality: 0.5) {
multipartFormData.append(imgData, withName: key, mimeType: "image/jpg")
}
}
}, usingThreshold: UInt64.init(), to: url, method: .post, headers: headers) { (result) in
print(result)
switch result{
case .success(let upload, _, _):
upload.uploadProgress(closure: { (progress) in
print("Preogress is: ", progress.fractionCompleted)
})
upload.responseJSON { response in
print("Succesfully uploaded")
switch response.result {
case .success(let value):
print(value)
case .failure(let error):
print(error)
}
}
case .failure(let error):
print("Error in upload: \(error.localizedDescription)")
}
}
}
I'm getting response like this,
success(request: 2019-08-12 13:07:04.224913-0400 project name[65508:460860] CredStore - performQuery - Error copying matching creds. Error=-25300, query={
class = inet;
"m_Limit" = "m_LimitAll";
ptcl = htps;
"r_Attributes" = 1;
sdmn = "url";
srvr = "url";
sync = syna;
}
so I'm confused why I'm getting success response with error parameters in that.
Not sure but I think authorization-name key present in headers is incorrect. It should be Authorization.
Hello I am doing download file by post with parameters. But server can't receive post parameters.
But if i do same thing with get with url parameters. Everything works fine.
Almofire.request also works fine by post with parameters. But only Almofire.download by post with parameter does not work.
Why Alamofire.download does not send paramters by post method ??
var sourceStringURL : String = "\(tmp_url)download"
let destination: DownloadRequest.DownloadFileDestination =
{
_, _ in
let fileURL = URL(fileURLWithPath: destPath)
return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}
Alamofire.download(sourceStringURL, method: .post, parameters: ["id": idStr, "var": varStr], encoding: JSONEncoding.default, headers: nil, to: destination)
.downloadProgress
{
progress in
var tmpPercent : Int = Int(progress.fractionCompleted*100 / 1.0)
}
.response
{
response in
if let error = response.error
{
print(error)
}
else
{
//success
}
}
Server receives post request correctly with Retrofit library in Android.
I just found that if i change JSONEncoding.default to URLEncoding.default.
It works fine.
I have migrated my project to Swift 3 (and updated Alamofire to latest Swift 3 version with pod 'Alamofire', '~> 4.0' in the Podfile).
I now get an "Extra argument in call" error on every Alamofire.request. Eg:
let patientIdUrl = baseUrl + nextPatientIdUrl
Alamofire.request(.POST, patientIdUrl, parameters: nil, headers: nil, encoding: .JSON)
Can anybody tell me why ?
According to Alamofire documentation for version 4.0.0 URL request with HTTP method would be followings:
Alamofire.request("https://httpbin.org/get") // method defaults to `.get`
Alamofire.request("https://httpbin.org/post", method: .post)
Alamofire.request("https://httpbin.org/put", method: .put)
Alamofire.request("https://httpbin.org/delete", method: .delete)
So your url request will be:
Alamofire.request(patientIdUrl, method: .post, parameters: nil, encoding: JSONEncoding.default, headers: nil)
and a sample request will be:
Alamofire.request(url, method: .post, parameters: param, encoding: JSONEncoding.default, headers: [AUTH_TOKEN_KEY : AUTH_TOKEN])
.responseJSON { response in
print(response.request as Any) // original URL request
print(response.response as Any) // URL response
print(response.result.value as Any) // result of response serialization
}
Hope this helps!
This one worked for me. No need to remove encoding parameter
Update for Swift 5.x
Alamofire uses the Result type introduced in Swift 5.Also Alamofire.request has been changed to AF.request which will now read their switch response.result value with .success and .failure
AF.request("https://yourServiceURL.com", method: .get, parameters: [:], encoding: URLEncoding.default, headers: ["":""]).responseJSON { (response) in
switch response.result {
case let .success(value):
print(value)
case let .failure(error):
print(error)
}
}
Swift 3.x / 4.x
Alamofire.request("https://yourServiceURL.com", 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(response.result.value)
}
break
case .failure(_):
print(response.result.error)
break
}
}
and make sure that the parameters are of type
[String:Any]?
In case of Get
Alamofire.request("https://yourGetURL.com", method: .get, parameters: ["":""], encoding: URLEncoding.default, headers: nil).responseJSON { (response:DataResponse<Any>) in
switch(response.result) {
case .success(_):
if let data = response.result.value{
print(response.result.value)
}
break
case .failure(_):
print(response.result.error)
break
}
}
Even works with
JSONEncoding.default
For Headers
If you are passing headers, make sure their type should be [String:String]
Go through the Parameter Encoding Link
https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%204.0%20Migration%20Guide.md#parameter-encoding-protocol
Post method Alamofire 4.0 with Swift 3.0 and xCode 8.0
Alamofire.request(URL, method: .post, parameters: PARAMS)
.responseJSON { closureResponse in
if String(describing: closureResponse.result) == "SUCCESS"
{
// Sucess code
}
else
{
// Failure Code
}
}
My solution is if you are using headers, its type must be [String:String].
This error is up to parameters value. It has to be [String: String]
let url = URL(string: "http://yourURLhere")!
let params: [String: String] = ["name": "oskarko", "email": "youremail#here.com", "sex": "male"]
Alamofire.request(url, method: .post, parameters: params, encoding: URLEncoding.default, headers: nil).validate(statusCode: 200..<600).responseJSON() { response in
switch response.result {
case .success:
var result = [String:String]()
if let value = response.result.value {
let json = JSON(value)
}
case .failure(let error):
print("RESPONSE ERROR: \(error)")
}
}
I just resolved the same problem as you have. The problem is I have imported Alamofire in the header, so I just remove the Alamofire when call request. Like that:
request(.POST, patientIdUrl, parameters: nil, headers: nil, encoding:
.JSON)
I hope it can help you.
I ran into this same Extra argument 'method' in call error when my URL variable was out of scope.
In your case, please make sure both baseUrl and nextPatientIdUrl are in scope when they are being used Alamofire.request(patientIdUrl,..) method.
Hopefully this resolves your issue. Thanks You!
func API()
{
if Reachability.isConnectedToNetwork()
{
let headers = ["Vauthtoken":"Bearer \(apiToken)"]
print(headers)
// let parameter = ["iLimit":"10","iOffset":"0","iThreadId":"1"]
ApiUtillity.sharedInstance.showSVProgressHUD(text: "Loding...")
Alamofire.request(ApiUtillity.sharedInstance.API(Join: "vehicle/CurrentVehicleLists"), method:.get, parameters:nil, headers: headers).responseJSON { response in
switch response.result {
case .success:
print(response)
ApiUtillity.sharedInstance.dismissSVProgressHUD()
let dictVal = response.result.value
let dictMain:NSDictionary = dictVal as! NSDictionary
let statusCode = dictMain.value(forKey: "status") as! Int
if(statusCode == 200)
{
}
else if statusCode == 401
{
}
else
{
}
case .failure(let error):
print(error)
ApiUtillity.sharedInstance.dismissSVProgressHUD()
}
}
} else
{
ApiUtillity.sharedInstance.dismissSVProgressHUD()
ApiUtillity.sharedInstance.showErrorMessage(Title: "Internet Connection", SubTitle: "Internet connection Faild", ForNavigation: self.navigationController!)
}
}
For me this is working.
For GET Request
Alamofire.request("http://jsonplaceholder.typicode.com/todos/1/get").responseJSON { (response:DataResponse<Any>) in
switch(response.result) {
case .success(_):
if response.result.value != nil{
print(response.result.value!)
}
break
case .failure(_):
print(response.result.error)
break
}
}
For POST
let parameters = NSDictionary(object: "nara", forKey: "simha" as NSCopying)
Alamofire.request("http://jsonplaceholder.typicode.com/posts", method: HTTPMethod.post, parameters: parameters as? Parameters, encoding: JSONEncoding.default, headers: nil).responseJSON { (response:DataResponse<Any>) in
switch(response.result) {
case .success(_):
if response.result.value != nil{
print(response.result.value!)
}
break
case .failure(_):
print(response.result.error)
break
}
}
Thanks #Rajan Maheswari.
I fixed this issue with:
Reorder parameters (url then method type).
Change Encoding Enum to be "JSONEncoding.default" for example.
Note that: Alamofire methods signature change in Swift 3
Two things that I found worth noting.
Remove the first url label before its value. Use
Alamofire.request("https://yourServiceURL.com", method: .post,
instead of Alamofire.request(url: "https://yourServiceURL.com",
method: .post,.
Make sure the data type of the parameters is [String:
String]. Declare it explicitly.
I copy this code from Alamofire,create a URLRequest and used Alamofire.request(URLRequest) method, avoid this error
originalRequest = try URLRequest(url: url, method: method, headers: headers)
let encodedURLRequest = try encoding.encode(originalRequest!, with: parameters)
I fixed this issue this way:
Just remove extra parameters, just parameters, encoding and headers, if these parameters are nil you can remove then and leave this way,
Alamofire.request(yourURLString, method: .post)
If you have added Alamofire files locally then don't use "Alamofire" before request
let apipath = “your api URL”
request(apipath, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: nil).responseJSON { response in switch(response.result) {
case .success(_):
do {
let JSON = try JSONSerialization.jsonObject(with: response.data! as Data, options:JSONSerialization.ReadingOptions(rawValue: 0))
guard let JSONDictionary: NSDictionary = JSON as? NSDictionary else {
print("Not a Dictionary")
return
}
print("Post Response : \(JSONDictionary)")
}
catch let JSONError as NSError {
print("\(JSONError)")
}
break
case .failure(_):
print("failure Http: \(String(describing: response.result.error?.localizedDescription))")
break
}
}
I am trying to update some code for a Alamofire custom response serializer I found this bit of code on "bits of cocoa".
extension Alamofire.Request {
public func responseCollection<T: Decodable>(completionHandler: Response<[T], NSError> -> Void) -> Self {
let responseSerializer = ResponseSerializer<[T], NSError> { request, response, data, error in
guard error == nil else { return .Failure(error!) }
let result = Alamofire
.Request
.JSONResponseSerializer(options: .AllowFragments)
.serializeResponse(request, response, data, error)
switch result {
case .Success(let value):
do {
return .Success(try [T].decode(value))
} catch {
return .Failure(Error.errorWithCode(.JSONSerializationFailed,
failureReason: "JSON parsing error, JSON: \(value)"))
}
case .Failure(let error): return.Failure(error)
}
}
return response(responseSerializer: responseSerializer, completionHandler: completionHandler)
}
}
This is pre swift 3, and Response<[T], NSError> is now a single value specialization Response<[T]> because of this I am not sure how this extension would translate for the changes to Alamofire on the swift 3
I started to update this code this is as far as I got
extension Alamofire.Request {
public func responseCollection<T: Decodable>(completionHandler: (Response<[T]>) -> Void) -> Self {
let responseSerializer = ResponseSerializer<[T]> { request, response, data, error in
guard error == nil else { return .failure(error!) }
let result = Alamofire
.Request
.JSONResponseSerializer(options: .allowFragments)
.serializeResponse(request, response, data, error)
switch result {
case .success(let value):
do {
return .success(try [T].decode(value))
} catch {
return .failure(Error(.errorWithCode(.JSONSerializationFailed, failureReason: "JSON parsing error, JSON: \(value)")))
}
case .failure(let error): return.failure(error)
}
}
return response(responseSerializer: responseSerializer, com
pletionHandler: completionHandler)
}
}
this get me 2 errors that at the moment I have not found any way to fix them:
1) for "return .failure(Error(.errorWithCode(.JSONSerializationFailed, failureReason: "JSON parsing error, JSON: \(value)")))", I am getting this error ('Error' cannot be constructed because it as no accessible initializers)
2) for "return response(responseSerializer: responseSerializer, completionHandler: completionHandler)", I am getting this error (Cannot call value of non-function type 'HTTPURLResponse')
Hopefully if any one can point me to a better solution then this bit of code or the correct fix for this. Thanks I will be working on this still, if I do fix it I will update this ticket.
Edit - update
So This is the code as of now
extension Alamofire.Request {
public func responseDecodable<T: Decodable>(completionHandler: #escaping (Response<T>) -> Void) -> Self {
let responseSerializer = ResponseSerializer<T> { request, response, data, error in
guard error == nil else {
print("error Network request: \(error)")
return .failure(error!)
}
let result = Alamofire
.Request
.JSONResponseSerializer(options: .allowFragments)
.serializeResponse(request, response, data, error)
switch result {
case .success(let value):
do {
let decodableObject = try T.decode(value)
return .success(decodableObject)
} catch let decodeErr {
print(decodeErr)
let failureReason = "JSON parsing error, JSON: \(value)"
let userInfo = [NSLocalizedFailureReasonErrorKey: failureReason]
let error = NSError(domain: "com.prospects.error", code: BackendError.JSONSerializationFailed.rawValue, userInfo: userInfo)
return .failure(error)
}
case .failure(let error): return.failure(error)
}
}
return response(responseSerializer: responseSerializer, completionHandler: completionHandler)
}
}
public protocol ResponseObjectSerializable {
init?(response: HTTPURLResponse, representation: AnyObject)
}
as per last comment : Response and ResponseSerializer are now unresolved, this used to work with no error yesterday. but updating xcode and alamofire this morning as made this to get errors now.
I have the following code snippet to load an image from an url:
let url = NSURL(string: imageUrl)
let data = NSData(contentsOfURL: url!)
let image = UIImage(data: data!)
In case that my variable imageUrl has a valid string value, what is the most secure way to protect this code against possible edge cases?
Following code seems not to be very handy:
if let url = NSURL(string: imageUrl) {
if let data = NSData(contentsOfURL: url) {
if let image = UIImage(data: data) {
// success -> do something with the image...
}
else {
// print error message
}
}
else {
// print error message
}
}
else {
// print error message
}
The best practice is not to use a synchronous method like contentsOfURL to load data from over the network.
The recommended way is NSURLSession which works asynchronously.
This is a simple example with a completion block and an enum with associated types,
it catches all possible errors
enum Result {
case Success(UIImage), Failure(NSString)
}
func loadImage(string : String, completion: (Result) -> ()) {
guard let url = NSURL(string: string) else {
completion(.Failure("Bad URL"))
return
}
NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) in
if error != nil {
completion(.Failure(error!.localizedDescription))
} else {
guard let image = UIImage(data: data!) else {
completion(.Failure("Could not load image data"))
return
}
completion(.Success(image))
}
}.resume()
}
Call it with:
loadImage("http://myserver.com/path/to/image.png") { result in
switch result {
case .Success(let image) :
// do something with the image
case .Failure(let error) :
print(error)
}
}