HTTP Headers w/ NSURLRequest in swift - swift

Anybody have an idea how to configure HTTP Headers with NSURLRequest in Swift? I have authentication set up on my server and it only needs a token passed to it but I'm having trouble setting the header
my code:
func getLatestData() {
var loggedInUsersNumber:String = SharingManager.sharedInstance.userID
var usersDataPoint:String = StormDataPoint + loggedInUsersNumber
activityIND.hidden = false
activityIND.startAnimating()
let request = NSURLRequest(URL: NSURL(string: usersDataPoint)!)
let tokenString = SharingManager.sharedInstance.authToken
//request.setValue("Token " + tokenString, forKey: "Authorization")
let urlSession = NSURLSession.sharedSession()
let task = urlSession.dataTaskWithRequest(request, completionHandler: {
(data, response, error) -> Void in
if let error = error {
print(error)
return }
I created a property "tokenString" to be the token to pass into the header and on the next line where i commented it out. request.setvalue - I popped it in and get an error to the tune of "cannot override data type". All my searches show Objective C help. Is there a better way to try to pass a header in?

In Swift 3, use the URLRequest structure instead of NSURLRequest (similarly, NSURL ↦ URL, NSURLSession ↦ URLSession, etc.).
Then use addValue(_:forHTTPHeaderField:) to add a header.
// swift 3:
var request = URLRequest(url: URL(string: usersDataPoint)!)
request.addValue("Token \(tokenString)", forHTTPHeaderField: "Authorization")
In Swift 2.2, you use an NSMutableURLRequest if you need to modify it.
// swift 2:
let request = NSMutableURLRequest(URL: NSURL(string: usersDataPoint)!)
request.addValue("Token \(tokenString)", forHTTPHeaderField: "Authorization")

You can create Mutable URL Request, then set value for field name.
let request = NSMutableURLRequest(URL: NSURL(string: yourURLString)!)
request.setValue("\(yourValue)", forHTTPHeaderField: "Header-field-name")

Swift3 bigger example
var req: URLRequest = /* create requets */
req.setValue("Bearer Y3GzLG2x6wSXihmUGhwGFw", forHTTPHeaderField: "Authorization")
req.timeoutInterval = 10
let task = URLSession.shared.dataTask(with: req, completionHandler: { (data, response, error) in
print("completionHandler invoked")
})
task.resume()

private func getHeaderData(url:String) -> Dictionary<String, String> {
let strLanguage:String = LanguageManager.sharedInstance.getCurrentLanuage()
let params:[String:String] = [WSKeys.XAPIkey: XAPIKeyString,
WSKeys.language:strLanguage
]
return params
}
class NetworkManager: NSObject {
static let shared = NetworkManager()
//MARK: - WS CALLS Methods
func GETRequset(showLoader: Bool, url:String, success:#escaping (AnyObject!) -> Void, failed:#escaping (AnyObject!) -> Void) {
self.startProgressLoading(isStart: showLoader)
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "GET"
request.allHTTPHeaderFields = getHeaderData(url: url)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print("O/P error=\(error.debugDescription)")
self.stopProgressLoading()
failed(error.debugDescription as AnyObject!)
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
self.stopProgressLoading()
failed(response as AnyObject!)
}
let responseString = String(data: data, encoding: .utf8)
self.stopProgressLoading()
DispatchQueue.main.async {
success(responseString as AnyObject!)
}
}
task.resume()
}
func POSTRequset(showLoader: Bool, url:String, parameter:[String : AnyObject]?, success:#escaping (AnyObject!) -> Void, failed:#escaping (AnyObject!) -> Void) {
self.startProgressLoading(isStart: showLoader)
let boundary = "Boundary-\(NSUUID().uuidString)"
let url = URL(string: url)
let request = NSMutableURLRequest(url: url!)
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let headerData = getHeaderData(url: (url?.absoluteString)!)
request.allHTTPHeaderFields = headerData
var body = Data()
if parameter != nil {
for (key, value) in parameter! {
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append("\(value)\r\n".data(using: String.Encoding.utf8)!)
}
}
body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)
request.httpBody = body
let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {
data, response, error in
print("##############################################################################")
guard let data = data, error == nil else {
failed(error.debugDescription as AnyObject!)
self.stopProgressLoading()
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
self.stopProgressLoading()
failed(response as AnyObject!)
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode == 401 {
self.stopProgressLoading()
failed(response as AnyObject!)
}
let responseString = String(data: data, encoding: .utf8)
let dict = self.convertToDictionary(text: responseString!)
if dict != nil
{
print("O/P responseDict = \(String(describing: dict))")
}
else
{
print("O/P responseString = \(String(describing: responseString))")
}
print("##############################################################################")
if (dict?["status"]) != nil {
let strStatus = dict?[WSKeys.status] as! NSNumber
let strMessage = dict?[WSKeys.message] as! NSString
self.stopProgressLoading()
if strStatus == 401{
failed(strMessage)
DispatchQueue.main.async {
getDelegate().logOut()
}
} else {
DispatchQueue.main.async {
success(dict as AnyObject!)
}
}
}
})
task.resume()
}
func POSTJsonArrayRequset(showLoader: Bool, url:String, parameter:[String : AnyObject]?, success:#escaping (AnyObject!) -> Void, failed:#escaping (AnyObject!) -> Void) {
self.startProgressLoading(isStart: showLoader)
let request = NSMutableURLRequest(url: URL(string:url)!)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try! JSONSerialization.data(withJSONObject: parameter)
request.httpMethod = "POST"
let headerData = getHeaderData(url: url)
request.allHTTPHeaderFields = headerData
let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {
data, response, error in
print("##############################################################################")
print("URL: \(String(describing: url))")
print("PARAMS: \(String(describing: parameter))")
print("Headers: \(headerData)")
print("Method: Post")
guard let data = data, error == nil else {
print("O/P error=\(error.debugDescription)")
failed(error.debugDescription as AnyObject!)
self.stopProgressLoading()
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
print("O/P statusCode should be 200, but is \(httpStatus.statusCode)")
// print("O/P response = \(String(describing: response))")
self.stopProgressLoading()
failed(response as AnyObject!)
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode == 401 {
print("O/P statusCode should be 401, but is \(httpStatus.statusCode)")
// print("O/P response = \(String(describing: response))")
self.stopProgressLoading()
failed(response as AnyObject!)
}
let responseString = String(data: data, encoding: .utf8)
let dict = self.convertToDictionary(text: responseString!)
if dict != nil
{
print("O/P responseDict = \(String(describing: dict))")
}
else
{
print("O/P responseString = \(String(describing: responseString))")
}
print("##############################################################################")
let strStatus = dict?[WSKeys.status] as! NSNumber
let strMessage = dict?[WSKeys.message] as! NSString
self.stopProgressLoading()
if strStatus == 401{
failed(strMessage)
DispatchQueue.main.async {
getDelegate().logOut()
}
} else {
DispatchQueue.main.async {
success(dict as AnyObject!)
}
}
})
task.resume()
}
func POSTJsonArrayRequsetTap(showLoader: Bool, url:String, parameter:[String : AnyObject]?, success:#escaping (AnyObject!) -> Void, failed:#escaping (AnyObject!) -> Void) {
self.startProgressLoading(isStart: showLoader)
let request = NSMutableURLRequest(url: URL(string:url)!)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try! JSONSerialization.data(withJSONObject: parameter)
request.httpMethod = "POST"
let headerData = ["content-type": "application/json"]
request.allHTTPHeaderFields = headerData
let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {
data, response, error in
print("##############################################################################")
print("URL: \(String(describing: url))")
print("PARAMS: \(String(describing: parameter))")
print("Headers: \(headerData)")
print("Method: Post")
guard let data = data, error == nil else {
print("O/P error=\(error.debugDescription)")
failed(error.debugDescription as AnyObject!)
self.stopProgressLoading()
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
print("O/P statusCode should be 200, but is \(httpStatus.statusCode)")
// print("O/P response = \(String(describing: response))")
self.stopProgressLoading()
failed(response as AnyObject!)
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode == 401 {
print("O/P statusCode should be 401, but is \(httpStatus.statusCode)")
// print("O/P response = \(String(describing: response))")
self.stopProgressLoading()
failed(response as AnyObject!)
}
let responseString = String(data: data, encoding: .utf8)
let dict = self.convertToDictionary(text: responseString!)
if dict != nil
{
print("O/P responseDict = \(String(describing: dict))")
}
else
{
print("O/P responseString = \(String(describing: responseString))")
}
print("##############################################################################")
let strStatus = dict?[WSKeys.status] as! NSNumber
let strMessage = dict?[WSKeys.message] as! NSString
self.stopProgressLoading()
if strStatus == 401{
failed(strMessage)
DispatchQueue.main.async {
getDelegate().logOut()
}
} else {
DispatchQueue.main.async {
success(dict as AnyObject!)
}
}
})
task.resume()
}
func convertToDictionary(text: String) -> [String: Any]? {
if let data = text.data(using: .utf8) {
do {
return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
} catch {
print(error.localizedDescription)
}
}
return nil
}
func MultipartFormDataRequset(showLoader: Bool, urlString:String, mediaKey:String?, mediaDataArray:[Dictionary<String, AnyObject>]?, parameter:[String : AnyObject]?, success:#escaping (AnyObject!) -> Void, failed:#escaping (AnyObject!) -> Void) {
let boundary = "Boundary-\(NSUUID().uuidString)"
let url = URL(string: urlString)
let request = NSMutableURLRequest(url: url!)
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.allHTTPHeaderFields = getHeaderData(url: urlString)
var body = Data()
if parameter != nil {
for (key, value) in parameter! {
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append("\(value)\r\n".data(using: String.Encoding.utf8)!)
}
}
if mediaDataArray != nil {
var i = 0
for var dict in mediaDataArray! {
let data = dict["data"]
let mimetype = "application/octet-stream"
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
let key = "\(String(describing: mediaKey))[\(i)]"
body.append("Content-Disposition: form-data; name=\"\(key)\"; filename=\"\(dict["fileName"]!)\"\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append(data! as! Data)
body.append("\r\n".data(using: String.Encoding.utf8)!)
i = i + 1
}
}
body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)
request.httpBody = body
let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {
data, response, error in
guard let data = data, error == nil else {
print("O/P error=\(error.debugDescription)")
failed(error.debugDescription as AnyObject!)
self.stopProgressLoading()
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
print("O/P statusCode should be 200, but is \(httpStatus.statusCode)")
print("O/P response = \(String(describing: response))")
self.stopProgressLoading()
failed(response as AnyObject!)
}
let responseString = String(data: data, encoding: .utf8)
print("O/P responseString = \(String(describing: responseString))")
self.stopProgressLoading()
DispatchQueue.main.async {
success(responseString as AnyObject!)
}
})
task.resume()
}
func MultipartFormDataForSingleMediaRequset(showLoader: Bool, url:String, mediaData:Data?, mediaKey:String?, parameter:[String : AnyObject]?, success:#escaping (AnyObject!) -> Void, failed:#escaping (AnyObject!) -> Void) {
let startBoundry:String = "AaB03x"
let url = URL(string: url)!
var request:URLRequest = URLRequest(url: url as URL, cachePolicy: URLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 10)
request.allHTTPHeaderFields = getHeaderData(url: url.absoluteString)
let boundary:String = "--\(startBoundry)"
let endMPboundary:String = "\(boundary)--"
let imageData:Data = mediaData!
var body:String = String()
if parameter != nil {
for (key, value) in parameter! {
body = body + "\(boundary)\r\n"
body = body + "Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n"
body = body + "\(value)\r\n"
}
}
body = body + "\(boundary)\r\n"
body = body + "Content-Disposition: form-data; name=\"\(mediaKey!)\"; filename=\"\("attachment.png")\"\r\n"
body = body + "Content-Type: image/png\r\n\r\n"
let end:String = "\r\n\(endMPboundary)"
var myRequestData:Data = Data();
myRequestData.append(body.data(using: String.Encoding(rawValue: String.Encoding.utf8.rawValue))!)
myRequestData.append(imageData as Data)
myRequestData.append(end.data(using: String.Encoding.utf8)!)
let content:String = "multipart/form-data; boundary=\(startBoundry)"
request.setValue(content, forHTTPHeaderField: "Content-Type")
request.setValue("\(myRequestData.count)", forHTTPHeaderField: "Content-Length")
request.httpBody = myRequestData as Data
request.httpMethod = "POST"
let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {
data, response, error in
guard let data = data, error == nil else {
print("O/P error=\(error.debugDescription)")
failed(error.debugDescription as AnyObject!)
self.stopProgressLoading()
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
print("O/P statusCode should be 200, but is \(httpStatus.statusCode)")
print("O/P response = \(String(describing: response))")
self.stopProgressLoading()
failed(response as AnyObject!)
}
let responseString = String(data: data, encoding: .utf8)
print("O/P responseString = \(String(describing: responseString))")
self.stopProgressLoading()
DispatchQueue.main.async {
success(responseString as AnyObject!)
}
})
task.resume()
}
private func startProgressLoading(isStart: Bool) {
DispatchQueue.main.async {
UIApplication.shared.isNetworkActivityIndicatorVisible = true
}
}
private func stopProgressLoading() {
DispatchQueue.main.async {
UIApplication.shared.isNetworkActivityIndicatorVisible = false
}
}
}
func getProductDetail(productID:String, success: #escaping (ProductDetailDataModel?) -> Void, failed: #escaping (AnyObject!) -> Void) {
if isConnectedToInternet() {
theController.showLoader()
let addressURL = productDetailURL
let theParamDict = [WSKeys.product_id : productID] as [String: AnyObject]
NetworkManager.shared.POSTRequset(showLoader: true, url: addressURL, parameter: theParamDict , success: { (responseObject) in
self.theController.hideLoader()
guard let data = responseObject.object(forKey: "data") as? NSDictionary else {
success(nil)
return
}
guard let storeInfo = data.object(forKey: "productDetailsInfo") as? [String: AnyObject] else {
success(nil)
return
}
let dataArray = self.setStoreDetail(dictData: storeInfo)
success(dataArray)
}, failed: { (error) in
self.theController.hideLoader()
print("error is \(error)")
failed(error)
})
} else {
failed("No Internet Connection" as AnyObject)
}
}
struct ProductDetailDataModel {
var strStoreID: String? = nil
var strPrice:NSNumber? = nil
var strType:NSNumber? = nil
var strSellerID:String? = nil
var dicSeller:[String:AnyObject] = [:]
var arrStoreMedia: [[String: AnyObject]]?
mutating func setTheProperties(theDict: [String: AnyObject]) {
strStoreID = "\(String(describing: theDict["product_id"]!))"
strPrice = theDict["price"] as? NSNumber
dicSeller = theDict["seller"] as! [String:AnyObject]
arrStoreMedia = theDict["products_medias"] as? [[String: AnyObject]]
for product in arrStoreMedia!
{
if let photo_original = product["photo_original"] as? String, photo_original != ""
{
strPhotoOrignal = photo_original
break;
}
}
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let cell = tblHome.dequeueReusableCell(withIdentifier: "CellHeadetTC") as! CellHeadetTC
cell.advertisements = homeDetail.arrAdvertisement
return cell
}
else if indexPath.row == 1 {
let cell = tblHome.dequeueReusableCell(withIdentifier: "CellHomeTableView") as! CellHomeTableView
cell.selectionStyle = .none
cell.nav = self.navigationController
cell.arrCat = homeDetail.arrCategory
cell.collectionViewCategory.reloadData()
return cell
}
else {
let cell = tblHome.dequeueReusableCell(withIdentifier: "CellServiceTableView") as! CellServiceTableView
cell.selectionStyle = .none
if indexPath.row == 2 {
cell.lblheader.text = "Pending Service".localized()
cell.arrService = homeDetail.arrRecentService
cell.btnSeeAll.addTarget(self, action: #selector(HomeViewControlller.btnRecentSeeAllClicked(_:)), for: .touchUpInside)
}
else{
cell.lblheader.text = "Upcoming Services".localized()
cell.arrService = homeDetail.arrUpcommingService
cell.btnSeeAll.addTarget(self, action : #selector(HomeViewControlller.btnUpcomingSeeAllClicked(_:)), for: .touchUpInside)
}
return cell
}
}
var arrCategory = [Categorys]()
let temp = responseDict["data"]!.dictionaryValue
let arrCategory = temp["categories"]!.arrayValue
let homeClass = HomeClass()
for i in 0..<arrCategory.count {
let dict = arrCategory[i].dictionaryValue
let categoryData = Categorys()
categoryData.strId = dict["id"]?.stringValue
homeClass.arrCategory.append(categoryData)
}

Related

How can I send nil picture as a Swift Data type in to REST service in Swift?

I am trying to upload pictures(with FTP way) by REST Service. So I have a function like below:
func saveFeedBack(feedbackType: String, feedbackText: String, picture1: Data, picture2: Data, picture3: Data)
{
let parameters = [
"ofeedbackType": feedbackType,
"ofeedbackText": feedbackText
]
let oimage1 = UIImage(data: picture1)
let oimage2 = UIImage(data: picture2)
let oimage3 = UIImage(data: picture3)
guard let mediaImage1 = Media(withImage: oimage1!, forKey: "pic1") else { return }
guard let mediaImage2 = Media(withImage: oimage2!, forKey: "pic2") else { return }
guard let mediaImage3 = Media(withImage: oimage3!, forKey: "pic3") else { return }
guard let url = URL(string: "http://abc.def.com/Mobile/SSS/feedback") else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
let boundary = generateBoundary()
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let dataBody = createDataBody(withParameters: parameters, media: [mediaImage1, mediaImage2, mediaImage3], boundary: boundary)
request.httpBody = dataBody
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print(response)
}
if let data = data
{
do
{
if let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any]
{
//some code in here
}
}
catch
{
print(error)
}
}
}.resume()
}
Here is the Media struct:
import UIKit
struct Media {
let key: String
let filename: String
let data: Data
let mimeType: String
init?(withImage image: UIImage, forKey key: String) {
self.key = key
self.mimeType = "image/jpeg"
self.filename = "fotograf.jpg"
guard let data = image.jpegData(compressionQuality: 1) else { return nil }
self.data = data
}
}
Let's talk about this scenario: Let's say I am sending picture 1 and picture 2. But I am not sending picture 3. Of course I am getting below error because of this code: guard let mediaImage3 = Media(withImage: oimage3!, forKey: "pic3") else { return }
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
How can I get rid of above problem? Pictures should be optional. I mean: functions should work fine if I don't send any picture.
Here is the CreateDataBody function
func createDataBody(withParameters params: Parameters?, media: [Media]?, boundary: String) -> Data {
let lineBreak = "\r\n"
var body = Data()
if let parameters = params {
for (key, value) in parameters {
body.append("--\(boundary + lineBreak)")
body.append("Content-Disposition: form-data; name=\"\(key)\"\(lineBreak + lineBreak)")
body.append("\(value + lineBreak)")
}
}
if let media = media {
for photo in media {
body.append("--\(boundary + lineBreak)")
body.append("Content-Disposition: form-data; name=\"\(photo.key)\"; filename=\"\(photo.filename)\"\(lineBreak)")
body.append("Content-Type: \(photo.mimeType + lineBreak + lineBreak)")
body.append(photo.data)
body.append(lineBreak)
}
}
body.append("--\(boundary)--\(lineBreak)")
return body
}
Can you try this?
import UIKit
struct Media {
let key: String
let filename: String
let data: Data?
let mimeType: String
init?(withImage image: UIImage, forKey key: String) {
self.key = key
self.mimeType = "image/jpeg"
self.filename = "photo.jpg"
self.data = image.jpegData(compressionQuality: 1)
}
}
func createDataBody(withParameters params: Parameters?, media: [Media]?, boundary: String) -> Data {
let lineBreak = "\r\n"
var body = Data()
if let parameters = params {
for (key, value) in parameters {
body.append("--\(boundary + lineBreak)")
body.append("Content-Disposition: form-data; name=\"\(key)\"\(lineBreak + lineBreak)")
body.append("\(value + lineBreak)")
}
}
if media != nil {
print("media cnt: ", media!.count)
if let media = media {
for photo in media {
body.append("--\(boundary + lineBreak)")
body.append("Content-Disposition: form-data; name=\"\(photo.key)\"; filename=\"\(photo.filename)\"\(lineBreak)")
body.append("Content-Type: \(photo.mimeType + lineBreak + lineBreak)")
body.append(photo.data!)
body.append(lineBreak)
print("photo.key", photo.key)
}
}
}
body.append("--\(boundary)--\(lineBreak)")
return body
}
func saveFeedBack(feedbackType: String, feedbackText: String, picture1: Data, picture2: Data, picture3: Data)
{
var imageList : [Media] = []
let parameters = [
"ofeedbackType": feedbackType,
"ofeedbackText": feedbackText
]
if let img1 = UIImage(data: picture1) {
if img1.size.width > 0 {
if let oImg1 = Media(withImage: img1, forKey: "pic1") {
imageListe.append(oImg1)
}
}
}
if let img2 = UIImage(data: picture2) {
if img2.size.width > 0 {
if let oImg2 = Media(withImage: img2, forKey: "pic2") {
imageListe.append(oImg2)
}
}
}
if let img3 = UIImage(data: picture3) {
if img3.size.width > 0 {
if let oImg3 = Media(withImage: img3, forKey: "pic3") {
imageListe.append(oImg3)
}
}
}
guard let url = URL(string: "http://abc.des.com/Test/SSS/feedback") else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
let boundary = generateBoundary()
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let dataBody = createDataBody(withParameters: parameters, media:imageList , boundary: boundary)
request.httpBody = dataBody
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print(response)
}
if let data = data
{
do
{
if let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any]
{
//some code in here
}
}
catch
{
print(error)
}
}
}.resume()
}
Just try with that hopefully this will work. I have made some changes.
Model:
struct Media {
let key: String
let filename: String
let data: Data
let mimeType: String
init?(withImage image: UIImage, forKey key: String) {
self.key = key
self.mimeType = "image/jpeg"
self.filename = "fotograf.jpg"
guard let data = image.jpegData(compressionQuality: 1) else { return nil }
self.data = data
}
}
Code:
func saveFeedBack(feedbackType: String, feedbackText: String, picture1: Data, picture2: Data, picture3: Data)
{
let parameters = [
"ofeedbackType": feedbackType,
"ofeedbackText": feedbackText
]
guard let oimage1 = UIImage(data: picture1) else { return }
guard let oimage2 = UIImage(data: picture2) else { return }
guard let oimage3 = UIImage(data: picture3) else { return }
let mediaImage1 = Media(withImage: oimage1, forKey: "pic1")
let mediaImage2 = Media(withImage: oimage2, forKey: "pic2")
let mediaImage3 = Media(withImage: oimage3, forKey: "pic3")
guard let url = URL(string: "http://abc.def.com/Mobile/SSS/feedback") else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
let boundary = generateBoundary()
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let dataBody = createDataBody(withParameters: parameters, media: [mediaImage1, mediaImage2, mediaImage3], boundary: boundary)
request.httpBody = dataBody
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print(response)
}
if let data = data
{
do
{
if let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any]
{
//some code in here
}
}
catch
{
print(error)
}
}
}.resume()
}

