Send image AND parameters to web server with Swift 3 - swift3

I am sending image to server successfully but fileName is showing Nil or [].How to slove this issue. I shared my source code also.
#IBAction func upLoadBtn(_ sender: Any)
{
let myUrl = NSURL(string: "http://digilegal.neviton.com:8080/Legal-app/uploadGenDoc");
//let myUrl = NSURL(string: "http://www.boredwear.com/utils/postImage.php");
let request = NSMutableURLRequest(url:myUrl! as URL)
request.httpMethod = "POST"
let obj1:String = String(masterIdStored)
let obj2:String = String(associateStored)
let obj3:String = String(associateNameStored)
print("obj1 is:\(obj1)")
let param = [
"masterClientId" : obj1,
"uploaderId" : obj2,
"uploaderName" : obj3
] as [String : Any]
print("param is:\(param)")
let boundary = generateBoundaryString()
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let imageData = UIImageJPEGRepresentation(imageView.image!, 1)
if(imageData==nil) { return; }
request.httpBody = createBodyWithParameters(parameters: param as! [String : String], filePathKey: "file", imageDataKey: imageData! as NSData, boundary: boundary) as Data
// myActivityIndicator.startAnimating();
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil {
print("error=\(error)")
return
}
// You can print out response object
print("******* response = \(String(describing: response))")
// Print out reponse body
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("****** response data = \(responseString!)")
let respVO:[RespVo] = Mapper<RespVo>().mapArray(JSONString: responseString! as String)!
print("responseString = \(respVO)")
let successResp = respVO[0].response
let statusResp = "Documents saved successfully"
if successResp! == (statusResp as NSString) as String {
DispatchQueue.main.async(execute: { () -> Void in
// self.submitOutlet.isUserInteractionEnabled = false
let ViewController = self.storyboard?.instantiateViewController(withIdentifier: "CustomSecondAlertViewController") as! CustomSecondAlertViewController
ViewController.view.backgroundColor = UIColor.black.withAlphaComponent(0.6)
self.addChildViewController(ViewController)
self.view.addSubview(ViewController.view)
self.dismiss(animated: false, completion: nil)
})
}
}
task.resume()
}
func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, imageDataKey: NSData, boundary: String) -> NSData {
let body = NSMutableData();
if parameters != nil {
for (key, value) in parameters! {
body.appendString(string: "--\(boundary)\r\n")
body.appendString(string: "Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString(string: "\(value)\r\n")
}
}
//let newObj = "manu.jpg"
//let manuObj = fileNameLabel.text
body.appendString(string: "--\(boundary)\r\n")
var mimetype = "image/jpg"
//let defFileName = fileNameObj
let imageData = UIImageJPEGRepresentation(imageView.image!, 1)
print("defFileName is :\(String(describing: imageData))")
let fnamed = fileNameObj
print("fnamed is:\(fnamed)")
body.appendString(string: "Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(String(describing: fnamed))\"\r\n")
body.appendString(string: "Content-Type: \(mimetype)\r\n\r\n")
body.append(imageData!)
body.appendString(string: "\r\n")
body.appendString(string: "--\(boundary)--\r\n")
return body
}
func generateBoundaryString() -> String {
return "Boundary-\(NSUUID().uuidString)"
}
extension NSMutableData {
func appendString(string: String) {
let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true)
append(data!)
}
}

Related

How to get each data from JSON on Swift 3?

