completion data doesn't append global array after extract from JSON (swift 4)












0















I have an issue with saving struct into Array of struct after fetched from API. After I finish fetching the JSON data and using completion, the data cannot be appended into array inside completion block. I've been looking around for couple days, tried many things, and still doesn't work.



Here is the code:



import UIKit

struct IndodaxApi:Decodable{
var ticker:dataStruct
}

struct dataStruct: Decodable {
var high:String
var low:String
var last:String
var vol_idr:String
var vol_btc:String

init(high:String, low:String, last:String, vol_idr:String, vol_btc:String) {
self.high = high
self.low = low
self.vol_idr = vol_idr
self.vol_btc = vol_btc
self.last = last
}

func printInfo() -> Void {
print("High:(high)")
print("Low:(low)")
print("Last:(last)")
print("vol_idr:(vol_idr)")
print("vol_btc:(vol_btc)")
}
}

class data {
private let link:String
private let ticker:String
private let coinlist_idr:[String]
private var dataCoin:[dataStruct]

init() {
link = "https://indodax.com/api/"
ticker = "/ticker"
coinlist_idr = ["btc_idr"]
dataCoin = [dataStruct]()
}

public func getData() -> [dataStruct] {
dataCoin.removeAll()
load()
return dataCoin
}


This function here means to append data returned from completionhandler into dataCoin array which is struct of DataStruct:



private func load(){
var index = 0
let totalCoin = coinlist_idr.count
while(index<totalCoin){
fetchcoin(coinName: getNextCoin(index), completionHandler: { (data) in
self.dataCoin.append(data)
})
index+=1
}
}


This function here is to fetch the data from API and pass into completionhandler:



public func fetchcoin(coinName:String, completionHandler: @escaping ((dataStruct)->Void)){
let urlLink = self.link + coinName + self.ticker;
let url = URL(string: urlLink)

URLSession.shared.dataTask(with: url!) { (data, response, err) in
guard let data = data else {return}
do {
let api = try JSONDecoder().decode(IndodaxApi.self, from: data)
DispatchQueue.main.async {
let returnData = dataStruct(high: api.ticker.high, low: api.ticker.low, last: api.ticker.last, vol_idr: api.ticker.vol_idr, vol_btc: api.ticker.vol_btc)
completionHandler(returnData)
}
}catch let jsonERR{
print(jsonERR)
}
}.resume()
}

private func getNextCoin(_ coinName:Int)->String{
return coinlist_idr[coinName]
}









share|improve this question

























  • Unrelated but why do you create a new dataStruct instance in the completion handler rather than using the decoded one? By the way please name structs with a starting capital letter. And dataTask works asynchronously. The method getData() cannot work.

    – vadian
    Nov 24 '18 at 20:10













  • @vadian i tried return the api directly , didnt work as well. Thats why i try create a new struct and test it. Noted for the struct with starting capital letter

    – Fernando Ciam
    Nov 24 '18 at 20:13











  • The while loop is pointless. You have to use DispatchGroup to get notified when the last data task has finished. And you have to add completion blocks to all methods which are related to asynchronous data processing.

    – vadian
    Nov 24 '18 at 20:18













  • @vadian noted, but how the completion block doesnt append the array? I tried one data only. I'll add DispatchGroup later.

    – Fernando Ciam
    Nov 24 '18 at 20:32











  • It does append but much much later than the line return dataCoin is executed.

