1

I am currently building an app to display tweets from a twitter list. For some reason I am only appending tweets with media links, and skipping over tweets with just full text and no media. The JSON data prints all tweets that I request. Does anyone know how to adjust my case let statement so I can include tweets without media?

**Here is how I set up my struct: **

struct TweetData: Codable, Identifiable {

    var id: String { id_str }

var id_str: String

    var full_text: String?
    var screen_name: String?
    var name: String?
    var profile_image_url_https: String?
    var media_url_https: String?

}

**Here is how I coded my function for the twitter list: **

func listTweets(listTag: ListTag) {

            swifter.listTweets(for: ListTag.id("1580201555286192128"), count: 20, includeEntities: true, includeRTs: true, tweetMode: .extended) { JSON in
    
                do {
                    switch JSON {
                    case .array(let array):
                        var tweets: [TweetData] = []
    
                        for json in array {
    
                            if case let .string(id) = json["id_str"],
                               case let .string(full_text) = json["full_text"],
                               case let .string(screen_name) = json["user"]["screen_name"],
                               case let .string(name) = json["user"]["name"],
                               case let .string(profile_image_url_https) = json["user"]["profile_image_url_https"],
                               case let .string(media_url_https) =  json["entities"]["media"][0]["media_url_https"] {
    
                                tweets.append(TweetData(id_str: id, full_text: full_text, screen_name: screen_name, name: name, profile_image_url_https: profile_image_url_https, media_url_https: media_url_https))
                                }
    
                        }
                        DispatchQueue.main.async { self.fantasyNews = tweets }
                    default:
                        print("Can't handle object: \(JSON)")
                    }
                } catch {
                    print("Got an error while parsing tweets: \(error)")
                }
    }

**On my content view, here is how I am calling the tweet: **

      Text(tweet.full_text!)
                   
                    AsyncImage(url: URL(string: tweet.media_url_https!)!,
                                  placeholder: { Text("Loading ...") },
                                  image: { Image(uiImage: $0).resizable() })
                    .aspectRatio(contentMode: .fit)


  .onAppear() {
            networkManager.listTweets(listTag: .id("1580201555286192128"))
        }
eazey12
  • 11
  • 1

1 Answers1

0

After reading the ReadMe file on Swifter, I discovered that my syntax was incorrect on my case let statement. The .string must follow the definition of the constant. Additionally a nil coalescing operator was necessary in the first statement.

    for json in array {

               if case let id = json["id_str"].string ?? "",
                  case let full_text = json["full_text"].string,
                  case let screen_name = json["user"]["screen_name"].string,
                  case let name = json["user"]["name"].string,
                  case let profile_image_url_https = json["user"]["profile_image_url_https"].string,
                  case let media_url_https =  json["entities"]["media"][0]["media_url_https"].string {
  
tweets.append(TweetData(id_str: id, full_text: full_text, screen_name: screen_name, name: name, profile_image_url_https: profile_image_url_https, expanded_url: expanded_url, media_url_https: media_url_https))
                                }

Now on my content view when I used AsyncImage, I have to call an optional saying that if there is no media URL link then a single white pixel will be posted. I am not sure how to get around that part, but it worked and this is what it looks like.

    AsyncImage(url: (URL(string: tweet.media_url_https ?? "https://commons.wikimedia.org/wiki/File:1x1_placeholder.png#/media/File:1x1_placeholder.png"))!,
                                  placeholder: { Text("") },
                                  image: { Image(uiImage: $0).resizable() })
                    .aspectRatio(contentMode: .fit)
eazey12
  • 11
  • 1