So I created this project to learn Swift Ui but I am stuck. I can't figure out why the HomeView isn't displaying the name of the contact. I created the ContactModel to store the contact details and the ContactViewModel to store all of the contacts in userDefaults.I stored the information in UserDefaults, but for some reason it just isn't working. I added all my files from the Xcode project. Thanks for the help!
@main
struct ContactsAppApp: App {
@StateObject var contactViewModel: ContactViewModel = ContactViewModel()
var body: some Scene {
WindowGroup {
NavigationView{
ContentView()
}
.environmentObject(contactViewModel)
}
}
}
struct ContentView: View {
var body: some View {
TabView{
HomeView()
.tabItem {
Image(systemName: "house")
.foregroundColor(.white)
Text("home")
}
AddContactView()
.tabItem{
Image(systemName: "laptopcomputer")
Text("work")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct ContactModel: Identifiable, Codable {
let id: String
let name: String
let phoneNumber: String
let email: String
init(id: String = UUID().uuidString, name: String, phoneNumber: String, email: String) {
self.id = id
self.name = name
self.phoneNumber = phoneNumber
self.email = email
}
func updateCompletion() -> ContactModel {
return ContactModel(id: id, name: name, phoneNumber: phoneNumber, email: email)
}
}
class ContactViewModel: ObservableObject {
@Published var items: [ContactModel] = [] {
didSet {
saveItems()
}
}
let itemsKey: String = "items_list"
init() {
getItems()
}
func getItems() {
guard
let data = UserDefaults.standard.data(forKey: itemsKey),
let savedItems = try? JSONDecoder().decode([ContactModel].self, from: data)
else { return }
self.items = savedItems
}
func deleteItem(indexSet: IndexSet) {
items.remove(atOffsets: indexSet)
}
func moveItem(from: IndexSet, to: Int) {
items.move(fromOffsets: from, toOffset: to)
}
func addItem(name: String, phoneNumber: String, email: String) {
let newItem = ContactModel(name: name, phoneNumber: phoneNumber, email: email)
items.append(newItem)
}
func updateItem(item: ContactModel) {
if let index = items.firstIndex(where: { $0.id == item.id }) {
items[index] = item.updateCompletion()
}
}
func saveItems() {
if let encodedData = try? JSONEncoder().encode(items) {
UserDefaults.standard.set(encodedData, forKey: itemsKey)
}
}
}
import SwiftUI
struct HomeView: View {
@EnvironmentObject var contactViewModel: ContactViewModel
var body: some View {
NavigationView {
VStack {
HStack{
Text("Contacts")
.font(.system(size: 35, weight: .bold))
.padding(.leading,30)
.padding(.top,20)
.foregroundColor(.white)
Spacer()
}
Spacer()
ScrollView{
ForEach(contactViewModel.items) { item in
contactWidget(name: item.name)
}
}
.padding(.top,20)
Button(action: {
print("touched")
}, label: {
NavigationLink(destination: AddContactView().navigationBarBackButtonHidden(true)) {
HStack{
ZStack{
RoundedRectangle(cornerRadius: 40)
.frame(width: 200, height: 50)
.foregroundColor(.blue)
Text("Add Contact")
.foregroundColor(.white)
}
}
}
.navigationBarHidden(true)
})
}
.background(.black)
}
.navigationBarHidden(true)
}
}
struct contactWidget : View{
let name: String
var body: some View{
ZStack {
RoundedRectangle(cornerRadius: 20)
.frame(width: 350, height: 100)
.foregroundColor(.gray)
HStack {
Image(systemName: "person")
.resizable()
.clipShape(Circle())
.frame(width: 40, height: 40)
Text(name)
.font(.system(size: 18, weight: .semibold))
Spacer()
HStack{
Circle()
.frame(width: 40, height: 40)
.foregroundColor(.orange)
Circle()
.frame(width: 40, height: 40)
.foregroundColor(.blue)
Circle()
.frame(width: 40, height: 40)
.foregroundColor(.pink)
}
}
.padding(.leading,40)
.padding(.trailing,30)
}
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
NavigationView{
HomeView()
}
.environmentObject(ContactViewModel())
}
}
import SwiftUI
struct AddContactView: View {
@EnvironmentObject var contactViewModel: ContactViewModel
@State var contactName: String = ""
@State var phoneNumber: String = ""
@State var email: String = ""
var body: some View {
NavigationView {
VStack {
HStack{
Text("Contacts")
.font(.system(size: 35, weight: .bold))
.padding(.leading,30)
.padding(.top,20)
.foregroundColor(.white)
Spacer()
}
TextField("Enter name", text: $contactName)
.frame(width: 330, height: 30)
.padding()
.background(.white)
.cornerRadius(10)
TextField("Enter Phone Number", text: $phoneNumber)
.frame(width: 330, height: 30)
.padding()
.background(.white)
.cornerRadius(10)
TextField("Enter Email", text: $email)
.frame(width: 330, height: 30)
.padding()
.background(.white)
.cornerRadius(10)
Text(contactName)
.foregroundColor(.white)
Spacer()
.padding(.top,20)
Button(action: {
contactViewModel.addItem(name: contactName, phoneNumber: phoneNumber, email: email)
contactName = ""
phoneNumber = ""
email = ""
}, label: {
NavigationLink(destination: HomeView().navigationBarBackButtonHidden(true)) {
HStack{
ZStack{
RoundedRectangle(cornerRadius: 40)
.frame(width: 200, height: 50)
.foregroundColor(.blue)
Text("Done")
.foregroundColor(.white)
}
}
}
.navigationBarHidden(true)
})
}
.background(.black)
}
.navigationBarHidden(true)
}
}
struct AddContactView_Previews: PreviewProvider {
static var previews: some View {
NavigationView{
AddContactView()
}
.environmentObject(ContactViewModel())
}
}