    – vadian
    Nov 24 '18 at 20:35
















0















I have an issue with saving struct into Array of struct after fetched from API. After I finish fetching the JSON data and using completion, the data cannot be appended into array inside completion block. I've been looking around for couple days, tried many things, and still doesn't work.



Here is the code:



import UIKit

struct IndodaxApi:Decodable{
var ticker:dataStruct
}

struct dataStruct: Decodable {
var high:String
var low:String
var last:String
var vol_idr:String
var vol_btc:String

init(high:String, low:String, last:String, vol_idr:String, vol_btc:String) {
self.high = high
self.low = low
self.vol_idr = vol_idr
self.vol_btc = vol_btc
self.last = last
}

func printInfo() -> Void {
print("High:(high)")
print("Low:(low)")
print("Last:(last)")
print("vol_idr:(vol_idr)")
print("vol_btc:(vol_btc)")
}
}

class data {
private let link:String
private let ticker:String
private let coinlist_idr:[String]
private var dataCoin:[dataStruct]

init() {
link = "https://indodax.com/api/"
ticker = "/ticker"
coinlist_idr = ["btc_idr"]
dataCoin = [dataStruct]()
}

public func getData() -> [dataStruct] {
dataCoin.removeAll()
load()
return dataCoin
}


This function here means to append data returned from completionhandler into dataCoin array which is struct of DataStruct:



private func load(){
var index = 0
let totalCoin = coinlist_idr.count
while(index<totalCoin){
fetchcoin(coinName: getNextCoin(index), completionHandler: { (data) in
self.dataCoin.append(data)
})
index+=1
}
}


This function here is to fetch the data from API and pass into completionhandler:



public func fetchcoin(coinName:String, completionHandler: @escaping ((dataStruct)->Void)){
let urlLink = self.link + coinName + self.ticker;
let url = URL(string: urlLink)

URLSession.shared.dataTask(with: url!) { (data, response, err) in
guard let data = data else {return}
do {
let api = try JSONDecoder().decode(IndodaxApi.self, from: data)
DispatchQueue.main.async {
let returnData = dataStruct(high: api.ticker.high, low: api.ticker.low, last: api.ticker.last, vol_idr: api.ticker.vol_idr, vol_btc: api.ticker.vol_btc)
completionHandler(returnData)
}
}catch let jsonERR{
print(jsonERR)
}
}.resume()
}

private func getNextCoin(_ coinName:Int)->String{
return coinlist_idr[coinName]
}









share|improve this question

























  • Unrelated but why do you create a new dataStruct instance in the completion handler rather than using the decoded one? By the way please name structs with a starting capital letter. And dataTask works asynchronously. The method getData() cannot work.

    – vadian
    Nov 24 '18 at 20:10













  • @vadian i tried return the api directly , didnt work as well. Thats why i try create a new struct and test it. Noted for the struct with starting capital letter

    – Fernando Ciam
    Nov 24 '18 at 20:13











  • The while loop is pointless. You have to use DispatchGroup to get notified when the last data task has finished. And you have to add completion blocks to all methods which are related to asynchronous data processing.

    – vadian
    Nov 24 '18 at 20:18













  • @vadian noted, but how the completion block doesnt append the array? I tried one data only. I'll add DispatchGroup later.

    – Fernando Ciam
    Nov 24 '18 at 20:32











  • It does append but much much later than the line return dataCoin is executed.

