Как заставить файлы Json правильно читаться/отображаться на iPhone в Swift?IOS

Программируем под IOS
Ответить
Anonymous
 Как заставить файлы Json правильно читаться/отображаться на iPhone в Swift?

Сообщение Anonymous »

Я работаю над приложением, которое хранит данные в файлах JSON. В настоящее время FileUtils имеет все функции, которые работают с файлами. ContentView содержит основной контент приложения, а AddEggView добавляет контент в основной ContentView. Моя проблема заключается в том, что при тестировании на iPhone мой основной контент не перерисовывается повторно при отправке новой привычки в AddEggView, но, похоже, он работает на Mac.
FileUtils:

Код: Выделить всё

import Foundation

func addJsonToFile(jsonString: String) {
// Get the URL of the documents directory
guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
print("Documents directory not found")
return
}

// Append the file name "habitData.json" to the documents directory URL
let fileURL = documentsDirectory.appendingPathComponent("habitData.json")

do {
if FileManager.default.fileExists(atPath: fileURL.path) {
// File exists, append to existing content
var existingData = try Data(contentsOf: fileURL)

// Remove trailing ']' if it exists
if let lastChar = existingData.last, lastChar == UInt8(ascii: "]") {
existingData.removeLast()
}

// If there's existing data, add a comma to separate objects
if !isEmptyFile(fileURL: fileURL) {
print("has content")
existingData.append(contentsOf: ", ".data(using: .utf8)!)
} else {
print("empty")
existingData.append(contentsOf: "[ ".data(using: .utf8)!)
}

// Convert the new JSON string to data and append to existing data
if let jsonData = jsonString.data(using: .utf8) {
existingData.append(jsonData)

// Append ']' to complete the array
existingData.append(UInt8(ascii: "]"))

// Write the updated data back to the file
try existingData.write(to: fileURL, options: .atomic)
} else {
print("Failed to convert JSON string to data")
}

print("Json data appended successfully to: \(fileURL)")
} else {
// File doesn't exist, create a new file with the JSON data wrapped in an array
let wrappedJsonString = "[\(jsonString)]"
try wrappedJsonString.write(to: fileURL, atomically: true, encoding: .utf8)
print("Json data saved successfully to a new file: \(fileURL)")
}
} catch {
print("Error appending json data: \(error)")
}
}

func getJsonData() -> Data? {
guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
print("Documents directory not found")
return nil
}

let fileURL = documentsDirectory.appendingPathComponent("habitData.json")
do {
// Read data from the file
let data = try Data(contentsOf: fileURL)
return data
} catch {
print("Error reading JSON data: \(error)")
return nil
}
}

func isEmptyFile(fileURL: URL) -> Bool {
do {
let fileContents = try String(contentsOf: fileURL, encoding: .utf8)
print("File contains: " + fileContents)
return fileContents.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
} catch {
print("Error reading file: \(error)")
return true // If there's an error reading the file, we can assume it's empty or inaccessible
}
}

Просмотр содержимого:

Код: Выделить всё

import SwiftUI
import UIKit
extension UIScrollView {  open override var clipsToBounds: Bool {   get { false }   set { }  } }

