I want to parse json from java spring code (Xcode 7.3 / Swift). I tried almost every solution from all sites.
When I register it gives the following error message at the console:
Response = Optional(<NSHTTPURLResponse: 0x7a7607e0> { URL: http://www.____.com/saveRegistrationJson.htm } { status code: 405, headers {
Allow = GET;
Connection = "Keep-Alive";
"Content-Length" = 1089;
"Content-Type" = "text/html;charset=utf-8";
Date = "Wed, 04 May 2016 12:21:34 GMT";
"Keep-Alive" = "timeout=15, max=100";
Server = "Apache-Coyote/1.1";
} })
before json
Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.}
This is my Code:
import UIKit
class RegistrationViewController: UIViewController {
#IBOutlet weak var userfnametextfield: UITextField!
#IBOutlet weak var userlnametextfield: UITextField!
#IBOutlet weak var useremailtextfield: UITextField!
#IBOutlet weak var userpwdtextfield: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func RegisterbtnTapped(sender: AnyObject) {
let fname = userfnametextfield.text
let lname = userlnametextfield.text
let Email = useremailtextfield.text
let pwd = userpwdtextfield.text
//check empty fields
if(fname!.isEmpty || lname!.isEmpty || Email!.isEmpty || pwd!.isEmpty )
{
DisplayMyAlertMessage("All Fields are required")
return
}
//store data
NSUserDefaults.standardUserDefaults().setObject(fname, forKey: "fname")
NSUserDefaults.standardUserDefaults().setObject(lname, forKey: "lname")
NSUserDefaults.standardUserDefaults().setObject(Email, forKey: "Email")
NSUserDefaults.standardUserDefaults().setObject(pwd, forKey: "password")
NSUserDefaults.standardUserDefaults().synchronize()
//send user data to server side
let myurl = NSURL(string: "http://www.____.com/saveRegistrationJson.htm")
let request = NSMutableURLRequest(URL: myurl!)
request.HTTPMethod = "POST"
let poststring = "fname\(fname!)&lname\(lname!)&email\(Email!)&password\(pwd!)"
request.HTTPBody = poststring.dataUsingEncoding(NSUTF8StringEncoding)
//request.HTTPBody = postData
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){data,response, error in
if error != nil{
print("Error\(error)")
return
}
print("Response = \(response)")
do{
var err : NSError?
print("before json")
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as? NSDictionary
print(json)
print("After json")
//print("demo : \(response?.description)")
guard let parseJSON = json else{
print("parsing json here:")
return
}
// guard let value = NSString(data: data!, encoding: NSUTF8StringEncoding) else{
// print("parsed")
// return
//}
//print("FirstName\(value)")
var requestValue = parseJSON[" "] as? String
print("result:\(requestValue)")
var isUserRegistered:Bool = false
if(requestValue=="Success") { isUserRegistered = true}
var messageToDisplay:String = parseJSON["Success"] as! String
if(!isUserRegistered){
messageToDisplay = parseJSON[" "] as! String
}
dispatch_async(dispatch_get_main_queue(), {
let myAlert = UIAlertController(title: "Alert", message: messageToDisplay, preferredStyle: UIAlertControllerStyle.Alert)
let onAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default) { (ACTION) -> Void in
self.dismissViewControllerAnimated(true, completion: nil)
}
myAlert.addAction(onAction)
self.presentViewController(myAlert, animated: true, completion: nil)
})
}
catch let error as NSError
{
print(error)
}
}
task.resume()
Help is very appreciated.
Related
I am retrieving details from my api with POST method, I have included the parameters here. I am able to print the response in console., but to the view it's quite complicating. Here added the code which i've tried. I appreciate if someone help me to get this done.
My network code goes here:
class HostApi: ObservableObject {
#Published var todos = [HostsHome]()
#Published var amenity = [AmenitiesHome]()
func loadData() {
let Url = String(format: Host_home)
guard let serviceUrl = URL(string: Url) else {
return
}
let parameters: [String : Any] = [
"request" : ["email" : "xxxxxxxxxxx.com",
"starting" : 0,
"ending" : 10]
]
var request = URLRequest(url: serviceUrl)
request.httpMethod = "POST"
request.setValue("Application/json", forHTTPHeaderField: "Content-Type")
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) else {
return
}
request.httpBody = httpBody
request.timeoutInterval = 20
let session = URLSession.shared
session.dataTask(with: request) { data, response, error in
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: .json5Allowed)
print(json)
} catch {
print(error)
}
}
}.resume()
}
}
ContentView code goes here :
struct Hosts_Home: View {
#StateObject var viewModel = HostApi()
var body: some View {
ForEach(viewModel.todos, id: \.title) { todo in
Text(todo.title!)
}
.onAppear {
viewModel.loadData()
}
}
}
[![api[![parameters][1]][1]][2]
[1]: https://i.stack.imgur.com/R5sBV.png
[2]: https://i.stack.imgur.com/yMj0t.png
Found a solution, I changed my network class like this below and it worked.
class HostApi: ObservableObject {
#Published var todos = [HostsHome]()
#Published var amenity = [AmenitiesHome]()
func loadData() {
let url = URL(string: Host_home)
guard let requestUrl = url else { fatalError() }
var request = URLRequest(url: requestUrl)
request.httpMethod = "POST"
let postString = "email=xxxxxxx#gmail.com&starting=0&ending=10";
request.httpBody = postString.data(using: String.Encoding.utf8);
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
do {
if let todoData = data {
let decodedData = try JSONDecoder().decode([HostsHome].self, from: todoData)
DispatchQueue.main.async {
self.todos = decodedData
self.amenity = decodedData[0].amenities
print(decodedData[0].propertyTypeGroup)
}
} else {
print("No data")
}
} catch {
print(error)
}
}
task.resume()
}
}
This is Doc File Generate in Postman by write method and url "link/services.php".
This is Header File.
#Headers({"Content-Type: application/json"})
#POST("services.php")
Observable<Division> divisionListApi(#Body HashMap<String, String> map);
map.put("method", "My_List");
After Postman Generation I Got This Given Below.
{"err_code":9,
"message":"My List ",
"list":[
{"ForestDivision":"Yam(T)"},
{"ForestDivision":"Rewar(T)"},
{"ForestDivision":"Ro(T)"},
{"ForestDivision":"Bh(T)"},
{"ForestDivision":"Ka(T) "},
{"ForestDivision":"Ambal(T) "},
{"ForestDivision":"Fari(T)"}]
}
I have made request by taking post mehod, is this the right way to create code in
swiftui.
import Foundation
import Combine
struct File: Decodable, Hashable {
var error_code : Int
var message : String
var list : [lisst]
}
struct lisst: Decodable, Hashable {
var ForestDivision: String
}
class fetchResults : ObservableObject{
#Published var fetchedRes : [lisst]?
func getData(completion: #escaping (File) -> ()){
print("Fetch")
let parameters = "{ I dont Know }"
let postData = parameters.data(using: .utf8)
var request = URLRequest(url: URL(string:
"URl")!,timeoutInterval: Double.infinity)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = postData
let task = URLSession.shared.dataTask(with: request) { (data, _, _) in
let resultList = try! JSONDecoder().decode(File.self, from: data!)
print(" ")
print("ID: \(resultList.error_code)")
print("VOLUME: \(resultList.message)")
print("READINGS: \(String(describing: resultList.list))")
print(" ")
print("SUCCESS: Got data - \(data! )")
DispatchQueue.main.async {
completion(resultList) // << here !!
}
}
task.resume()
}
}
Also How to Write in Swiftui View.
To Make Properly Works in List View.
import SwiftUI
import UIKit
struct DivisionList: View {
#ObservedObject var res = fetchResults()
var body: some View {
NavigationView {
Text("Nothing Here")
List(res.fetchedRes ?? [], id: \.self) { resp in // Error Here
ForEach(res.list, id: \.self) { course in
VStack {
Text(res.for) // Error Here
}
}
}
.navigationBarTitle("Data")
.onAppear(perform: {
self.getData // Error Here
})
}
}
}
struct DivisionList_Previews: PreviewProvider {
static var previews: some View {
DivisionList()
}
}
Create New Swift File Copy this Post Requests.
import Foundation
import Combine
let postUrl = "Your URl"
struct divisionList: Decodable, Identifiable {
let id: Int
let mesg: String
let list: [FDivision]
private enum CodingKeys: String, CodingKey {
case id = "err_code"
case mesg = "message"
case list = "list"
}
}
struct FDivision: Decodable, Hashable {
let forestDivision: String
private enum CodingKeys: String, CodingKey {
case forestDivision = "ForestDivision"
}
init(data:String) {
forestDivision = data
}
}
class viewModal: ObservableObject {
#Published var items = [FDivision]()
func postData() {
guard let serviceUrl = URL(string: postUrl) else { return }
let parameters: [String: Any] = [
"method": "Your Method Name"
var request = URLRequest(url: serviceUrl)
request.httpMethod = "POST"
request.setValue("Application/json", forHTTPHeaderField: "Content-Type")
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: []) else {
return
}
request.httpBody = httpBody
request.timeoutInterval = 20
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print(response)
}
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
if let dictionary = json as? [String:Any] {
if let arrList = dictionary["list"] as? [[String:Any]]{
for data in arrList{
let model = FDivision(data: data["ForestDivision"] as! String)
self.items.append(model)
}
}
}
print(json)
} catch {
print(error)
}
}
}.resume()
}
}
Create Now New Swiftui File.
import SwiftUI
import UIKit
struct DivisionList: View {
#ObservedObject var vm = viewModal()
var body: some View {
NavigationView {
VStack {
List(vm.items, id: \.self) { item in
Button(action: {}, label: {
Text(item.forestDivision).foregroundColor(.customGreen)
})
}
}.navigationBarTitle("Data")
.onAppear(perform: {
vm.postData()
})
}
}
}
struct DivisionList_Previews: PreviewProvider {
static var previews: some View {
DivisionList()
}
}
In my application I am trying to upload photos with web service but it send empty to service. There seems to be no errors in the code, but I do not know why it is.However, when I try a different method without photography, the data is full. I really do not understand what is the problem. How can solve this problem?
func apiIsGuvenligi ()
{
let imgData = UIImageJPEGRepresentation(imageView.image!, 0.2)!
var request = URLRequest(url: URL(string: "http://glcwebapi.azurewebsites.net/api/JobSecurity/JobSecurity")!)
request.httpMethod = "POST"
let boundary = generateBoundaryString()
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.addValue("Bearer \(self.token2)", forHTTPHeaderField: "Authorization")
payload = ["MessageBody": textView.text!,
"IsCallEmergencyTeam": acilDurum,
"IsFireExtinguishUsed": yangin,
"SendMyself": kendimeGonder,
"LocationParameter": "\(latitude)-\(longitude)"
] as [String : AnyObject]
if(imgData == nil) { return }
request.httpBody = createBodyWithParameters(parameters: payload as? [String : String], filePathKey: "file", imageDataKey: imgData as NSData, boundary: boundary) as Data
apiKontrol = true
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
self.hataMesaji = "Hata=\(String(describing: error))"
return
}
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String:Any]
let error = json["Data"] as? String
if error == nil
{
}
else
{
self.mesajVer2(mesaj: error!)
self.hataMesaji = "\(String(describing: error))"
}
}
catch let error as NSError {
print(error)
}
// Apiden gelen tüm keys-values, veriler parse edilip kullanılır.
let responseString = String(data: data, encoding: .utf8)
print("responseString iş güvenliği = \(String(describing: responseString))")
}
task.resume()
}
func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, imageDataKey: NSData, boundary: String) -> NSData {
let body = NSMutableData()
if payload != nil {
for (key, value) in payload {
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")
print("key \(key) \(value)")
}
}
let filename = "image.jpg"
let mimetype = "image/jpg"
body.appendString(string: "--\(boundary)\r\n")
body.appendString(string: "Content-Disposition: form-data; name=\"PhotoRequest\"; filename=\"\(filename)\"\r\n")
body.appendString(string: "Content-Type: \(mimetype)\r\n\r\n")
body.append(imageDataKey as Data)
body.appendString(string: "\r\n")
body.appendString(string: "--\(boundary)--\r\n")
return body
}
func generateBoundaryString() -> String {
return "Boundary-\(NSUUID().uuidString)"
}
// extension for image uploading
extension NSMutableData {
func appendString(string: String) {
let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true)
append(data!)
}
}
I'm trying to send an image from my application to telegram bot like here
https://newfivefour.com/swift-form-data-multipart-upload-URLRequest.html
Here is the code
let BotToken = "12345"
let ChatID = "123"
func SendToTelegram()
{
var request = URLRequest(url: URL(string: "https://api.telegram.org/bot"+BotToken+"/sendPhoto")!)
request.httpMethod = "POST"
let boundary = "Boundary-\(UUID().uuidString)"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let params = [:] as [String: String]
UIGraphicsBeginImageContextWithOptions(ScreenImage.bounds.size, true, 0.0)
ScreenImage.image?.draw(in: CGRect(x: 0, y: 0, width: ScreenImage.frame.size.width, height: ScreenImage.frame.size.height))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
request.httpBody = createBody(parameters: params,
boundary: boundary,
data: UIImageJPEGRepresentation(image!, 0.7)!,
mimeType: "image/jpg",
filename: "hello.jpg")
print(request.httpBody!)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
return
}
do {
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? AnyObject
if let parseJSON = json {
print("resp :\(parseJSON)")
}
} catch let error as NSError {
print("error : \(error)")
}
}
task.resume()
}
and get an error
Bad Request: there is no photo in the request";
"error_code" = 400;
ok = 0;
Where do i make a mistake? I'm new in SWIFT and sorry for my English
I know this question is old but the link provided pushed me in the right direction. This is my solution for server side Swift not iOS but you should be able to use it with minimal changes. Remember if you're using iOS, perform none of these operations on the main thread.
class NetworkManager {
func sendTelegramPhoto(_ photo: Data) {
let url = "https://api.telegram.org/bot\(Constants.Telegram.token)/sendPhoto"
let params: [String: Any] = [
"chat_id": Constants.Telegram.uid,
"photo": photo
]
let _ = sendMultiTypePostRequest(url, parameters: params)
}
private func sendMultiTypePostRequest(_ url: String, parameters: [String:String]) -> NetworkResponse {
var networkResponse = NetworkResponse()
let semaphore = DispatchSemaphore(value: 0)
guard let url = URL(string: url) else {
return networkResponse
}
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = "POST"
let boundary = "Boundary-\(UUID().uuidString)"
urlRequest.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let httpBody = createBody(parameters: parameters,
boundary: boundary,
mimeType: "image/jpeg",
filename: "snapshot.jpg")
let config = URLSessionConfiguration.default
config.requestCachePolicy = .reloadIgnoringLocalCacheData
let session = URLSession(configuration: config)
let task = session.uploadTask(with: urlRequest, from: httpBody) { (data, response, error) in
networkResponse.data = data
networkResponse.response = response
networkResponse.error = error
semaphore.signal()
}
task.resume()
_ = semaphore.wait(timeout: .distantFuture)
return networkResponse
}
private func createBody(parameters: [String: String],
boundary: String,
mimeType: String,
filename: String) -> Data {
var body = Data()
let boundaryPrefix = "--\(boundary)\r\n"
for (key, value) in parameters {
if let data = value as? Data {
body.appendString(boundaryPrefix)
body.appendString("Content-Disposition: form-data; name=\"\(key)\"; filename=\"\(filename)\"\r\n")
body.appendString("Content-Type: \(mimeType)\r\n\r\n")
body.append(data)
body.appendString("\r\n")
} else if let string = value as? String {
body.appendString(boundaryPrefix)
body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString("\(string)\r\n")
}
}
body.appendString("--".appending(boundary.appending("--")))
return body
}
}
private extension Data {
mutating func appendString(_ string: String) {
let data = string.data(using: String.Encoding.utf8, allowLossyConversion: false)
append(data!)
}
}
For a recent project I tried to pull some data from a server in the SOAP and oData format respectively, that is protected with a Microsoft NTLM authentication, and it has been a nightmare figuring out how to do it, none of the online examples really worked.
So here is my solution; I had to adapt, expand and combine a few different sources. I hope this helps someone in the future.
You might have to allow arbitrary loads!!
Adapted from:
https://gist.github.com/stevenschobert/f374c999e5cba6ccf09653b846967c83
https://blogs.msdn.microsoft.com/chiranth/2013/09/20/ntlm-want-to-know-how-it-works/
import UIKit
class ViewController: UIViewController {
var username: String? = nil
var password: String? = nil
lazy var conn: URLSession = {
let config = URLSessionConfiguration.ephemeral
let session = URLSession(configuration: config, delegate: self, delegateQueue: nil)
return session
}()
override func viewDidLoad() {
super.viewDidLoad()
username = "<username>"
password = "<password>"
ntlm()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func ntlm() {
let urlString = "<url>"
let url = URL(string: urlString)
let request = NSMutableURLRequest(url: url!, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 60000)
request.httpMethod = "GET"
let task = conn.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
print(response)
print(error)
print(String(data: data!, encoding: .utf8))
})
task.resume()
}
func doesHaveCredentials() -> Bool {
guard let _ = self.username else { return false }
guard let _ = self.password else { return false }
return true
}
}
extension ViewController: URLSessionDelegate {
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: #escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
print("got challenge")
guard challenge.previousFailureCount == 0 else {
print("too many failures")
challenge.sender?.cancel(challenge)
completionHandler(.cancelAuthenticationChallenge, nil)
return
}
guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodNTLM else {
print("unknown authentication method \(challenge.protectionSpace.authenticationMethod)")
challenge.sender?.cancel(challenge)
completionHandler(.cancelAuthenticationChallenge, nil)
return
}
guard self.doesHaveCredentials() else {
challenge.sender?.cancel(challenge)
completionHandler(.cancelAuthenticationChallenge, nil)
DispatchQueue.main.async {
print("Userdata not set")
};
return
}
let credentials = URLCredential(user: self.username!, password: self.password!, persistence: .forSession)
challenge.sender?.use(credentials, for: challenge)
completionHandler(.useCredential, credentials)
}
}