    – vadian
    Nov 24 '18 at 20:35














0












0








0








I have an issue with saving struct into Array of struct after fetched from API. After I finish fetching the JSON data and using completion, the data cannot be appended into array inside completion block. I've been looking around for couple days, tried many things, and still doesn't work.



Here is the code:



import UIKit

struct IndodaxApi:Decodable{
var ticker:dataStruct
}

struct dataStruct: Decodable {
var high:String
var low:String
var last:String
var vol_idr:String
var vol_btc:String

init(high:String, low:String, last:String, vol_idr:String, vol_btc:String) {
self.high = high
self.low = low
self.vol_idr = vol_idr
self.vol_btc = vol_btc
self.last = last
}

func printInfo() -> Void {
print("High:(high)")
print("Low:(low)")
print("Last:(last)")
print("vol_idr:(vol_idr)")
print("vol_btc:(vol_btc)")
}
}

class data {
private let link:String
private let ticker:String
private let coinlist_idr:[String]
private var dataCoin:[dataStruct]

init() {
link = "https://indodax.com/api/"
ticker = "/ticker"
coinlist_idr = ["btc_idr"]
dataCoin = [dataStruct]()
}

public func getData() -> [dataStruct] {
dataCoin.removeAll()
load()
return dataCoin
}


This function here means to append data returned from completionhandler into dataCoin array which is struct of DataStruct:



private func load(){
var index = 0
let totalCoin = coinlist_idr.count
while(index<totalCoin){
fetchcoin(coinName: getNextCoin(index), completionHandler: { (data) in
self.dataCoin.append(data)
})
index+=1
}
}


This function here is to fetch the data from API and pass into completionhandler:



public func fetchcoin(coinName:String, completionHandler: @escaping ((dataStruct)->Void)){
let urlLink = self.link + coinName + self.ticker;
let url = URL(string: urlLink)

URLSession.shared.dataTask(with: url!) { (data, response, err) in
guard let data = data else {return}
do {
let api = try JSONDecoder().decode(IndodaxApi.self, from: data)
DispatchQueue.main.async {
let returnData = dataStruct(high: api.ticker.high, low: api.ticker.low, last: api.ticker.last, vol_idr: api.ticker.vol_idr, vol_btc: api.ticker.vol_btc)
completionHandler(returnData)
}
}catch let jsonERR{
print(jsonERR)
}
}.resume()
}

private func getNextCoin(_ coinName:Int)->String{
return coinlist_idr[coinName]
}









share|improve this question
















I have an issue with saving struct into Array of struct after fetched from API. After I finish fetching the JSON data and using completion, the data cannot be appended into array inside completion block. I've been looking around for couple days, tried many things, and still doesn't work.



Here is the code:



import UIKit

struct IndodaxApi:Decodable{
var ticker:dataStruct
}

struct dataStruct: Decodable {
var high:String
var low:String
var last:String
var vol_idr:String
var vol_btc:String

init(high:String, low:String, last:String, vol_idr:String, vol_btc:String) {
self.high = high
self.low = low
self.vol_idr = vol_idr
self.vol_btc = vol_btc
self.last = last
}

func printInfo() -> Void {
print("High:(high)")
print("Low:(low)")
print("Last:(last)")
print("vol_idr:(vol_idr)")
print("vol_btc:(vol_btc)")
}
}

class data {
private let link:String
private let ticker:String
private let coinlist_idr:[String]
private var dataCoin:[dataStruct]

init() {
link = "https://indodax.com/api/"
ticker = "/ticker"
coinlist_idr = ["btc_idr"]
dataCoin = [dataStruct]()
}

public func getData() -> [dataStruct] {
dataCoin.removeAll()
load()
return dataCoin
}


This function here means to append data returned from completionhandler into dataCoin array which is struct of DataStruct:



private func load(){
var index = 0
let totalCoin = coinlist_idr.count
while(index<totalCoin){
fetchcoin(coinName: getNextCoin(index), completionHandler: { (data) in
self.dataCoin.append(data)
})
index+=1
}
}


This function here is to fetch the data from API and pass into completionhandler:



public func fetchcoin(coinName:String, completionHandler: @escaping ((dataStruct)->Void)){
let urlLink = self.link + coinName + self.ticker;
let url = URL(string: urlLink)

URLSession.shared.dataTask(with: url!) { (data, response, err) in
guard let data = data else {return}
do {
let api = try JSONDecoder().decode(IndodaxApi.self, from: data)
DispatchQueue.main.async {
let returnData = dataStruct(high: api.ticker.high, low: api.ticker.low, last: api.ticker.last, vol_idr: api.ticker.vol_idr, vol_btc: api.ticker.vol_btc)
completionHandler(returnData)
}
}catch let jsonERR{
print(jsonERR)
}
}.resume()
}

private func getNextCoin(_ coinName:Int)->String{
return coinlist_idr[coinName]
}






json swift






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 24 '18 at 22:25









rmaddy

244k27321383




244k27321383










asked Nov 24 '18 at 20:01









Fernando CiamFernando Ciam

65




65













  • Unrelated but why do you create a new dataStruct instance in the completion handler rather than using the decoded one? By the way please name structs with a starting capital letter. And dataTask works asynchronously. The method getData() cannot work.

