wyte wyte - 5 months ago 21
Swift Question

Creating a var with the name of a parameter

I'm just coding a json parser for my app. It fetches information for a specific object which is named after its uid. The app plays online streamed music back. So:

I have a Struct:

struct Song : Decodable {
var uid: String
var album: Album
var artist: String
var artwork: Artwork
var ranking: Int
var title: String
}


now I want to have a function which fetches the necessary parameters for a song. The song should be named after its uid.

let someArtwork = Artwork(large: "someLink", medium: "someLink", small: "someLink")
let someAlbumUID = Album(uid: "someAlbumUID", artwork: someArtwork, title: "myAlbum", tracks: [0 : "someSongUID"])

func fetchSongWith(someSongUID: String) -> Song {
// fetch information here
let someSongUID = Song(uid: "someSongUID", album: someAlbumUID, artist: String, artwork: Artwork, ranking: Int, title: String)
return someSongUID
}

// App has a song with a myUID fetched

fetchSongWith(someSongUID: myUID)


To wrap it up:
I want to create a constant which is named like the uid of the song its information it holds.

Does anyone know how I could solve this? Or how I should name the constants? I'm using Swift 3/3.1/4 with Xcode 8/9

Thank you




EDIT:

I'm going to try to describe my problem better:

I'm currently programming an app which streams music from a server. I need to fetch information about the track the user wants to play. For example if the user wants to play the song "foo" the app needs to parse the metadata of the song, e.g the album "bar", the artist "foobar". I created a struct for that called "Song" which contains all these parameters.
So when the user clicks on the song the parser fetches the metadata and stores it into a constant named after the song's UID of the type "Song". The question is how can I declare a constant with the name being the song's UID?
I created a function which essentially fetches the metadata. It has an input parameter "uid". The function uses that UID for searching the storage database for the requested track. After that it downloads the metadata which is stored in a child named after the UID of the song in my database. So that I can call the function like that:

fetchSongWith(uid: "foobar")


and it creates a new constant named "foobar" of type "Song" which contains all the metadata of the song.

Is that somehow possible or is it a bad habit? How should I store the metadata?

I'm sorry for the confusion.

Answer Source

All your stuff ends up in the top level Song struct. So my suggestion here is that, to better keep track of everything, starts from your struct and add up data instead of storing your UID separately. UID is part of your Song so it should not be stored as string separately.

In your struct, add an init method with optional and default values. Only UID is required because that's the ID of the song and a song cannot exist without it. Tweak the code however you want. I'm just giving you an idea.

struct Song : Decodable {
    var uid: String
    var album: Album?
    var artist: String?
    var artwork: Artwork?
    var ranking: Int?
    var title: String?

    init(uid: String, album: Album? = nil, artist: String? = nil, artwork: Artwork? = nil, ranking: Int? = nil, title: String? = nil){
        self.uid = uid,
        self.album = album
        //...keep doing
    }
}

Now, say at the beginning, you have an API call to get 5 song's UID, you can simply do this

for uid in uidArray {
    songArray.append(Song(uid: uid))
}

Whenever you want to fetch more data, do it on song level

func fetchSongWith(someSong: song) -> Song {
    // fetch information here
    song.album = "something"
    song.ranking = 1
    return song
}

This will also make future change easy. Say now you want to fetch both UID and sone name at first so that user has a better clue about the sone name. Now the only change you need to make is:

Song(uid: uid, title: "Lady GAGA")

Hope that helps