I'm registering some data of user in database and after that the API returns others data in JSON usuario, like this:
And i'm trying to get idUsuario, nome and cpf from this JSON and print to see if they are correct, but they don't appear on console!
#IBAction func botaoSalvar(_ sender: Any) {
let nomeUsuario = self.campoUsuario.text;
let cpf = self.campoCPF.text;
let senha = self.campoSenha.text;
let parameters = ["nome": nomeUsuario, "cpf": cpf, "senha": senha, "method": "app-set-usuario"]
let urlPost = "http://easypasse.com.br/gestao/wsCadastrar.php"
guard let url = URL(string: urlPost) else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: []) else { return }
request.httpBody = httpBody
let session = URLSession.shared
session.dataTask(with: request) {
(data, response, error) in
if let data = data {
do {
let dadosJson = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
if let usuario = json["usuario"] as? [String: Any] {
let idUsuario = usuario["idUsuario"] as? Int
let nome = usuario["nome"] as? String
let cpf = usuario["cpf"] as? Int
print(idUsuario as! Int, nome as! String, cpf as! Int)
}
} catch {
print(error)
}
}
}.resume()
The value for key usuario is an array, please notice the (, dictionary is {. Blame the owner of the service for singular / plural confusion 😉.
This is your code with a few swiftifications (native collection types and no never .mutableContainers):
if let data = data {
do {
if let dadosJson = try JSONSerialization.jsonObject(with: data) as? [String:Any],
let usuarios = dadosJson["usuario"] as? [[String:Any]] {
for usuario in usuarios {
if let nomeUsuario = usuario["nome"] as? String {
print(nomeUsuario)
}
if let idUsuario = usuario["idUsuario"] as? Int { // can also be `String`
print(idUsuario)
}
if let cpf = usuario["cpf"] as? Int { // can also be `String`
print(cpf)
}
}
}
} catch {
print(error)
}
}

unable to save the data in api using POST method in swift

I am not able to see the changes as per required in API, when I am using the Post method to do so can I get the correct solution. Here is the Code that I have written
#IBAction func savebutton(_ sender: Any) {
if let id1 = UserDefaults.standard.string(forKey: "Userid"),let usertype1 = UserDefaults.standard.string(forKey: "Usertype")
{
var request = URLRequest(url: URL(string: "http://www.shreetechnosolution.com/funded/donorprofile.php")!)
request.httpMethod = "POST"
let postString = "Name=\(textname.text!)&Gender=\(textGender.text!)&Email=\(textemail.text!)&MobileNo=\(textmb.text!)&Country=\(textcountry.text!)&donorid=\(id1)&usertype=\(usertype1)"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(String(describing: error))")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
let json = try! JSONSerialization.jsonObject(with: data, options: []) as! NSDictionary
let msg = json.value(forKey: "message") as! NSString!
let alert : UIAlertView = UIAlertView(title: "Alert box!", message: "\(msg!).",delegate: nil, cancelButtonTitle: "OK")
alert.show()
}
}
}
Can anyone help me, please?

swift | unresolved identifier error

Here is the code:
let task: URLSessionDataTask = session.dataTask(with: request as URLRequest) { (data, response, error) -> Void in
// Get the HTTP status code of the request.
let statusCode = (response as! HTTPURLResponse).statusCode
if statusCode == 200 {
// Convert the received JSON data into a dictionary.
do {
if let dataDictionary = (try? JSONSerialization.jsonObject(with: data!, options: [JSONSerialization.ReadingOptions.mutableContainers])) as? [String:Any] { let accessToken = dataDictionary["access_token"] as? String }
UserDefaults.setObject(accessToken, forKey: "LIAccessToken")
UserDefaults.standard.synchronize()
DispatchQueue.main.async(execute: { () -> Void in
self.dismiss(animated: true, completion: nil)
})
}
catch {
print("Could not convert JSON data into a dictionary.")
}
}
new Code: ( this is from app coda that is not able to compile in latest swift,https://github.com/appcoda/LinkedInSignInDemo/blob/master/LISignIn/WebViewController.swift)
let dataDictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)
let accessToken = dataDictionary["access_token"] as! String
NSUserDefaults.standardUserDefaults().setObject(accessToken, forKey: "LIAccessToken")
NSUserDefaults.standardUserDefaults().synchronize()
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.dismissViewControllerAnimated(true, completion: nil)
})
You have to use like this :
You defined accessToken in if loop. And you are accessing it outside of it.
if let dataDictionary = (try? JSONSerialization.jsonObject(with: data!, options: [JSONSerialization.ReadingOptions.mutableContainers])) as? [String:Any] {
let accessToken = dataDictionary["access_token"] as? String
UserDefaults.setObject(accessToken, forKey: "LIAccessToken")
}

Error handling in swift 3 using objectMapper and alamofire

