Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "user", intValue: nil)], debugDescription: "No value associated with key CodingKeys(stringValue: "updatedAt", intValue: nil) ("updatedAt").", underlyingError: nil))
ContentView:
import SwiftUI
struct ContentView: View {
@State private var email = ""
@State private var password = ""
@State private var wrongEmail = 0
@State private var wrongPassword = 0
@State private var showingLoginScreen = false
@State private var userData: User? // Declare a @State property for UserData
var body: some View {
NavigationView {
ZStack {
Color.blue
.ignoresSafeArea()
Circle()
.scale(1.7)
.foregroundColor(.white.opacity(0.15))
Circle()
.scale(1.35)
.foregroundColor(.white)
VStack {
Text("Login")
.font(.largeTitle)
.bold().padding()
TextField("Email", text: $email)
.padding()
.frame(width: 300, height: 50)
.background(Color.black.opacity(0.05))
.cornerRadius(10)
.border(.red, width: CGFloat(wrongEmail))
SecureField("Password", text: $password)
.padding()
.frame(width: 300, height: 50)
.background(Color.black.opacity(0.05))
.cornerRadius(10)
.border(.red, width: CGFloat(wrongPassword))
Button("Login") {
authenticateUser(email: email, password: password)
}
.foregroundColor(.white)
.frame(width: 300, height: 50)
.background(Color.blue)
.cornerRadius(10)
NavigationLink(
destination: ArtworkView(user: userData),
isActive: $showingLoginScreen
) {
EmptyView()
}
// NavigationLink(destination: Text("You are logged in @\(email)"), isActive: $showingLoginScreen) {
// EmptyView()
// }
}
}.navigationBarHidden(true)
}
}
func authenticateUser(email: String, password: String) {
guard let url = URL(string: "https://api.hangn.art/api/login") else {
return
}
print("making api call")
var request = URLRequest(url: url)
// method, body, headers
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let body: [String: AnyHashable] = [
"email": email,
"password": password
]
request.httpBody = try? JSONSerialization.data(withJSONObject: body, options: .fragmentsAllowed)
//Make the request
let task = URLSession.shared.dataTask(with: request) { data, _, error in
guard let data = data, error == nil else {
return
}
print(String(data: data, encoding: .utf8))
let decoder = JSONDecoder()
//decoder.keyDecodingStrategy = .convertFromSnakeCase // Configure snake case decoding
do {
// let response = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
let response = try decoder.decode(LoginResponse.self, from: data)
self.userData = response.user
let userData = try decoder.decode(User.self, from: data)
print("SUCCESS: \(userData)")
wrongEmail = 0
wrongPassword = 0
showingLoginScreen = true
}
catch {
print("Error parsing response data: \(error)")
print("Response data: \(String(data: data, encoding: .utf8) ?? "")")
}
}
task.resume()
}
}
//struct Response: Codable {
// let email: String
// let password: String
//}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}```
ArtworkView:
import SwiftUI
struct ArtworkView: View {
var user: User?
var body: some View {
if let user = user {
VStack {
Text("Name: \(user.firstName) \(user.lastName)")
Text("Email: \(user.email)")
Text("Description: \(user.description)")
// ... display other properties ...
}
} else {
Text("Loading...")
}
}
}
User:
import Foundation
struct LoginResponse: Decodable {
let token: String
let user: User
}
struct User: Decodable {
let clientId: Int
let createdAt: String
let description: String
let email: String
let emailVerifiedAt: String?
let firstName: String
let id: Int
let image: String
let lastName: String
let location: String? // Make it optional
let pmLastFour: String? // Make it optional
let pmType: String? // Make it optional
let stripeId: String
let trialEndsAt: String? // Make it optional
let updatedAt: String
// Define custom keys for snake case properties
private enum CodingKeys: String, CodingKey {
case clientId = "client_id"
case createdAt = "created_at"
case description = "description"
case email = "email"
case emailVerifiedAt = "email_verified_at"
case firstName = "first_name"
case id = "id"
case image = "image"
case lastName = "last_name"
case location = "location"
case pmLastFour = "pm_last_four"
case pmType = "pm_type"
case stripeId = "stripe_id"
case trialEndsAt = "trial_ends_at"
case updatedAt = "updatedAt"
// ... other properties ...
}
}
please help
Post
Replies
Boosts
Views
Activity
hi, so I have 3 files in my xcode:
ContentView
import SwiftUI
struct ContentView: View {
@State private var email = ""
@State private var password = ""
@State private var wrongEmail = 0
@State private var wrongPassword = 0
@State private var showingLoginScreen = false
@State private var userData: User? // Declare a @State property for UserData
var body: some View {
NavigationView {
ZStack {
Color.blue
.ignoresSafeArea()
Circle()
.scale(1.7)
.foregroundColor(.white.opacity(0.15))
Circle()
.scale(1.35)
.foregroundColor(.white)
VStack {
Text("Login")
.font(.largeTitle)
.bold().padding()
TextField("Email", text: $email)
.padding()
.frame(width: 300, height: 50)
.background(Color.black.opacity(0.05))
.cornerRadius(10)
.border(.red, width: CGFloat(wrongEmail))
SecureField("Password", text: $password)
.padding()
.frame(width: 300, height: 50)
.background(Color.black.opacity(0.05))
.cornerRadius(10)
.border(.red, width: CGFloat(wrongPassword))
Button("Login") {
authenticateUser(email: email, password: password)
}
.foregroundColor(.white)
.frame(width: 300, height: 50)
.background(Color.blue)
.cornerRadius(10)
NavigationLink(
destination: ArtworkView(user: userData),
isActive: $showingLoginScreen
) {
EmptyView()
}
// NavigationLink(destination: Text("You are logged in @\(email)"), isActive: $showingLoginScreen) {
// EmptyView()
// }
}
}.navigationBarHidden(true)
}
}
func authenticateUser(email: String, password: String) {
guard let url = URL(string: "https://api.hangn.art/api/login") else {
return
}
print("making api call")
var request = URLRequest(url: url)
// method, body, headers
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let body: [String: AnyHashable] = [
"email": email,
"password": password
]
request.httpBody = try? JSONSerialization.data(withJSONObject: body, options: .fragmentsAllowed)
//Make the request
let task = URLSession.shared.dataTask(with: request) { data, _, error in
guard let data = data, error == nil else {
return
}
print(String(data: data, encoding: .utf8))
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase // Configure snake case decoding
do {
// let response = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
let response = try decoder.decode(LoginResponse.self, from: data)
self.userData = response.user
let userData = try decoder.decode(User.self, from: data)
print("SUCCESS: \(userData)")
wrongEmail = 0
wrongPassword = 0
showingLoginScreen = true
}
catch {
print("Error parsing response data: \(error)")
print("Response data: \(String(data: data, encoding: .utf8) ?? "")")
}
}
task.resume()
}
}
//struct Response: Codable {
// let email: String
// let password: String
//}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
ArtworkView
import SwiftUI
struct ArtworkView: View {
var user: User?
var body: some View {
if let user = user {
VStack {
Text("Name: \(user.firstName) \(user.lastName)")
Text("Email: \(user.email)")
Text("Description: \(user.description)")
// ... display other properties ...
}
} else {
Text("Loading...")
}
}
}
User
import Foundation
struct LoginResponse: Decodable {
let token: String
let user: User
}
struct User: Decodable {
let clientId: Int
let createdAt: String
let description: String
let email: String
let emailVerifiedAt: String?
let firstName: String
let id: Int
let image: String
let lastName: String
let location: String? // Make it optional
let pmLastFour: String? // Make it optional
let pmType: String? // Make it optional
let stripeId: String
let trialEndsAt: String? // Make it optional
let updatedAt: String
// Define custom keys for snake case properties
private enum CodingKeys: String, CodingKey {
case clientId = "client_id"
case createdAt = "created_at"
case emailVerifiedAt = "email_verified_at"
case firstName = "first_name"
case lastName = "last_name"
case pmLastFour = "pm_last_four"
case pmType = "pm_type"
case stripeId = "stripe_id"
case trialEndsAt = "trial_ends_at"
// ... other properties ...
}
}
why am I getting: Type 'User' does not conform to protocol 'Decodable'
So I had firebase working with my app and now it is not, I have tried installing the package from: https://github.com/firebase/firebase-ios-sdk.git
but I get
Package Resolution Failed
firebase-ios-sdk could not be resolved
I have tried the following:
let data = FirebaseManager.shared.firestore.collection("favourites").where("uid", "==", user?.uid).get()
print(data)
and I get:
Value of type 'CollectionReference' has no member 'where'
Please help?
You would've thought this is basic stuff, I have a view with CancelButtonView with the following code:
import SwiftUI
struct CancelButtonView: View {
var body: some View {
NavigationView {
NavigationLink(destination: AboutView()) {
Button {
} label: {
HStack {
Spacer()
Text("Continue anyway")
.foregroundColor(.white)
.padding(.vertical, 10)
.font(.system(size: 14, weight: .semibold))
Spacer()
}.background(Color.blue)
}
}
}
}
}
struct CancelButtonView_Previews: PreviewProvider {
static var previews: some View {
CancelButtonView()
}
}
in my other view I am calling this:
CancelButtonView()
Why can't I see my button?!
So I have the function: storeFaveArtwork and I am trying to action it in my button further down using: self.storeFaveArtwork(artwork.id)
I am getting the error at the top in my
var body: some View {
The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions
Here is my code:
//
// ContentView.swift
// Shared
//
// Created by J*** B******* on 04/05/2022.
//
import SwiftUI
import Firebase
struct ContentView: View {
private func storeFaveArtwork(artwork: Artwork) {
guard let uid = FirebaseManager.shared.auth.currentUser?.uid else {
return
}
let artData = ["id": artwork.id, "uid": uid] as [String : Any]
FirebaseManager.shared.firestore.collection("favourites")
.document(uid).setData(artData) { err in
if let err = err {
print(err)
return
}
print("Success")
}
}
@StateObject var viewAllArtwork = ViewAllArtwork()
var body: some View {
NavigationView {
List {
ForEach(viewAllArtwork.artworksData, id: \.self) { artwork in
NavigationLink(destination: ContentDetail(item: artwork)) {
HStack(alignment: .top, spacing: 3.0) {
URLImage(urlString: "https://melvynbiddulph.co.uk/images/gallery/"+artwork.file)
VStack(alignment: .leading, spacing: 3.0) {
if(artwork.id != nil){
Text("\(artwork.id)")
.font(.caption2)
.fontWeight(.bold)
.padding(2.0)
.foregroundColor(Color.gray)
.frame(width: 32.0, height: 32.0)
.shadow(radius: 20)
.overlay(RoundedRectangle(cornerRadius: 20)
.stroke(Color.gray, lineWidth: 2))
.background(Color.white, in: RoundedRectangle(cornerRadius: 20)
).position(x: -124, y: 20)
}
Text(artwork.title)
.font(.body)
.bold()
.frame(height: 36, alignment: .center)
.frame(maxWidth: .infinity)
HStack(spacing: 2) {
if (artwork.size != nil) {
Text(artwork.size)
.padding(4)
.font(.caption)
.background(Color.gray.opacity(0.2))
.cornerRadius(5)
.foregroundColor(Color.gray)
.frame(height: 25, alignment: .center)
.frame(maxWidth: .infinity)
}
if (artwork.price != 0) {
Text("£\(artwork.price)")
.fontWeight(.bold)
.padding(4)
.font(.caption)
.background(Color.green)
.cornerRadius(5)
.foregroundColor(Color.white)
.frame(width: .infinity)
}
Button {
self.storeFaveArtwork(artwork.id)
} label: {
HStack {
Spacer()
Text("Favourite")
.foregroundColor(.white)
.padding(.vertical, 10)
.font(.system(size: 14, weight: .semibold))
Spacer()
}.background(Color.blue)
}
Spacer()
.frame(width: 0.0, height: 60.0)
}
}
.frame(width: 150.0)
}
}
}
}
.navigationTitle("Artwork")
.onAppear {
viewAllArtwork.fetch()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
I'm getting: Cannot find 'viewAllArtwork' in scope
my detail view:
import SwiftUI
struct ArtworkDetailView: View {
@StateObject var viewAllArtwork = ViewAllArtwork()
var artwork: Artwork
var body: some View {
Text(artwork.title)
}
}
struct ArtworkDetailView_Previews: PreviewProvider {
static var previews: some View {
ArtworkDetailView(artwork: viewAllArtwork.artworksData[0])
}
}
and my Artwork Views:
import SwiftUI
struct ArtworkView: View {
@StateObject var singleArtwork = SingleArtwork()
var body: some View {
NavigationView {
List {
ForEach(singleArtwork.artworksData, id: \.self) { artwork in
HStack(spacing: 8) {
URLImage(urlString: "https://melvynbiddulph.co.uk/images/gallery/"+artwork.file)
Text(artwork.title)
.bold()
if (artwork.size != nil) {
Text(artwork.size)
}
}
}
}
.navigationTitle("Single Artwork")
.onAppear {
singleArtwork.fetch()
}
}
}
}
struct ArtworkView_Previews: PreviewProvider {
static var previews: some View {
ArtworkView()
}
}
and to get the data for this:
import Foundation
import SwiftUI
class ViewAllArtwork: ObservableObject {
@Published var artworksData: [Artwork] = []
func fetch() {
guard let url = URL(string: "https://melvynbiddulph.co.uk/api/artwork") else {
return
}
let task = URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
return
}
//convert to JSON
do {
let artworksData = try JSONDecoder().decode([Artwork].self, from: data)
DispatchQueue.main.async {
self.artworksData = artworksData
}
} catch {
print(error)
}
}
task.resume()
}
}
Please help
Hi, I am able to get data in an array and loop through it but how can I get single object data and display it?
artwork view
import SwiftUI
struct ArtworkView: View {
@StateObject var singleArtwork = SingleArtwork()
var body: some View {
NavigationView {
List {
ForEach(singleArtwork.artworksData, id: \.self) { artwork in
HStack(spacing: 8) {
URLImage(urlString: "https://melvynbiddulph.co.uk/images/gallery/"+artwork.file)
Text(artwork.title)
.bold()
if (artwork.size != nil) {
Text(artwork.size)
}
}
}
}
.navigationTitle("Single Artwork")
.onAppear {
singleArtwork.fetch()
}
}
}
}
struct ArtworkView_Previews: PreviewProvider {
static var previews: some View {
ArtworkView()
}
}
Single Artwork Object
import SwiftUI
class SingleArtwork: ObservableObject {
@Published var artworksData: [Artwork] = []
func fetch() {
guard let url = URL(string: "https://melvynbiddulph.co.uk/api/artwork/11") else {
return
}
let task = URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
return
}
//convert to JSON
do {
let artworksData = try JSONDecoder().decode([Artwork].self, from: data)
DispatchQueue.main.async {
self.artworksData = artworksData
}
} catch {
print(error)
}
}
task.resume()
}
}
URLImage
import SwiftUI
struct URLImage: View {
let urlString: String
@State var data: Data?
var body: some View {
if let data = data, let uiimage = UIImage(data: data) {
Image(uiImage: uiimage)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 130, height: 130)
.background(Color.gray)
} else {
Image(systemName: "loading")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 130, height: 130)
.background(Color.gray)
.onAppear {
fetchData()
}
}
}
private func fetchData() {
guard let url = URL(string: urlString) else {
return
}
let task = URLSession.shared.dataTask(with: url) { data, response, error in
self.data = data
}
task.resume()
}
}
Obviously it works for an array of objects:
https://www. melvynbiddulph .co.uk/api/artwork
but not working for single objects:
https://www. melvynbiddulph .co.uk/api/artwork/11