so I have two functions the first gets an array of structs and the second func gets another struct object and appends it to the first array. In my view I have a scroll view that displays all these elements in the array. When I run the code with the getAd function commented out (does not execute at all) the view displays the correct array of elements in the scroll view. but when I uncomment the getAd function the view does not display any elements at all. But I added a button to print the viewModel.new array, and when I click it, the correct array is printed out WITH the final element appended. Since the app works fine when the second function is commented out, it leads me to believe that the second func is causing the problem, but when I print the array with the button, the result looks just fine how I want it to look. Im not sure what the problem is, maybe the asynchronous nature of the functions.
view
import SwiftUI
struct FeedView: View {
@StateObject var viewModel = FeedViewModel()
var body: some View {
mainInterFaceView
}
}
extension FeedView{
var mainInterFaceView: some View{
VStack(){
ZStack(){
ScrollView {
LazyVStack {
ForEach(viewModel.new) { tweet in
TweetRowView(tweet: tweet, hasDivider: true)
}
}
}
}
}
}
}
}
viewModel:
class FeedViewModel: ObservableObject{
@Published var new = [Tweet]()
var ads = [Tweet]()
let service = TweetService()
let userService = UserService()
init(){
fetchNew()
}
func fetchNew(){
service.fetchNew { tweets in
self.new = tweets
for i in 0 ..< tweets.count {
let uid = tweets[i].uid
self.userService.fetchUser(withUid: uid) { user in
self.new[i].user = user
}
}
self.getAd() //here
}
}
func getAd() {
service.fetchAd { ads in
self.ads = ads
for i in 0 ..< ads.count {
let uid = ads[i].uid
self.userService.fetchUser(withUid: uid) { user in
self.ads[i].user = user
}
}
self.new.append(self.ads[0])
}
}
Hello so I have two functions, the first gets tweets and the second gets ads and inserts them into the first array, for some reason calling the getAd function makes all the tweets.user var equal to nil. So when I run the app I briefly see all the tweets, then they disappear because the getAd function is called and their user values become nil. And after this only the ad is displayed. How can I fix this so that the user values do not become nill, I think this is an asynchronous issue and that's why I tried to do it inside the closer when i == count -1, but this did not work.
class FeedViewModel: ObservableObject{
@Published var new = [Tweet]()
var ads = [Tweet]()
let service = TweetService()
let userService = UserService()
init(){
fetchNew()
}
func fetchNew() {
service.fetchNew { tweets in
self.new = tweets
self.lastNew = tweets.last?.timestamp ?? Timestamp(seconds: 2, nanoseconds: 2)
for i in 0 ..< tweets.count {
let uid = tweets[i].uid
self.userService.fetchUser(withUid: uid) { user in
self.new[i].user = user
if i == (tweets.count - 1){
self.new.sort { $0.promoted < $1.promoted }
self.getAd(myArray: tweets, direction: 1)
}
}
}
}
}
func getAd(myArray: [Tweet], direction: Int) {
var localArray = myArray
service.fetchAd { ads in
self.ads = ads
self.lastAd = ads.last?.timestamp ?? Timestamp(seconds: 2, nanoseconds: 2)
self.ads.sort { $0.plus ?? true && !($1.plus ?? false) }
for i in 0 ..< ads.count {
let uid = ads[i].uid
self.userService.fetchUser(withUid: uid) { user in
self.ads[i].user = user
if i == (ads.count - 1){
let a = self.ads[0]
localArray.append(a)
self.new = localArray
}
}
}
}
}