How i can handle error in completion block if get error from server side.Here is object mapper class for login.
class Login: Mappable {
var result: LoginData?
var success: Bool?
var error: String?
required init?(map: Map){
}
func mapping(map: Map) {
result <- map["data"]
success <- map["success"]
error <- map["error"]
}
}
class LoginData: Mappable {
var name: String?
var title: String?
var token: String?
var imageUrl: String?
required init?(map: Map){
}
func mapping(map: Map) {
name <- map["name"]
title <- map["title"]
token <- map["token"]
name <- map["name"]
imageUrl <- map["imageUrl"]
}
}
Here is my api calling from view controller.
func loginMethod(){
let postData = ["username":loginDict.object(forKey: KUserUserId) as! String,
"password": loginDict.object(forKey: KUserPass) as! String]
userLoginHttp(parameters: postData){ completion in
self.getUserLoginResponse(result: completion)
}
}
func getUserLoginResponse(result: LoginData) {
// Here i do further
}
This is Network class mthod from where i fire the service
//User login web service
func userLoginHttp(parameters:Parameters, completion:#escaping (_
result:LoginData)->()) {
let defaultObject = UserDefaults.standard
var headerToken = String()
if let x = defaultObject.object(forKey: KDeviceToken)
{
headerToken = x as! String
}
else{
headerToken = ""
}
let headers = ["fcmToken": headerToken]
Alamofire.request(KLoginUrl, method: .post, parameters: parameters,encoding: JSONEncoding.default, headers: headers)
.validate()
.responseObject{ (response: DataResponse<Login>) in
switch response.result{
case .success:
let value = response.result.value
completion((value?.result)!)
case .failure(let error):
print(error.localizedDescription)
}
}
}
So how i can handle error in my view controller completion block?
you can just create another handler for errors and call it in error case
func userLoginHttp(parameters:Parameters,
completion:#escaping (_ result:LoginData)->(),
errorHandler:#escaping (_ result:Error,_ statusCode:Int?)->()//error handler
) {
let defaultObject = UserDefaults.standard
var headerToken = String()
if let x = defaultObject.object(forKey: KDeviceToken)
{
headerToken = x as! String
}
else{
headerToken = ""
}
let headers = ["fcmToken": headerToken]
Alamofire.request(KLoginUrl, method: .post, parameters: parameters,encoding: JSONEncoding.default, headers: headers)
.validate()
.responseObject{ (response: DataResponse<Login>) in
switch response.result{
case .success:
let value = response.result.value
completion((value?.result)!)
case .failure(let error):
errorHandler(error,response.response?.statusCode)//call error handler
print(response.response?.statusCode)
print(error.localizedDescription)
}
}
}
usage
func loginMethod(){
let postData = ["username":loginDict.object(forKey: KUserUserId) as! String,
"password": loginDict.object(forKey: KUserPass) as! String]
userLoginHttp(
parameters: postData,
completion:{ completion in
self.getUserLoginResponse(result: completion)
},
errorHandler:{ error,code in
//do your error stuff
})
}
func getUserLoginResponse(result: LoginData) {
// Here i do further
}

api youtube in swift 3 error 403