How to wait for a download task to finish in swift 3

I am trying to build a user regeistration form, which should check if the user already exists. So I am sending a php request to my my mysql server. If the return value is empty, the user does not exists yet.
Unfortunatley I am really stuck with waiting for this check to finish. I tried several solutions I found googleing but none of them worked. My current code uses semaphores and will crash with "fatal error: unexpectedly found nil while unwrapping an Optional value", so the semaphore is not waiting until the task is finished as I would expect it.
Any hints, would be greatly appreciated. Thanks guys.
private func isUniqueEmail(email: String) -> Bool {
var result: Bool?
let semaphore = DispatchSemaphore(value: 1)
let requestURL = URL(string: "http://localhost/firstpostget/functions/get.php")
var request = URLRequest(url: requestURL!)
request.httpMethod = "POST"
let postParameters = "email=" + email
request.httpBody = postParameters.data(using: .utf8)
let configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main)
let task = session.dataTask(with: request) {(data, response, error) in
var myJson: AnyObject
do{
myJson = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
if myJson.count == 0{
result = true
semaphore.signal()
} else{
result = false
semaphore.signal()
}
} catch{
//TODO
print(error)
}
}
task.resume()
semaphore.wait(timeout: .distantFuture)
return result!
}
Your task is async and you are force unwrapping nil value so this is the reason it crashes.
You have to change your function implementation to also be async, for example using closures:
private func isUniqueEmail(email: String, completion: ((Bool) -> (Void))?) {
let requestURL = URL(string: "http://localhost/firstpostget/functions/get.php")
var request = URLRequest(url: requestURL!)
request.httpMethod = "POST"
let postParameters = "email=" + email
request.httpBody = postParameters.data(using: .utf8)
let configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main)
let task = session.dataTask(with: request) {(data, response, error) in
var myJson: AnyObject
do{
myJson = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
if myJson.count == 0 {
completion?(true)
} else{
completion?(false)
}
} catch{
//TODO
print(error)
}
}
task.resume()
}
Now you can use this function in this way:
isUniqueEmail(email: "aaa#bbbb.com") { result in
if result {
print("email unique")
} else {
print("email not unique")
}
}
I think you should rethink the pattern you're using to get the data out of your request, you should consider using a custom handler/callback method that you pass along with the email you're trying to check. See below for an example:
private func isUniqueEmail(email: String, handler: ((_ result: Bool) -> Void)?) -> Void {
let requestURL = URL(string: "http://localhost/firstpostget/functions/get.php")
var request = URLRequest(url: requestURL!)
request.httpMethod = "POST"
let postParameters = "email=" + email
request.httpBody = postParameters.data(using: .utf8)
let configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main)
let task = session.dataTask(with: request) {(data, response, error) in
var myJson: AnyObject
var result: Bool = false
do{
myJson = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
if myJson.count == 0 {
result = true
}
guard handler != nil else {
return
}
handler!(result)
} catch{
//TODO
print(error)
}
}
task.resume()
}
Run:
isUniqueEmail(email: "test#test.com", handler: { result in
print(result) // true || false
})
If you really want to go down the "wait" route then take a took at DispatchGroup's
https://developer.apple.com/documentation/dispatch/dispatchgroup
try using this:
ApihelperClass
static let sharedInstance = ApihelperClass()
typealias CompletionHandler = (_ success:Bool, _ error:Bool, _ result:NSDictionary) -> Void
typealias ErrorHandler = (_ success: Bool, _ error:Bool) -> Void
func callPostRequest(_ urlPath: String, params:[String: AnyObject], completionHandler: #escaping CompletionHandler, errorHandler:#escaping ErrorHandler ){
print("urlPath:==> \(urlPath) ")
let session = Foundation.URLSession.shared
let url = URL(string: urlPath)
var request = URLRequest(url : url!)
request.httpMethod = "POST"
do {
let jsonData = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData
session.dataTask(with: request, completionHandler: { data, response, error in
OperationQueue.main.addOperation {
guard error == nil && data != nil else { // check for fundamental networking error
print("error=\(error)")
errorHandler(false, true)
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 = \(response)")
}
let responseString = String(data: data!, encoding: String.Encoding.utf8)
print("responseString = \(responseString!)")
if let responsedata = responseString!.data(using: String.Encoding.utf8)! as? Data{
do {
let jsonResult:NSDictionary = try JSONSerialization.jsonObject(with: responsedata, options: []) as! NSDictionary
print("Get The Result \(jsonResult)")
//parse your jsonResult as per your requirements
if error != nil {
print("error=\(error)")
completionHandler(false, true, jsonResult)//
}
if let str = jsonResult["success"] as? NSNull {
print("error=\(str)")
completionHandler(false, true, jsonResult)
}
else {
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
// print("Response string : \(responseString)")
completionHandler(true, false, jsonResult)
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
}
}) .resume()
}catch {
print("Error ->Catch")
}
}
Add to your viewcontroller
func isUniqueEmail(email: String){
ApihelperClass.sharedInstance.callPostRequest("http://localhost/firstpostget/functions/get.php", params: ["email":email as AnyObject], completionHandler: { (success, error, result) in
//success 200
}) { (success, error) in
//error
}
}
you can use URlSession like :
func isUniqueEmail(email: String,completion: #escaping (Bool) -> ()) {
var request = URLRequest(url: URL(string: "http://localhost/firstpostget/functions/get.php")!)
request.httpMethod = "POST"
let postString = "email=\(email)"
request.httpBody = postString.data(using: .utf8)
// loading to wait request
UIApplication.shared.isNetworkActivityIndicatorVisible = true
let task = URLSession.shared.dataTask(with: request) { data, response, error in
// we get request request
UIApplication.shared.isNetworkActivityIndicatorVisible = false
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(String(describing: error))")
completion(false)
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))")
completion(false)
}else{
completion(true)
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(String(describing: responseString))")
}
task.resume()
}
and used in code Like
self.isUniqueEmail(email: "your Email") { (isExit) in
if isExit {
}else{
}
}
Ok, I just found a solution. My semaphore approach actually worked as well as dispatchgroups. The task just needed to be URLSession.shared.dataTask
Still thank's a lot for all the answers.

Callback syntax in swift 3

I am trying to create a callback on swift 3 but haven't had any luck so far. I was taking a look at this question: link which is similar, but the answer gives me an error.
Basically I have an API struct with a static function that I need to have a callback.
import UIKit
struct API {
public static func functionWithCallback(params: Dictionary<String, String>, success: #escaping ((_ response: String) -> Ticket), failure: #escaping((_ error:String) -> String) ) {
let app_server_url = "http://api.com" + params["key"]!
let url: URL = URL(string: app_server_url)!
var request: URLRequest = URLRequest(url: url)
request.httpMethod = "POST"
do {
request.httpBody = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
} catch let error {
print(error.localizedDescription)
}
request.addValue("application/json charset=utf-8", forHTTPHeaderField: "Content-Type")
request.addValue("application/json charset=utf-8", forHTTPHeaderField: "Accept")
let session = URLSession.shared
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
guard error == nil else {
return
}
guard let data = data else {
return
}
DispatchQueue.main.async {
do {
let json = try JSONSerialization.jsonObject(with: data) as! [String: Any]
print(json)
var message = ""
if let result = json["result"] as? String {
if(result == "success") {
//attempt to call callback gives me an error: extra argument in call
success("") {
let ticket = json["ticket"] as! NSDictionary
var date = ticket["date"] as! String
var ticket: Ticket = nil
ticket.setDate(date: date)
return ticket
}
}
else {
message = json["message"] as! String
print(message)
}
} catch let error {
print(error.localizedDescription)
let description = error.localizedDescription
if let data = description.data(using: .utf8) {
do {
let jsonError = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
let message = jsonError?["message"] as! String
} catch {
}
}
}
}
})
task.resume()
}
}
So I basically can't call the callback success because it gives me an error: Extra argument in call. Any idea on how to fix it?
My goal is to call:
API.functionWithCallback(params: params, success() -> Ticket {
//do something with the returned ticket here
},
error() -> () {
//do something with the error message here
}
)
I believe you have it wrong on how to use call back closures, from what I can understand of your question you want to do something with the ticket in the call back closure and to do that it should be a parameter of the closure not the return type of the closure.
Replace your function declaration with this:
public static func functionWithCallback(params: Dictionary<String, String>, success: #escaping ((_ response: String, _ ticket: Ticket) -> Void), failure: #escaping((_ error:String) -> Void) ) {
And inside the function replace this:
success("") {
let ticket = json["ticket"] as! NSDictionary
var date = ticket["date"] as! String
var ticket: Ticket = nil // Im not sure what you are trying to do with this line but this will definitely give an error
ticket.setDate(date: date)
return ticket
}
With:
let ticket = json["ticket"] as! NSDictionary
var date = ticket["date"] as! String
var ticket: Ticket = nil // fix this line
ticket.setDate(date: date)
success("",ticket)
And then you can call the function like this:
API.functionWithCallback(params: params, success: { response, ticket in
// you can use ticket here
// and also the response text
}) { errorMessage in
// use the error message here
}
Try this :
func uploadImage(api: String,token : String, methodType : String, requestDictionary: [String:AnyObject],picData:[Data], successHandler: #escaping (AnyObject) -> Void,failureHandler: #escaping (NSError) -> Void)
{
if Common_Methods.Reachability1.isConnectedToNetwork() == false
{
let del :AppDelegate = (UIApplication.shared.delegate as? AppDelegate)!
let nav : UINavigationController = (del.window?.rootViewController as? UINavigationController)!
let alert = UIAlertController(title: "", message: "The Internet connection appears to be offline" , preferredStyle: UIAlertControllerStyle.alert)
// Create the actions
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default)
{
UIAlertAction in
}
alert.addAction(okAction)
nav.present( alert, animated: true, completion: nil)
return
}
let apiUrl = "\(KbaseUrl)\(api)"
let session = URLSession.shared
let url: NSURL = NSURL(string: apiUrl as String)!
print(url)
let request = NSMutableURLRequest(url: url as URL)
request.httpMethod = methodType
let boundary = NSString(format: "---------------------------14737809831466499882746641449") as String
//-------- add token as perameter and set a check if token not nill then set token in header -------
if(token.characters.count > 0)
{
request.setValue(token, forHTTPHeaderField: "x-logintoken")
}
request.setValue("Keep-Alive", forHTTPHeaderField: "Connection")
request.setValue("multipart/form-data; boundary="+boundary, forHTTPHeaderField: "Content-Type")
let data = createBodyWithParameters(parameters: requestDictionary, filePathKey:nil, imageDataKey: picData.count > 0 ? picData : [], boundary: boundary)
print(data)
request.httpBody = data
let task = session.dataTask(with: request as URLRequest) { data, response, error in
// handle fundamental network errors (e.g. no connectivity)
guard error == nil && data != nil else {
successHandler(data as AnyObject )//completion(data as AnyObject?, error as NSError?)
print(error)
DispatchQueue.main.async {
Common_Methods.hideHUD(view: (topVC?.view)!)
}
return
}
// check that http status code was 200
if let httpResponse = response as? HTTPURLResponse , httpResponse.statusCode != 200 {
do {
let responseObject = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary
if let responseDictionary = responseObject as? [String:AnyObject]
{
if responseDictionary["statusCode"] as! Int == 401
{
// self.objDelegate.sessionExpire(msgStr: "Session Expired. Please login again to continue.")
}
else
{
//completion(String(data: data!, encoding: String.Encoding.utf8) as AnyObject?, nil)
}
}
} catch let error as NSError {
print(error)
DispatchQueue.main.async {
Common_Methods.hideHUD(view: (topVC?.view)!)
}
// completion(String(data: data!, encoding: String.Encoding.utf8) as AnyObject?, nil)
}
}
// parse the JSON response
do {
DispatchQueue.main.async {
Common_Methods.hideHUD(view: (topVC?.view)!)
}
let responseObject = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary
successHandler(responseObject! )
} catch let error as NSError {
DispatchQueue.main.async {
Common_Methods.hideHUD(view: (topVC?.view)!)
}
// completion(String(data: data!, encoding: String.Encoding.utf8) as AnyObject?, error)
failureHandler(error)
}
}
task.resume()
// return task
}
and function Call is :
WebService.sharedInstance.uploadImage(api: KEditEmployerProfile,token: token,methodType: "PUT", requestDictionary: parameters1 as! [String : AnyObject], picData: [imageData as Data], successHandler: { (responseObject) in
print(responseObject)
}) { (error) in
print(error)
}
}