struct ContentView: View {
// State Variables
@State private var fulfilled = 0
@State private var numOfEggs = 3
@State private var displayState = true
@State private var displayHabit = " "
@State private var showAddEggView = false
@State private var loadJsonData = true

// For Array of Habit Structs (loaded on initalization)
@ObservedObject var viewModel = HabitViewModel()

// ContentView
var body: some View {
NavigationView {
// Main Chicken
let chickenImageName = fulfilled == numOfEggs ? "chicken_in_egg"  : "chicken_in_egg_sad"

ZStack {
// ContentView Background
Color(#colorLiteral(red: 0.9294117647, green: 0.9294117647, blue: 0.9137254902, alpha: 1)).ignoresSafeArea()
.onTapGesture {
print("Tapped Screen")
displayHabit = " "
}

// Settings Button
VStack {
HStack {
Spacer().frame(maxWidth: 300)
Button(action: {
print("Settings tapped")
}) {
Image("settings")
.resizable()
.background(Color.clear)
.frame(width: 37, height: 37)
}
}

Image(chickenImageName)
.resizable()
.background(Color.clear)
.frame(width: 350, height: 350)

// ScrollView
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: -10) {
if numOfEggs == 0 {
// FIX THIS (when all eggs are removed)
//                                HabitEggButton(habit: .constant(Habit(habitName: "Temp"))).opacity(0)
} else {

if viewModel.isLoading {
Text("Loading data...")
}
else {
ForEach($viewModel.habits) { $habit in
if habit.isDisplayed {
HabitEggButton(habit: $habit, displayHabit: $displayHabit)
}
}
}

// Add HabitEgg Button
Button(action: {
print("Add tapped")
showAddEggView = true

}) {
Image("add-button")
.resizable()
.frame(width: 60, height: 60)
.offset(x: -28, y: 10)
.frame(width: 180, height: 100)
}
}
}
}
.offset(x: 25)
.sheet(isPresented: $showAddEggView) {
AddEggView(viewModel: viewModel)
}

// Habit Text Display
Text(displayHabit)
.font(Font.custom("Inika-Bold", size: 26))
.opacity(displayHabit == ""  ? 0 : 1)
.offset(y: 50)
}
.offset(y: -65)
}
}.navigationBarHidden(true)
}
}

#Preview {
ContentView()
}
AddEggView:

Код: Выделить всё

import Foundation
import SwiftUI

struct AddEggView: View {
@Environment(\.presentationMode) var presentationMode
@State private var inputHabit: String = ""
@ObservedObject var viewModel: HabitViewModel

init(viewModel: HabitViewModel) {
self.viewModel = viewModel
}

var body: some View {
ZStack {
Color(#colorLiteral(red: 0.9294117647, green: 0.9294117647, blue: 0.9137254902, alpha: 1)).ignoresSafeArea()

VStack {

Text("Add a Habit!").font(Font.custom("Inika-Bold", size: 35))

Image("egg_uncracked")
.resizable()
.frame(width: 220, height: 220)

TextField("Please enter a habit", text: $inputHabit)
.font(Font.custom("Inika", size: 14))
.padding(EdgeInsets(top: 8, leading: 12, bottom: 8, trailing: 12))
.background(Color.white)
.cornerRadius(10)
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(Color.gray, lineWidth: 1)
)
.frame(width: 200, height: 100)

Button(action: {
print("Egg Submitted")

if inputHabit != "" {
do {
let habit = Habit(habitName: inputHabit)
let jsonData = try JSONEncoder().encode(habit)
let jsonString = String(data: jsonData, encoding: .utf8)!

print(jsonString)

addJsonToFile(jsonString: jsonString)
viewModel.loadJsonData()

self.presentationMode.wrappedValue.dismiss()
} catch {
print("Error encoding habit: \(error)")
}

self.presentationMode.wrappedValue.dismiss()
}
}, label: {
Text("Start Hatching!").font(Font.custom("Inika-Bold", size: 18))
.foregroundColor(.black)
})
.padding(.horizontal, 20)
.padding(.vertical, 10)
.background(Color(red: 1.0, green: 0.682, blue: 0.682))
.cornerRadius(20)
.overlay(RoundedRectangle(cornerRadius: 20)
.stroke(Color.black, lineWidth: 1))
}
}
}
}

#Preview {
AddEggView(viewModel: HabitViewModel())
}
Я считаю, что с рендерингом что-то не так, поскольку терминал сообщил мне, что:
Данные Json успешно добавлены в: file:///var /mobile/Containers/Data/Application/D5AEAD8C-23FB-45B1-A65C-C0DF3A520047/Documents/habitData.json
Я впервые работаю с постоянными данными, и я не слишком уверен, как исправить эту ошибку. Любая помощь будет полезна, спасибо!

Подробнее здесь: https://stackoverflow.com/questions/787 ... e-in-swift
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»