I am trying to use youtube api in ios swift, and following this tutorial
http://www.appcoda.com/youtube-api-ios-tutorial/
HTTP Status Code = 403
Error while loading channel details: nil
I'm using swift 3
var urlString = "https://www.googleapis.com/youtube/v3/search?part=snippet&q=\(textField.text)&type=\(type)&key=\(apiKey)"
urlString = urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
// Create a NSURL object based on the above string.
let targetURL = URL(string: urlString)
// Get the results.
performGetRequest(targetURL, completion: { (data, HTTPStatusCode, error) -> Void in
if HTTPStatusCode == 200 && error == nil {
// Convert the JSON data to a dictionary object.
do {
let resultsDict = try JSONSerialization.jsonObject(with: data!, options: []) as! Dictionary<String, AnyObject>
// Get all search result items ("items" array).
let items: Array<Dictionary<String, AnyObject>> = resultsDict["items"] as! Array<Dictionary<String, AnyObject>>
// Loop through all search results and keep just the necessary data.
for i in 0 ..< items.count {
let snippetDict = items[i]["snippet"] as! Dictionary<String, AnyObject>
// Gather the proper data depending on whether we're searching for channels or for videos.
if self.segDisplayedContent.selectedSegmentIndex == 0 {
// Keep the channel ID.
self.desiredChannelsArray.append(snippetDict["channelId"] as! String)
}
else {
// Create a new dictionary to store the video details.
var videoDetailsDict = Dictionary<String, AnyObject>()
videoDetailsDict["title"] = snippetDict["title"]
videoDetailsDict["thumbnail"] = ((snippetDict["thumbnails"] as! Dictionary<String, AnyObject>)["default"] as! Dictionary<String, AnyObject>)["url"]
videoDetailsDict["videoID"] = (items[i]["id"] as! Dictionary<String, AnyObject>)["videoId"]
// Append the desiredPlaylistItemDataDict dictionary to the videos array.
self.videosArray.append(videoDetailsDict)
// Reload the tableview.
self.tblVideos.reloadData()
}
}
} catch {
print(error)
}
// Call the getChannelDetails(…) function to fetch the channels.
if self.segDisplayedContent.selectedSegmentIndex == 0 {
self.getChannelDetails(true)
}
}
else {
print("HTTP Status Code = \(HTTPStatusCode)")
print("Error while loading channel videos: \(error)")
}
// Hide the activity indicator.
self.viewWait.isHidden = true
})
return true
}
// MARK: Custom method implementation
func performGetRequest(_ targetURL: URL!, completion: #escaping (_ data: Data?, _ HTTPStatusCode: Int, _ error: NSError?) -> Void) {
// let request = NSMutableURLRequest(url: targetURL)
// request.httpMethod = "GET"
var request = URLRequest(url: targetURL)
request.httpMethod = "GET"
let sessionConfiguration = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfiguration)
/* let task = session.dataTask(with: request, completionHandler: { (data: Data?, response: URLResponse?, error: NSError?) -> Void in
DispatchQueue.main.async(execute: { () -> Void in
completion(data, (response as! HTTPURLResponse).statusCode, error)
})
} as! (Data?, URLResponse?, Error?) -> Void)*/
/* let task = session.dataTask(with: request, completionHandler: ({ (data: Data?, response: URLResponse?, error: NSError?) -> Void in
DispatchQueue.main.async(execute: { () -> Void in
completion(data as Data?, (response as! HTTPURLResponse).statusCode, error)
})
} as! (Data?, URLResponse?, Error?) -> Void))*/
let task = session.dataTask(with: request) { data, response, error in DispatchQueue.main.async { completion(data, (response as! HTTPURLResponse).statusCode, error as? NSError) } }
task.resume()
}
First of all the JSON dictionary representation in Swift 3 is [String:Any] (aka Dictionary<String,Any>)
Second of all in Swift 3 all parameter labels in closures have been removed
func performGetRequest(_ targetURL: URL, completion: #escaping (Data?, Int, NSError?) -> Void) {
Do not use implicit unwrapped optionals for method parameter types. Either use regular optional (?) or non-optional.
Error 403 means Forbidden Access. Make sure you have the correct apiKey from google/youtube developer.
I also used the appcoda youtube api tutorial (which is in Swift 2 I think) and this is a working version of mine for swift 3.
func getVideosForChannelAtIndex() {
let urlString = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=\(playlistID)&maxResults=\(maxResults)&key=\(apiKey)"
// Create a NSURL object based on the above string.
let targetURL = URL(string: urlString)
// Fetch the playlist from Google.
performGetRequest(targetURL!) { (data, HTTPStatusCode, error) -> Void in
if HTTPStatusCode == 200 && error == nil {
do {
self.videos = []
// Convert the JSON data into a dictionary.
let resultsDict = try JSONSerialization.jsonObject(with: data!, options: []) as! Dictionary<AnyHashable, Any>
// Get all playlist items ("items" array).
let items:Array<Dictionary<AnyHashable, Any>> = resultsDict["items"] as! Array<Dictionary<AnyHashable, Any>>
// Use a loop to go through all video items.
// for var i=0; i<items.count; ++i
for i in 0 ..< items.count {
let playlistSnippetDict = (items[i] as Dictionary<AnyHashable, Any>)["snippet"] as! Dictionary<AnyHashable, Any>
let video = Video()
video.title = playlistSnippetDict["title"] as? String
// video.thumbnail =
video.videoId = (playlistSnippetDict["resourceId"] as? Dictionary<AnyHashable, Any>)?["videoId"] as? String
guard let thumbnail = ((playlistSnippetDict["thumbnails"] as? Dictionary<AnyHashable, Any>)?["high"] as? Dictionary<AnyHashable, Any>)?["url"] as? String else {
video.thumbnail = UIImage(named: "Icon1024x1024")
return
}
guard let url:URL? = URL(string: thumbnail), let data:Data? = try? Data(contentsOf: url!) else {
video.thumbnail = UIImage(named: "Icon1024x1024")
return
}
if let dataImage = data {
video.thumbnail = UIImage(data: dataImage)
} else {
video.thumbnail = UIImage(named: "Icon1024x1024")
}
self.videos.append(video)
// Reload the tableview.
self.tblVideos.reloadData()
}
} catch {
print("json error: \(error)")
}
} else {
print("")
print("HTTP Status Code = \(HTTPStatusCode)")
print("")
//Show alertDialog here with Error
print("Error while loading videos: \(error?.localizedDescription)")
let alert = UIAlertView(title: "Oops!", message: error?.localizedDescription, delegate: self, cancelButtonTitle: "OK")
alert.show()
}
// Hide the activity indicator.
self.viewWait.isHidden = true
}
}
This is for the performGetRequest
func performGetRequest(_ targetURL: URL, completion: #escaping (_ data: Data?, _ HTTPStatusCode: Int?, _ error: Error?) -> Void) {
var request = URLRequest(url: targetURL)
request.httpMethod = "GET"
let sessionConfiguration = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfiguration)
let task = session.dataTask(with: request) { data, response, error in
DispatchQueue.main.async(execute: {
completion(data, (response as? HTTPURLResponse)?.statusCode, error)
})
}
task.resume()
}