How to receive data from Server in "Multipart/form-data" in iOS swift?

func postRequestUsingDictionaryParametersImage(requestType : String, urlComponent : String, inputParameters : NSDictionary, completion: (result : NSData, httpResponse : NSHTTPURLResponse) -> Void, failure:(error: NSError) ->()){
let accessToken : String = "Bearer " + (TNPAppData.sharedInstane.objTNPUserData?.accessToken)!
let urlString: String = "\(kBaseURLString)\(urlComponent)"
do {
let jsonData = try NSJSONSerialization.dataWithJSONObject(inputParameters, options: NSJSONWritingOptions.PrettyPrinted)
let jsonString = NSString(data: jsonData, encoding: NSUTF8StringEncoding)! as String
let data = jsonString.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: false)
let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
request.HTTPMethod = requestType
request.HTTPBody = data
request.setValue("application/Json", forHTTPHeaderField: "Content-Type")
request.setValue("multipart/form-data", forHTTPHeaderField: "Accept")
request.setValue(accessToken, forHTTPHeaderField: "Authorization")
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
guard error == nil && data != nil else {
// check for fundamental networking error
print("error=\(error)")
failure(error: error!)
return
}
do{
let dict = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments) as! [String:AnyObject]
print("Response from Server :", dict)
}
catch let error as NSError{
print(error)
}
let httpStatus = response as? NSHTTPURLResponse
print(httpStatus)
if httpStatus?.statusCode == 401 {
// Make Request for New Access Token
let str = TNPAppData.sharedInstane.objTNPUserData!.refreshToken
let inputparameters = "grant_type=refresh_token&refresh_token=" + str
print(inputparameters)
self.requestTokenAgain2("token", inputParameters: inputparameters, requestType: "POST", refrshcompletion: { (result, httpResponse) in
do {
let dict = try NSJSONSerialization.JSONObjectWithData(result, options: .AllowFragments) as! [String:AnyObject]
print("Response from Server :", dict)
let httpStatus = httpResponse as? NSHTTPURLResponse
if httpStatus?.statusCode == 400{
completion(result: result, httpResponse: (response as? NSHTTPURLResponse)!)
}
else if httpStatus?.statusCode == 200{
let obj = TNPUserData(dictionary: dict)
TNPAppData.sharedInstane.objTNPUserData = obj
print("New Token Received")
print(obj.accessToken)
print(obj.bodyAccessToken)
print(obj.refreshToken)
// Now Call Get Details API Again
self.postRequestUsingDictionaryParameters2(requestType, urlComponent: urlComponent, inputParameters: inputParameters, completion: completion, failure: failure)
}
else{
// Go back to login screen
failure (error: error!)
}
} catch let error as NSError {
print(error)
}
}, failure: { (error) in
print(error)
})
} else {
if error != nil {
failure (error: error!)
} else {
completion(result: data!, httpResponse: (response as? NSHTTPURLResponse)!)
}
}
}
task.resume()
}
catch let error as NSError {
print(error)
}
}

