Swift全局变量

时间:2018-01-09 15:49:40

标签: json swift swift4

我是Swift的初学者,所以让我知道这是否有意义,但我有一个JSON文件,我可以在swift中访问并解析成一个数组,从那里我可以得到一个数组中的字符串并将其存储在var中。我希望能够在全球范围内访问此变量,但我不知道该怎么做。

在另一位用户" rmaddy"的帮助下。我有这段代码:

struct Games: Decodable {
    let videoLink: String
}

class BroadService {
    static let sharedInstance = BroadService()

    func fetchBroadcasts(completion: @escaping ([Games]?) -> ()) {
        let jsonUrlString = "LINK IS HERE."
        guard let url = URL(string: jsonUrlString) else {
            completion(nil)
            return
        }

        URLSession.shared.dataTask(with: url) { (data, response, err) in
            guard let data = data else {
                completion(nil)
                return
            }

            do {
                let games = try JSONDecoder().decode([Games].self, from: data)
                completion(games)
            } catch let jsonErr {
                print("Error deserializing json:", jsonErr)
                completion(nil)
            }
        }.resume()
    }
}

然后我可以从这里访问另一个类:

BroadService.sharedInstance.fetchBroadcasts { (games) in
if let games = games {
    let game = games[indexPath]
    let videoLink = game.videoLink

}

我希望能够访问" videoLink"的内容。在全球范围内,无需使用" BroadService.sharedInstance.fetchBroadcasts {(games)in"我该怎么做呢

2 个答案:

答案 0 :(得分:1)

您可以使用名为Global的结构创建一个文件,并创建一个静态var,并在您获取游戏后将其设置在您的完成块中。

这是一个例子。

struct Global {
    static var games:[Any]? = nil

    static func setGames(games:[Any]) {
        Global.games = games
    }
}

然后在加载应用程序之前或在使用Global之前获取数据并设置该属性:

URLSession.shared.dataTask(with: url) { (data, response, err) in
        guard let data = data else {
            completion(nil)
            return
        }

        do {
            let games = try JSONDecoder().decode([Games].self, from: data)
            Global.setGames(games: games)
            completion(games)
        } catch let jsonErr {
            print("Error deserializing json:", jsonErr)
            completion(nil)
        }
    }.resume()

请注意,这将使Global.games可以从任何地方访问,但它也不会是常量,因此您应该小心不要覆盖它。

这种方式Global.games可以从任何地方访问。

答案 1 :(得分:1)

你不应该使用全局变量,我认为不推荐使用任何语言。

现在你看起来像是一个Singleton类(BroadService),这很好,因为它是你正在寻找的一个很好的解决方案。

接下来,您需要做的就是为该类添加一个属性。假设videoLink是一个字符串,您可以将字符串属性添加到BroadService,例如storedVideoLink作为可选字符串,并在下次需要获取该值之后您已经提取,您可以像这样访问它:BroadService.sharedInstance.storedVideoLink

还有一件事,要让BroadService作为单身人士正常工作,您应该将init设为私有。

总结一下,这就是我的建议:

class BroadService {
    static let sharedInstance = BroadService()
    var storedVideoLink: String?

    private init() {} // to ensure only this class can init itself

    func fetchBroadcasts(completion: @escaping ([Games]?) -> ()) {
        // your code here
    }
}

// somewhere else in your code:
BroadService.sharedInstance.fetchBroadcasts { (games) in
    if let games = games {
        let game = games[indexPath]
        let videoLink = game.videoLink
        BroadService.sharedInstance.storedVideoLink = videoLink
    }
}
// now you can access it from anywhere as
// BroadService.sharedInstance.storedVideoLink

这种方式在同一个班级中保持凝聚力。你甚至可以为storedVideoLink添加一个getter方法,这样你就不必直接访问它了,在这个方法中你可以说如果字符串是nil那么你获取数据,将链接存储到字符串,然后返回字符串。