I have an app that I wrote using the Apache Cordova Libraries that saves a small amount of data in a local SQLite database.
I'm currently rewriting the app using SwiftUI and Core Data.
Is there any way of getting the data from the existing SQLite database so I can process it and re-save in Core Data?
I've googled and it seems that SwiftUI doesn't play well with SQLite. It looks as though it may be possible but the options I've seen don't seem very satisfactory and are overly complicated.
Are there any suggestions for a good method of recovering the data?
I don't want the users to lose their information.
Thanks
Post
Replies
Boosts
Views
Activity
Hi,
I have the following page (this is a simplified version) where there is a FetchRequest to get a record from CoreData based on an id.
This id is obtained from some json that is stored in UserDefaults (returned by the getLodgeData method).
import SwiftUI
struct TestView: View {
var lodge: Lodge = getLodgeData()
@State var lodgeid: Int = -1
var body: some View {
TestViewPage(lodgeid: lodgeid)
.onAppear(perform: {
self.lodgeid = Int(lodge.LodgeID) ?? 0
})
}
}
struct TestViewPage: View {
var lodgeid: Int
@Environment(\.managedObjectContext) var managedObjectContext
var lodge: Lodge = getLodgeData()
@State var favourite = false
//this gets the list
@FetchRequest var cdlodges: FetchedResults<CDLodge>
init(lodgeid: Int) {
self.lodgeid = lodgeid
self._cdlodges = FetchRequest(
entity: CDLodge.entity(),
sortDescriptors: [
NSSortDescriptor(keyPath: \CDLodge.lodge, ascending: true),
],
predicate: NSPredicate(format: "lodgeid == \(lodgeid)")
)
if cdlodges.isEmpty == false {
//not empty so set fav to true
favourite = true
}
else {
//not a favourite so set to false
favourite = false
}
}
var body: some View {
NavigationView {
ScrollView {
VStack(alignment: .leading) {
VStack {
switch favourite {
case false:
Button(action: {
///save the lodge in core data
//...
favourite = setFav()
})
{
Image("favicon_off")
}
case true:
Button(action: {
///delete the lodge from Core Data
//...
})
{
Image("favicon_on")
}
}
}
Button(action: {
if cdlodges.isEmpty == false {
//not empty so set fav to true
favourite = true
}
else {
//not a favourite so set to false
favourite = false
}
}) {
Text("testing")
}
}
.padding()
}///end of scrollview
.navigationBarTitle("")
.navigationBarHidden(true)
} //end of navigationview
}
}
I want to set a variable (favourite) based on if the dataset that the FetchRequest returns is empty or not.
I tried putting the check after the request, but it always comes back as empty.
This is odd as I know that a row is being returned.
I added a button (marked test) that runs the same check, and that works fine so I can only sumise that the initial check is being done before the resultset is finished being populated.
Is there a way that I can do the check when the query updates?
At this point I feel that I'm missing something simple, but I just can't seem to see it.
Any help would be greatly appreciated.
thanks
I'm doing a FetchRequest before the body of my page but can't add in the predicate as the id that I'm after isn't available until after self is available.
I've tried moving the query to a method triggered by a button press, but I get a segmentation fault.
Is there any way that I can add the predicate after the initial query to get my collection?
Alternatively, is there a way of passing in the id to the page direct? (Its a detail page, but its not triggered by selecting a list item)
If I hard code the id, everything works as expected, I just can't seem to get the id in the original query.
thanks
Hi,
I'm getting data from an api and reading it to a model that contains (among other things) an id and a name.
I can get the picker to populate using a ForEach loop so that when I click, I get the list showing the name, I just can't seem to return the id and then show the name in the picker as the selected item.
I feel like I'm missing something simple, but just can't seem to spot it.
Picker("Pick an item", selection: $ID) {
ForEach(mydata, id: \.ID) { mymodel in
Text(mymodel.Name)
}
}.onAppear(perform: loadData)
Text("Selected: \(ID)")
Any help would be gratefully received.
Thanks
Hi,
I have a SwiftUI project where I've been getting json from an api and been using it to populate lists etc.
The data was in the form:
[{"PersonID":12345,"Name":"Joe Brown","MemID":2631,"NoOfThings":1}]
and I was able to read it in using the following code:
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
if let response = try? JSONDecoder().decode([Member].self, from: data) {
DispatchQueue.main.async {
members = response
}
return
}
}
}.resume()
However, I've now been given a new api to use and it gives the json in a slightly different (but still valid) format.
{"Table":[{"PersonID":12345,"Name":"Joe Brown","MemID":2631,"NoOfThings":1}]}
This is as there are some calls that will return more than a single table.
It all works fine from android in java, but I can't seen to get it to work properly in Swift 5.
I have a struct that I'm reading the data into
let members = [Member]()
struct Member: Hashable, Codable {
var PersonID: String
var Name: String
var MemID: String?
var NoOfThings: String?
}
And have members as a collection of Member.
I'm thinking there must be a simple way of achieving reading the data from the api in the new form.
Can anyone help with an example please?
Thanks
Hi, I'm new to swiftUI and am having a few issues getting my head around how it works.
My immediate issue is that I'm getting a response from an api in the form of a JSON string that I'm splitting into 2 arrays of my data model.
This works fine and I have 2 lists in my view that if I change the binding in my list, the data changes to the other list.
I can't seem to get it to change on a button click though. I want 2 buttons (one for each list) and clicking them will change the binding.
I've got to the stage where I feel I'm soooooo close, but am missing something obvious.
This is the code in my view:
struct SplitView: View {
@EnvironmentObject var viewRouter: ViewRouter
@State var list1 = [MyModel]()
@State var list2 = [MyModel]()
private var viewingModels: [MyModel] {
list1
}
var body: some View {
HStack {
Button(action: {
//selected = 1
}){
Text("List 1")
}
Button(action: {
//selected = 2
}){
Text("List 2")
}
}
List(viewingModels, id: \.ID) { myitem in
HStack(alignment: .center) {
VStack(alignment: .leading) {
Text(myitem.Name)
.font(.subheadline)
.fontWeight(.bold)
Spacer()
}
}
} //end list
.onAppear(perform: loadList)
Spacer()
}
}
So, I have my @State variables list1 and list2 and if I change which one appears in viewingModels, the list changes.
How can I do this on the button presses?
Thanks