Hello,
I encounter two issues with my networking function.
The function is working properly when all entries are correctly entered.
Now I would like to implement my error management.
I'm having this first issue:
Invalid conversion from throwing function of type '(Data?, URLResponse?, Error?) throws -> Void' to non-throwing function type '(Data?, URLResponse?, Error?) -> Void' (line 15)
Here is the code : func connect(url: String) throws {
guard let encoded = try? JSONEncoder().encode(connexion) else {
print("Fail to encode newMed")
return
}
let url = URL(string: "/api/\(url)")!
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = encoded
URLSession.shared.dataTask(with: url) { data, res, error in
guard let httpResponse = res as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode)
else if (res == nil) {
throw ConnexionError.invalidServerRes /* here is the error */
} else {
self.handleServerError(res!)
return
}
if let data = data {
let decoder = JSONDecoder()
if let json = try? decoder.decode(Connexion.self, from: data) {
print(json)
self.connexion.id = json.id
self.connexion.token = json.token
self.connexion.sessionID = json.sessionID
self.signInSuccess = true
} else {
let dataString = String(decoding: data, as: UTF8.self)
print("Invalid response \(dataString)")
}
}
}.resume()
}
}
This is the enum would like to use for the error handling:
enum ConnexionError: Error {
case invalidPasswd
case invalidId
case invalidServerRes
}
This is my class:
class Connexion: Codable, ObservableObject {
enum CodingKeys: String, CodingKey {
case email, password, id, token, sessionID
}
@Published var token: String = ""
@Published var sessionID: String = ""
@Published var id: String = ""
@Published var email: String = ""
@Published var password: String = ""
init() { }
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
sessionID = try container.decode(String.self, forKey: .sessionID)
token = try container.decode(String.self, forKey: .token)
id = try container.decode(String.self, forKey: .id)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(email, forKey: .email)
try container.encode(password, forKey: .password)
}
}
https://developer.apple.com/forums/thread/671055
The second error, is coming out of nowhere... (if you don't know it is okay)
When using Postman, I get this: {
		"id": "5fc565209ce8b43c1315da9b",
		"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9",
		"sessionID": "O7KdKIuDMVHeVV91AWcApPYezCXEfz7n"
}
But when I print the dataString (line 30) it's another story. I get almost all the BDD ...
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hello,
I’m having a little issue with my Codable class…
I have an Int which I will Post on my API. But when I GET back, it is a String.
Let me show you some code: this is my class:
class NFCDataSec: ObservableObject, Codable {
		enum CodingKeys: String, CodingKey {
				case firstName, lastName, age
		}
		@Published var lastName: String = ""
		@Published var firstName: String = ""
		@Published var age: Int = 0
		init() {		}
		required init(from decoder: Decoder) throws {
				let container = try decoder.container(keyedBy: CodingKeys.self)
				lastName = try container.decode(String.self, forKey: .lastName)
				firstName = try container.decode(String.self, forKey: .firstName)
				age = try container.decode(Int.self, forKey: .age) /* (1) */
		}
		func encode(to encoder: Encoder) throws {
				var container = encoder.container(keyedBy: CodingKeys.self)
				try container.encode(firstName, forKey: .firstName)
				try container.encode(lastName, forKey: .lastName)
				try container.encode(age, forKey: .age)
		}
}
this is my JSON Post request:
func SecuringData() throws {
						guard let encoded = try? JSONEncoder().encode(dataToWrite) else {
								print("Fail to encode SecuringData - NFCDataSec")
								return
						}
						let url = URL(string: "https://MY_API.COM/api/sendToChip")!
						var request = URLRequest(url: url)
						request.setValue("application/json", forHTTPHeaderField: "Content-Type")
						request.httpMethod = "POST"
						request.httpBody = encoded
						URLSession.shared.dataTask(with: request) { data, res, error in
								guard let httpResponse = res as? HTTPURLResponse,
												(200...299).contains(httpResponse.statusCode) else {
												self.handleServerError(res)
										return
								}
								if let data = data {
										let decoder = JSONDecoder()
										if let json = try? decoder.decode(NFCDataSec.self, from: data) {
												print(json)
										}
										else {
												let dataString = String(decoding: data, as: UTF8.self)
												print("Invalid response \(dataString)") /* (2) */
										}
								}
						}.resume()
(1) the API GET returns String instead of Int - but it needs to have Int when I’m making the POSTmethod
(2) I get an invalid response from the API when I GET the data back from it.
Here is an exemple of working JSON POST:
{
"lastName":"John",
"firstName":"Taylor",
"age":23
}
GET:
{
		"firstName": "8ac18f61",
		"lastName": "88cf8f64dc719eac6a",
		"age": "e893"
}
Following this thread : https://developer.apple.com/forums/thread/670309
I previously created a structure in order to store what is contained in my NDEF tag.
After displaying all its data [from the tag], I need to update it and to format the received data and update it into a String.
Here is where I am having an issue.
When I fill the string inside onTapGesture method. Nothing is happening. Here is the code :
/* nfcWriteButton(data: $data) */
/* I would like to perform the onTapGesture here instead of the button. The Button is for debug purposes */
Button(action: {
print("\(self.nfcData.lastName)") /* 1 */
				print("\(String(describing:self.deciphered["lastName"])")) /* 1 */ /* displaying `Optional("Paul")` */
print(self.data) /* 2 */
}) {
Text("UPDATE - test")
}
.onTapGesture {
self.data = "lastName:\(self.deciphered["lastName"])\ngender:\(self.deciphered["gender"])\nfirstName:\(self.deciphered["firstName"])\nage:\(self.deciphered["age"])\n"
						print("self.data")
}
I noticed that (1) printed the updated value. Whereas (2) prints the data string as it got it, without the update made in the onTapGesture
Then I also noticed that the print un the onTapGesture is never executed.
Is is normal because I'm doing this onTapGesture for the button and it won't accept it because there is already the action in the first part of the Button?
Will it - the onTapGesture method - work for nfcWriteButton?
Here is part of the code of this button:
struct nfcWriteButton : UIViewRepresentable {
@Binding var data: String
func updateUIView(_ uiView: UIButton, context: Context) { }
func makeUIView(context: UIViewRepresentableContext<nfcWriteButton>) -> UIButton {
let button = UIButton()
button.setTitle("Write on Tag", for: .normal)
button.addTarget(context.coordinator, action: #selector(context.coordinator.beginScan(_:)), for: .touchUpInside)
return button
}
func makeCoordinator() -> nfcWriteButton.Coordinator {
return Coordinator(data: $data)
}
}
Hello,
I'm having a little issue with this code.
struct nfcButton : UIViewRepresentable {
@Binding var data: String
@Binding var showData: Bool
func makeUIView(context: UIViewRepresentableContext<nfcButton>) -> UIButton {
let button = UIButton()
button.setImage(UIImage(named: "phoneFinal"), for: .normal)
button.addTarget(context.coordinator, action: #selector(context.coordinator.beginScan(_:)), for: .touchUpInside)
return button
}
I just change my image with a better and bigger one.
The thing is don't know how to resize it. I tried to add .frame to the structure call like so :
nfcButton(data: $data, showData: $showNFCMobile)
		.frame(width: 150.0, height: 250.0)
I also tried with resizableImage method but I don't really understand what is the capInsets
button.setImage(UIImage(named: "phoneFinal")?.resizableImage(withCapInsets: <#T##UIEdgeInsets#>), for: .normal)
I know in my regular view I just need to make like this and it works;
Image("Image_name").resizable().frame(width: 150)
Thank for your help !
I'm using the following :
(https://developer.apple.com/forums/thread/670303)
var data = "Key0:Value\nKey1:Value\nKey2:Value\nKey3:Value\n"
var deciphered = data.split(separator: "\n").reduce(into: [String: String]()) {
let str = $1.split(separator: ":")
if let first = str.first, let value = str.last {
$0[String(first)] = String(value)
}
}
The little issue I'm facing now, is to display the dictionary. I'm using SwiftUI for my app UI.
Here is the code:
struct NFCMobileView: View {
		@Binding var data: String
		var body: some View {
				var deciphered = data.split(separator: "\n").reduce(into: [String: String]()) {
						let str = $1.split(separator: ":")
						if let first = str.first, let value = str.last {
								$0[String(first)] = String(value)
						}
				}
				HStack {
						Text("Last Name")
						TextField("", text: deciphered["lastName"]) /* error */
				}
		}
}
This is the error I'm having: Cannot convert value of type 'String?' to expected argument type 'Binding<String>'
If I unwrap this way :
TextField("", text: deciphered["lastName"] ?? "")
I get this error: Cannot convert value of type 'String' to expected argumument type 'Binding<String>'
I'm getting the binding value data from what is on the NDEF tag
Hello dear readers,
I'm having an issue with dictionaries.
I am receiving this from my NDEF tag: Key0:Value\nKey1:Value\nKey2:Value\nKey3:Value\n
The values can be ether String or Int.
I would like to create a dictionary with these keys and values.
I have written this code for now:
let deciphered = str.split(separator: "\n").reduce(into: [String: AnyObject]()) {
		let str = $1.split(separator: ":")
		if let first = str.first, let key = String(first), let value = str.last {
				$0[key] = value as AnyObject
		}
}
I also tried this:
let split = str.split(whereSeparator: \.isNewline)
Where str is my string of all values. But I'm stuck with the : between the Key and Value
But I'm having this error:
error: initializer for conditional binding must have Optional type, not 'String'
if let first = str.first, let key = String(first), let value = str.last {
																		^	 ~~~~~~~~~~~~~
Can you help me or give me an other way to store it ?
The idea after is to modify the value and send it back on a NDEF tag.
Thank you for your help
Hello,
I am beginning with swift and I'm stuck with a picker issue.
I need to fill a JSON with the selected choice. And it keeps returning me the array.
Here is the Class:
class NewPatient: ObservableObject, Codable {
enum CodingKeys: String, CodingKey {
case lastName, firstName, age, phoneNumber, emailAddr = "email", address, streetNumber, street, typeStreetNumber, typeStreet
}
@Published var firstName: String = ""
@Published var lastName: String = ""
@Published var age: Int?
static let typeStreetNbr = ["", "bis", "ter"]
@Published var typeStreetNumber: String = ""
@Published var indexStreetNbr = 0
static let typeStrt = ["rue", "boulevard", "avenue", "chemin"]
@Published var typeStreet: String = ""
@Published var indexStreet = 0
init() { }
required init(from decoder: Decoder) throws {
lastName = try container.decode(String.self, forKey: .lastName)
firstName = try container.decode(String.self, forKey: .firstName)
age = try container.decode(Int.self, forKey: .age)
let address = try container.nestedContainer(keyedBy: CodingKeys.self, forKey: .address)
typeStreetNumber = try address.decode(String.self, forKey: .typeStreetNumber)
typeStreet = try address.decode(String.self, forKey: .typeStreet)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(firstName, forKey: .firstName)
try container.encode(lastName, forKey: .lastName)
try container.encode(age, forKey: .age)
var address = container.nestedContainer(keyedBy: CodingKeys.self, forKey: .address)
try address.encode(typeStreetNumber, forKey: .typeStreetNumber)
try address.encode(typeStreet, forKey: .typeStreet)
}
}
Here is the View code:
struct SignUpClient: View {
@State private var backPressed: Bool = false
var body: some View {
if backPressed {
return AnyView(PreSignUp())
} else {
return AnyView(SignUpClientView(backPressed: $backPressed, patient: NewPatient()))
}
}
}
struct SignUpClientView: View {
@Binding var backPressed: Bool
@State private var patientAddressInfo: Bool = false
@ObservedObject var patient: NewPatient
var body: some View {
Form {
Section {
Picker("Street desc.", selection: $patient.indexStreet) {
ForEach (0 ..< NewPatient.typeStrt.count) {
Text(NewPatient.typeStrt[$0])
}
}.pickerStyle(SegmentedPickerStyle())
}
}
}
I would like to store ether assign e.g. typeStreet variable with the result of the picker selection or just return the selected one.
Thank you for your help,
P.