    – vadian
    Nov 24 '18 at 20:10













  • @vadian i tried return the api directly , didnt work as well. Thats why i try create a new struct and test it. Noted for the struct with starting capital letter

    – Fernando Ciam
    Nov 24 '18 at 20:13











  • The while loop is pointless. You have to use DispatchGroup to get notified when the last data task has finished. And you have to add completion blocks to all methods which are related to asynchronous data processing.

    – vadian
    Nov 24 '18 at 20:18













  • @vadian noted, but how the completion block doesnt append the array? I tried one data only. I'll add DispatchGroup later.

    – Fernando Ciam
    Nov 24 '18 at 20:32











  • It does append but much much later than the line return dataCoin is executed.

    – vadian
    Nov 24 '18 at 20:35



















  • Unrelated but why do you create a new dataStruct instance in the completion handler rather than using the decoded one? By the way please name structs with a starting capital letter. And dataTask works asynchronously. The method getData() cannot work.

    – vadian
    Nov 24 '18 at 20:10













  • @vadian i tried return the api directly , didnt work as well. Thats why i try create a new struct and test it. Noted for the struct with starting capital letter

    – Fernando Ciam
    Nov 24 '18 at 20:13











  • The while loop is pointless. You have to use DispatchGroup to get notified when the last data task has finished. And you have to add completion blocks to all methods which are related to asynchronous data processing.

    – vadian
    Nov 24 '18 at 20:18













  • @vadian noted, but how the completion block doesnt append the array? I tried one data only. I'll add DispatchGroup later.

    – Fernando Ciam
    Nov 24 '18 at 20:32











  • It does append but much much later than the line return dataCoin is executed.

    – vadian
    Nov 24 '18 at 20:35

















Unrelated but why do you create a new dataStruct instance in the completion handler rather than using the decoded one? By the way please name structs with a starting capital letter. And dataTask works asynchronously. The method getData() cannot work.

– vadian
Nov 24 '18 at 20:10







Unrelated but why do you create a new dataStruct instance in the completion handler rather than using the decoded one? By the way please name structs with a starting capital letter. And dataTask works asynchronously. The method getData() cannot work.

– vadian
Nov 24 '18 at 20:10















@vadian i tried return the api directly , didnt work as well. Thats why i try create a new struct and test it. Noted for the struct with starting capital letter

– Fernando Ciam
Nov 24 '18 at 20:13





@vadian i tried return the api directly , didnt work as well. Thats why i try create a new struct and test it. Noted for the struct with starting capital letter

– Fernando Ciam
Nov 24 '18 at 20:13













The while loop is pointless. You have to use DispatchGroup to get notified when the last data task has finished. And you have to add completion blocks to all methods which are related to asynchronous data processing.

– vadian
Nov 24 '18 at 20:18







The while loop is pointless. You have to use DispatchGroup to get notified when the last data task has finished. And you have to add completion blocks to all methods which are related to asynchronous data processing.

– vadian
Nov 24 '18 at 20:18















@vadian noted, but how the completion block doesnt append the array? I tried one data only. I'll add DispatchGroup later.

– Fernando Ciam
Nov 24 '18 at 20:32





@vadian noted, but how the completion block doesnt append the array? I tried one data only. I'll add DispatchGroup later.

– Fernando Ciam
Nov 24 '18 at 20:32













It does append but much much later than the line return dataCoin is executed.

– vadian
Nov 24 '18 at 20:35





It does append but much much later than the line return dataCoin is executed.

– vadian
Nov 24 '18 at 20:35












0






active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53461895%2fcompletion-data-doesnt-append-global-array-after-extract-from-json-swift-4%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53461895%2fcompletion-data-doesnt-append-global-array-after-extract-from-json-swift-4%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Tonle Sap (See)

I get strange results when I access the Sqlitedatabase with Unity C# via XAMPP

Guatemaltekische Davis-Cup-Mannschaft