swift, send file to server

I am learning swift and I send a request to the server with the code below. It works for simple request and I get response from the server. My problem is I can not send a file to server.
code :
let parameters = parameter
let request = NSMutableURLRequest(URL: NSURL(string: requestUrl)!)
let boundaryConstant = "-----Boundary+\(arc4random())\(arc4random())"
let contentType = "multipart/form-data; boundary=" + boundaryConstant
let boundaryStart = "--\(boundaryConstant)\r\n"
let boundaryEnd = "--\(boundaryConstant)--\r\n"
let body:NSMutableString = NSMutableString();
for (key, value) in parameters {
body.appendFormat(boundaryStart)
body.appendFormat("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendFormat("\(value)\r\n")
}
body.appendFormat(boundaryEnd)
request.HTTPMethod = "POST"
request.setValue(contentType, forHTTPHeaderField: "Content-Type")
request.HTTPBody = body.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
guard error == nil && data != nil else {
// check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
self.responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)!
print("MMMMMMMM \(self.responseString)")
self.result = self.responseString.dataUsingEncoding(NSUTF8StringEncoding)! as NSData
callback(self.responseString)
}
print("code start")
task.resume()
result :
i can post file to server by this code:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let request = createRequest()
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
if error != nil {
// handle error here
print(error)
return
}
do {
if let responseDictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
print("success == \(responseDictionary)")
}
} catch {
print(error)
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("responseString = \(responseString)")
}
}
task.resume()
}
func createRequest () -> NSURLRequest {
let param = []
let boundary = generateBoundaryString()
let url = NSURL(string: "URl")!
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
request.setValue("userValue", forHTTPHeaderField: "X-Client-user")
request.setValue("passValue", forHTTPHeaderField: "X-Access-pass")
//let path1 = NSBundle.mainBundle().pathForResource("voice", ofType: "png") as String!
request.HTTPBody = createBodyWithParameters(param, filePathKey: "voice", paths: ["pathURl"], boundary: boundary)
return request
}
func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, paths: [String]?, boundary: String) -> NSData {
let body = NSMutableData()
if parameters != nil {
for (key, value) in parameters! {
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString("\(value)\r\n")
}
}
if paths != nil {
for path in paths! {
let url = NSURL(fileURLWithPath: path)
let filename = url.lastPathComponent
let data = NSData(contentsOfURL: url)!
let mimetype = mimeTypeForPath(path)
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename!)\"\r\n")
body.appendString("Content-Type: \(mimetype)\r\n\r\n")
body.appendData(data)
body.appendString("\r\n")
}
}
body.appendString("--\(boundary)--\r\n")
return body
}
func generateBoundaryString() -> String {
return "Boundary-\(NSUUID().UUIDString)"
}
func mimeTypeForPath(path: String) -> String {
let url = NSURL(fileURLWithPath: path)
let pathExtension = url.pathExtension
if let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension! as NSString, nil)?.takeRetainedValue() {
if let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue() {
return mimetype as String
}
}
return "application/octet-stream";
}
As you read here, you should use NSURLSession for HTTP work, it far more flexible and powerful; and I think is destined to replace NSURLconnection...
https://www.objc.io/issues/5-ios7/from-nsurlconnection-to-nsurlsession/
Here is a example for you...
func getMetaData(lePath:String, completion: (string: String?, error: ErrorType?) -> Void) {
// **** get_metadata ****
let request = NSMutableURLRequest(URL: NSURL(string: "https://api.dropboxapi.com/2/files/get_metadata")!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
request.addValue("Bearer ab-blah-blah", forHTTPHeaderField: "Authorization")
request.addValue("application/json",forHTTPHeaderField: "Content-Type")
request.addValue("path", forHTTPHeaderField: lePath)
let cursor:NSDictionary? = ["path":lePath]
do {
let jsonData = try NSJSONSerialization.dataWithJSONObject(cursor!, options: [])
request.HTTPBody = jsonData
print("json ",jsonData)
} catch {
print("snafoo alert")
}
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
if let error = error {
completion(string: nil, error: error)
return
}
let strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Body: \(strData)\n\n")
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers);
self.jsonParser(jsonResult,field2file: "ignore")
for (key, value) in self.parsedJson {
print("key2 \(key) value2 \(value)")
}
completion(string: "", error: nil)
} catch {
completion(string: nil, error: error)
}
})
task.resume()
}
Great answer above.. Here it's updated for Swift3:
func getMetaData(lePath:String, completion: (string: String?, error: ErrorType?) -> Void) {
// **** get_metadata ****
let request = NSMutableURLRequest(URL: NSURL(string: "https://api.dropboxapi.com/2/files/get_metadata")!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
request.addValue("Bearer ab-blah-blah", forHTTPHeaderField: "Authorization")
request.addValue("application/json",forHTTPHeaderField: "Content-Type")
request.addValue("path", forHTTPHeaderField: lePath)
let cursor:NSDictionary? = ["path":lePath]
do {
let jsonData = try NSJSONSerialization.dataWithJSONObject(cursor!, options: [])
request.HTTPBody = jsonData
print("json ",jsonData)
} catch {
print("snafoo alert")
}
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
if let error = error {
completion(string: nil, error: error)
return
}
let strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Body: \(strData)\n\n")
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers);
self.jsonParser(jsonResult,field2file: "ignore")
for (key, value) in self.parsedJson {
print("key2 \(key) value2 \(value)")
}
completion(string: "", error: nil)
} catch {
completion(string: nil, error: error)
}
})
task.resume()
}