Observing Asynchronous Requests

女生的网名这么多〃 提交于 2019-12-23 05:29:33

问题


I have three separate calls to APIs. When all three calls are complete, I am going to aggregate the data and use it to form a separate model object.

I figured I would use property observers to accomplish this but I have no idea how it would be implemented. Any help or guidance would be appreciated.

I have created a model object for making the network calls that passes the response data into an escaping closure. This is the function where the data is parsed:

func loadLibrary() {

    //  League Data Containers

    var names = Dictionary<Int, String>() // API Call 1
    var titles = Dictionary<Int, String>() // Call 1
    var masteryLevels = Dictionary<Int, Int>() // 2
    var masteryPoints = Dictionary<Int, Int>() // 2

    //  Champion Data Containers

    var championRolesLibrary = Array<Dictionary<String,Array<Role>>>() // 3
    var championWithRoles = Dictionary<String,Array<Role>>() // 3
    var championRoles = Array<Role>() // 3

    //  Making Calls to the APIs

    leagueAPI.downloadStaticData { data in
        //  API Call is made and data is parsed into containers
    }

    leagueAPI.downloadChampionMasteryData { data in
        //  API Call is made and data is parsed into containers
    }

    championAPI.downloadChampionRolesData { data in
        //  API Call is made and data is parsed into containers
    }

    // Once all three calls have completed and the data has been parsed into different containers, the data is all brought together to create a library of objects.

    func aggregateData() {

        //  Take data from all the containers and use them in here.
        //  The issue is when to call this function.

    }
}

回答1:


A simple way to solve that is by nesting all three requests:

func loadLibrary() {

    //  League Data Containers

    var names = Dictionary<Int, String>() // API Call 1
    var titles = Dictionary<Int, String>() // Call 1
    var masteryLevels = Dictionary<Int, Int>() // 2
    var masteryPoints = Dictionary<Int, Int>() // 2

    //  Champion Data Containers

    var championRolesLibrary = Array<Dictionary<String,Array<Role>>>() // 3
    var championWithRoles = Dictionary<String,Array<Role>>() // 3
    var championRoles = Array<Role>() // 3

    //  Making Calls to the APIs

    leagueAPI.downloadStaticData { data in
        //  API Call is made and data is parsed into containers

        leagueAPI.downloadChampionMasteryData { data2 in

            //  API Call is made and data is parsed into containers
            championAPI.downloadChampionRolesData { data3 in

                //  API Call is made and data is parsed into containers// Once all three calls have completed and the data has been parsed into different containers, the data is all brought together to create a library of objects.

                aggregateData() {

                //  Take data from all the containers and use them in here.
                //  The issue is when to call this function.

                }
            }
        }
    }

}

EDIT: You can also accomplish what you want by using DispatchGroup as said by @ rmaddy, in this case you would do this:

func loadLibrary() {

    //  League Data Containers

    var names = Dictionary<Int, String>() // API Call 1
    var titles = Dictionary<Int, String>() // Call 1
    var masteryLevels = Dictionary<Int, Int>() // 2
    var masteryPoints = Dictionary<Int, Int>() // 2

    //  Champion Data Containers

    var championRolesLibrary = Array<Dictionary<String,Array<Role>>>() // 3
    var championWithRoles = Dictionary<String,Array<Role>>() // 3
    var championRoles = Array<Role>() // 3

    // Create DispatchGroup
    let dispatchGroup = DispatchGroup()

    //  Making Calls to the APIs

    dispatchGroup.enter()
    leagueAPI.downloadStaticData { data in
        //  API Call is made and data is parsed into containers
        dispatchGroup.leave()
    }

    dispatchGroup.enter()
    leagueAPI.downloadChampionMasteryData { data in
        //  API Call is made and data is parsed into containers
        dispatchGroup.leave()
    }
    dispatchGroup.enter()
    championAPI.downloadChampionRolesData { data in
        //  API Call is made and data is parsed into containers
        dispatchGroup.leave()
    }

    // Once all three calls have completed and the data has been parsed into different containers, the data is all brought together to create a library of objects.
    dispatchGroup.notify(queue: DispatchQueue.global(qos: .background)){
        aggregateData() {

            //  Take data from all the containers and use them in here.
            //  The issue is when to call this function.

        }
    }

}


来源:https://stackoverflow.com/questions/43689685/observing-asynchronous-requests

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!