Setting a text on the label using JSON data
}
Hey guys, I have a problem setting a value for the label. The label should display the number of elements in the array inside my JSON (link - followers_url
variable). I call alamo and make a request with that url. When I print the value inside parseData()
method I get the right result. When I print it inside configureView()
and viewDidLoad()
I always get 0.
Setting the label text also works only inside parseData()
method. Any ideas how I can get it to work?
ios json swift parsing alamofire
add a comment |
}
Hey guys, I have a problem setting a value for the label. The label should display the number of elements in the array inside my JSON (link - followers_url
variable). I call alamo and make a request with that url. When I print the value inside parseData()
method I get the right result. When I print it inside configureView()
and viewDidLoad()
I always get 0.
Setting the label text also works only inside parseData()
method. Any ideas how I can get it to work?
ios json swift parsing alamofire
Alamofire call is on another background thread..before the response is received the statement of print after callAlamo is executed. Please do your operation after the completion handler ie response is received in {response in block
– Mukul More
Nov 22 '18 at 8:08
Mat I am not sure what you are asking, do you, I mean based on what I understood, if you writefollowersLabel.text = String(followersAndFollowingArray.count)
That should solve the problem. I am assuming that you know these are asynchronous calls and that is why delegate function will need to be used in order to update the code.
– rptwsthi
Nov 22 '18 at 8:09
add a comment |
}
Hey guys, I have a problem setting a value for the label. The label should display the number of elements in the array inside my JSON (link - followers_url
variable). I call alamo and make a request with that url. When I print the value inside parseData()
method I get the right result. When I print it inside configureView()
and viewDidLoad()
I always get 0.
Setting the label text also works only inside parseData()
method. Any ideas how I can get it to work?
ios json swift parsing alamofire
}
Hey guys, I have a problem setting a value for the label. The label should display the number of elements in the array inside my JSON (link - followers_url
variable). I call alamo and make a request with that url. When I print the value inside parseData()
method I get the right result. When I print it inside configureView()
and viewDidLoad()
I always get 0.
Setting the label text also works only inside parseData()
method. Any ideas how I can get it to work?
ios json swift parsing alamofire
ios json swift parsing alamofire
edited Nov 22 '18 at 14:15
Matt Andrei
asked Nov 22 '18 at 8:01
Matt AndreiMatt Andrei
11
11
Alamofire call is on another background thread..before the response is received the statement of print after callAlamo is executed. Please do your operation after the completion handler ie response is received in {response in block
– Mukul More
Nov 22 '18 at 8:08
Mat I am not sure what you are asking, do you, I mean based on what I understood, if you writefollowersLabel.text = String(followersAndFollowingArray.count)
That should solve the problem. I am assuming that you know these are asynchronous calls and that is why delegate function will need to be used in order to update the code.
– rptwsthi
Nov 22 '18 at 8:09
add a comment |
Alamofire call is on another background thread..before the response is received the statement of print after callAlamo is executed. Please do your operation after the completion handler ie response is received in {response in block
– Mukul More
Nov 22 '18 at 8:08
Mat I am not sure what you are asking, do you, I mean based on what I understood, if you writefollowersLabel.text = String(followersAndFollowingArray.count)
That should solve the problem. I am assuming that you know these are asynchronous calls and that is why delegate function will need to be used in order to update the code.
– rptwsthi
Nov 22 '18 at 8:09
Alamofire call is on another background thread..before the response is received the statement of print after callAlamo is executed. Please do your operation after the completion handler ie response is received in {response in block
– Mukul More
Nov 22 '18 at 8:08
Alamofire call is on another background thread..before the response is received the statement of print after callAlamo is executed. Please do your operation after the completion handler ie response is received in {response in block
– Mukul More
Nov 22 '18 at 8:08
Mat I am not sure what you are asking, do you, I mean based on what I understood, if you write
followersLabel.text = String(followersAndFollowingArray.count)
That should solve the problem. I am assuming that you know these are asynchronous calls and that is why delegate function will need to be used in order to update the code.– rptwsthi
Nov 22 '18 at 8:09
Mat I am not sure what you are asking, do you, I mean based on what I understood, if you write
followersLabel.text = String(followersAndFollowingArray.count)
That should solve the problem. I am assuming that you know these are asynchronous calls and that is why delegate function will need to be used in order to update the code.– rptwsthi
Nov 22 '18 at 8:09
add a comment |
3 Answers
3
active
oldest
votes
Alamofire.request(url).validate().responseJSON { response in
self.parseData(data: response.data!)
}
This above request runs on another background thread.
So when you call the function callAlamo the response is received in the completion block ( { response in ). So when you call print() after callAlamo. the response has not yet been received and print is called so value is not updated. So please perform the operation on the response only through completion block.
If you want to set a label write you set label code after self.parseData in completion block ({response in). Make sure you set it in main queue as the UI operation needs to be performed on main queue only
Following question will help to set label on main thread.
In Swift how to call method with parameters on GCD main thread?
You need to understand multithreading concept to get a better understanding of this. Follow this https://medium.com/@gabriel_lewis/threading-in-swift-simply-explained-5c8dd680b9b2
add a comment |
You should learn something about iOS Parsing techniques. Then learn how to create Model using class or struct. Then you will get Idea.
You should look into Object Mapper as well.
add a comment |
You're dealing with an asynchronous operation. Asynchronous operations are "actions" that are dispatched and require you to wait before they complete. Think about loading a website in Safari. Once you type, let's say, stackoverflow.com in your browser, a loading spinner will notify that something is loading. While the page is loading, you obviously cannot see what's on the webpage. There's only an empty, white page.
The same is happening with your request. When you call the callAlamo
function you're telling the app to start loading something. This is requiring you to wait until the task is done. If you count the elements in the followersAndFollowingArray
right after the server call, then you'll get it empty, because the request is still waiting to be completed. It's like pretending to view the stackoverflow.com website immediately after having typed the URL. You can't.
That's where closures come in handy. You can use closures to execute something when another action has been completed. In this case, I would fire the web request, display a loading spinner to notify the user that something is loading, and finally populate the followersLabel
along with stopping the animation. You can do something like that
func callAlamo(url: String, completion: @escaping ([User]) -> Void) {
if Connectivity.isConnectedToInternet {
Alamofire.request(url).validate().responseJSON { response in
let userData = self.parseData(data: response.data!)
completion(userData)
}
}
}
Additionally you need to let the parseData
method to return the parsed array of Users
, so the callAlamo function could use it.
func parseData(data : Data) -> [User] {
do {
return try JSONDecoder().decode([User].self, from: data)
} catch let jsonErr {
print("Error serializing", jsonErr)
return [User]()
}
}
Finally, you can execute the callAlamo
function on inside the configureView
method, performing an action when the server request has been completed. In our case, we want to populate the label.
private func configureView(){
followersLabel.text = String(followers)
// Starting the loading animation
startAnimation()
callAlamo(url: "Hello") { userData in
// Assigning the callAlamo result to your followers array
// once the server request has been completed
self.followersAndFollowingArray = userData
// This will return the number you'd expect
print(self.followersAndFollowingArray.count)
// Stopping the loading animation
stopAnimation()
}
}
Right now you probably won't have the startAnimation
and stopAnimation
methods, but you can feel free to implement them, I just wanted to give you an idea of a classic implementation.
@MattAndrei ops, you're right, I forgot that you're dealing with a do/catch block. I fixed the parseData method to work correctly and avoid that error :)
– Lorenzo Zanotto
Nov 22 '18 at 14:28
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53426291%2fsetting-a-text-on-the-label-using-json-data%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Alamofire.request(url).validate().responseJSON { response in
self.parseData(data: response.data!)
}
This above request runs on another background thread.
So when you call the function callAlamo the response is received in the completion block ( { response in ). So when you call print() after callAlamo. the response has not yet been received and print is called so value is not updated. So please perform the operation on the response only through completion block.
If you want to set a label write you set label code after self.parseData in completion block ({response in). Make sure you set it in main queue as the UI operation needs to be performed on main queue only
Following question will help to set label on main thread.
In Swift how to call method with parameters on GCD main thread?
You need to understand multithreading concept to get a better understanding of this. Follow this https://medium.com/@gabriel_lewis/threading-in-swift-simply-explained-5c8dd680b9b2
add a comment |
Alamofire.request(url).validate().responseJSON { response in
self.parseData(data: response.data!)
}
This above request runs on another background thread.
So when you call the function callAlamo the response is received in the completion block ( { response in ). So when you call print() after callAlamo. the response has not yet been received and print is called so value is not updated. So please perform the operation on the response only through completion block.
If you want to set a label write you set label code after self.parseData in completion block ({response in). Make sure you set it in main queue as the UI operation needs to be performed on main queue only
Following question will help to set label on main thread.
In Swift how to call method with parameters on GCD main thread?
You need to understand multithreading concept to get a better understanding of this. Follow this https://medium.com/@gabriel_lewis/threading-in-swift-simply-explained-5c8dd680b9b2
add a comment |
Alamofire.request(url).validate().responseJSON { response in
self.parseData(data: response.data!)
}
This above request runs on another background thread.
So when you call the function callAlamo the response is received in the completion block ( { response in ). So when you call print() after callAlamo. the response has not yet been received and print is called so value is not updated. So please perform the operation on the response only through completion block.
If you want to set a label write you set label code after self.parseData in completion block ({response in). Make sure you set it in main queue as the UI operation needs to be performed on main queue only
Following question will help to set label on main thread.
In Swift how to call method with parameters on GCD main thread?
You need to understand multithreading concept to get a better understanding of this. Follow this https://medium.com/@gabriel_lewis/threading-in-swift-simply-explained-5c8dd680b9b2
Alamofire.request(url).validate().responseJSON { response in
self.parseData(data: response.data!)
}
This above request runs on another background thread.
So when you call the function callAlamo the response is received in the completion block ( { response in ). So when you call print() after callAlamo. the response has not yet been received and print is called so value is not updated. So please perform the operation on the response only through completion block.
If you want to set a label write you set label code after self.parseData in completion block ({response in). Make sure you set it in main queue as the UI operation needs to be performed on main queue only
Following question will help to set label on main thread.
In Swift how to call method with parameters on GCD main thread?
You need to understand multithreading concept to get a better understanding of this. Follow this https://medium.com/@gabriel_lewis/threading-in-swift-simply-explained-5c8dd680b9b2
answered Nov 22 '18 at 8:14
Mukul MoreMukul More
253415
253415
add a comment |
add a comment |
You should learn something about iOS Parsing techniques. Then learn how to create Model using class or struct. Then you will get Idea.
You should look into Object Mapper as well.
add a comment |
You should learn something about iOS Parsing techniques. Then learn how to create Model using class or struct. Then you will get Idea.
You should look into Object Mapper as well.
add a comment |
You should learn something about iOS Parsing techniques. Then learn how to create Model using class or struct. Then you will get Idea.
You should look into Object Mapper as well.
You should learn something about iOS Parsing techniques. Then learn how to create Model using class or struct. Then you will get Idea.
You should look into Object Mapper as well.
answered Nov 22 '18 at 9:36
MukeshMukesh
2,0111227
2,0111227
add a comment |
add a comment |
You're dealing with an asynchronous operation. Asynchronous operations are "actions" that are dispatched and require you to wait before they complete. Think about loading a website in Safari. Once you type, let's say, stackoverflow.com in your browser, a loading spinner will notify that something is loading. While the page is loading, you obviously cannot see what's on the webpage. There's only an empty, white page.
The same is happening with your request. When you call the callAlamo
function you're telling the app to start loading something. This is requiring you to wait until the task is done. If you count the elements in the followersAndFollowingArray
right after the server call, then you'll get it empty, because the request is still waiting to be completed. It's like pretending to view the stackoverflow.com website immediately after having typed the URL. You can't.
That's where closures come in handy. You can use closures to execute something when another action has been completed. In this case, I would fire the web request, display a loading spinner to notify the user that something is loading, and finally populate the followersLabel
along with stopping the animation. You can do something like that
func callAlamo(url: String, completion: @escaping ([User]) -> Void) {
if Connectivity.isConnectedToInternet {
Alamofire.request(url).validate().responseJSON { response in
let userData = self.parseData(data: response.data!)
completion(userData)
}
}
}
Additionally you need to let the parseData
method to return the parsed array of Users
, so the callAlamo function could use it.
func parseData(data : Data) -> [User] {
do {
return try JSONDecoder().decode([User].self, from: data)
} catch let jsonErr {
print("Error serializing", jsonErr)
return [User]()
}
}
Finally, you can execute the callAlamo
function on inside the configureView
method, performing an action when the server request has been completed. In our case, we want to populate the label.
private func configureView(){
followersLabel.text = String(followers)
// Starting the loading animation
startAnimation()
callAlamo(url: "Hello") { userData in
// Assigning the callAlamo result to your followers array
// once the server request has been completed
self.followersAndFollowingArray = userData
// This will return the number you'd expect
print(self.followersAndFollowingArray.count)
// Stopping the loading animation
stopAnimation()
}
}
Right now you probably won't have the startAnimation
and stopAnimation
methods, but you can feel free to implement them, I just wanted to give you an idea of a classic implementation.
@MattAndrei ops, you're right, I forgot that you're dealing with a do/catch block. I fixed the parseData method to work correctly and avoid that error :)
– Lorenzo Zanotto
Nov 22 '18 at 14:28
add a comment |
You're dealing with an asynchronous operation. Asynchronous operations are "actions" that are dispatched and require you to wait before they complete. Think about loading a website in Safari. Once you type, let's say, stackoverflow.com in your browser, a loading spinner will notify that something is loading. While the page is loading, you obviously cannot see what's on the webpage. There's only an empty, white page.
The same is happening with your request. When you call the callAlamo
function you're telling the app to start loading something. This is requiring you to wait until the task is done. If you count the elements in the followersAndFollowingArray
right after the server call, then you'll get it empty, because the request is still waiting to be completed. It's like pretending to view the stackoverflow.com website immediately after having typed the URL. You can't.
That's where closures come in handy. You can use closures to execute something when another action has been completed. In this case, I would fire the web request, display a loading spinner to notify the user that something is loading, and finally populate the followersLabel
along with stopping the animation. You can do something like that
func callAlamo(url: String, completion: @escaping ([User]) -> Void) {
if Connectivity.isConnectedToInternet {
Alamofire.request(url).validate().responseJSON { response in
let userData = self.parseData(data: response.data!)
completion(userData)
}
}
}
Additionally you need to let the parseData
method to return the parsed array of Users
, so the callAlamo function could use it.
func parseData(data : Data) -> [User] {
do {
return try JSONDecoder().decode([User].self, from: data)
} catch let jsonErr {
print("Error serializing", jsonErr)
return [User]()
}
}
Finally, you can execute the callAlamo
function on inside the configureView
method, performing an action when the server request has been completed. In our case, we want to populate the label.
private func configureView(){
followersLabel.text = String(followers)
// Starting the loading animation
startAnimation()
callAlamo(url: "Hello") { userData in
// Assigning the callAlamo result to your followers array
// once the server request has been completed
self.followersAndFollowingArray = userData
// This will return the number you'd expect
print(self.followersAndFollowingArray.count)
// Stopping the loading animation
stopAnimation()
}
}
Right now you probably won't have the startAnimation
and stopAnimation
methods, but you can feel free to implement them, I just wanted to give you an idea of a classic implementation.
@MattAndrei ops, you're right, I forgot that you're dealing with a do/catch block. I fixed the parseData method to work correctly and avoid that error :)
– Lorenzo Zanotto
Nov 22 '18 at 14:28
add a comment |
You're dealing with an asynchronous operation. Asynchronous operations are "actions" that are dispatched and require you to wait before they complete. Think about loading a website in Safari. Once you type, let's say, stackoverflow.com in your browser, a loading spinner will notify that something is loading. While the page is loading, you obviously cannot see what's on the webpage. There's only an empty, white page.
The same is happening with your request. When you call the callAlamo
function you're telling the app to start loading something. This is requiring you to wait until the task is done. If you count the elements in the followersAndFollowingArray
right after the server call, then you'll get it empty, because the request is still waiting to be completed. It's like pretending to view the stackoverflow.com website immediately after having typed the URL. You can't.
That's where closures come in handy. You can use closures to execute something when another action has been completed. In this case, I would fire the web request, display a loading spinner to notify the user that something is loading, and finally populate the followersLabel
along with stopping the animation. You can do something like that
func callAlamo(url: String, completion: @escaping ([User]) -> Void) {
if Connectivity.isConnectedToInternet {
Alamofire.request(url).validate().responseJSON { response in
let userData = self.parseData(data: response.data!)
completion(userData)
}
}
}
Additionally you need to let the parseData
method to return the parsed array of Users
, so the callAlamo function could use it.
func parseData(data : Data) -> [User] {
do {
return try JSONDecoder().decode([User].self, from: data)
} catch let jsonErr {
print("Error serializing", jsonErr)
return [User]()
}
}
Finally, you can execute the callAlamo
function on inside the configureView
method, performing an action when the server request has been completed. In our case, we want to populate the label.
private func configureView(){
followersLabel.text = String(followers)
// Starting the loading animation
startAnimation()
callAlamo(url: "Hello") { userData in
// Assigning the callAlamo result to your followers array
// once the server request has been completed
self.followersAndFollowingArray = userData
// This will return the number you'd expect
print(self.followersAndFollowingArray.count)
// Stopping the loading animation
stopAnimation()
}
}
Right now you probably won't have the startAnimation
and stopAnimation
methods, but you can feel free to implement them, I just wanted to give you an idea of a classic implementation.
You're dealing with an asynchronous operation. Asynchronous operations are "actions" that are dispatched and require you to wait before they complete. Think about loading a website in Safari. Once you type, let's say, stackoverflow.com in your browser, a loading spinner will notify that something is loading. While the page is loading, you obviously cannot see what's on the webpage. There's only an empty, white page.
The same is happening with your request. When you call the callAlamo
function you're telling the app to start loading something. This is requiring you to wait until the task is done. If you count the elements in the followersAndFollowingArray
right after the server call, then you'll get it empty, because the request is still waiting to be completed. It's like pretending to view the stackoverflow.com website immediately after having typed the URL. You can't.
That's where closures come in handy. You can use closures to execute something when another action has been completed. In this case, I would fire the web request, display a loading spinner to notify the user that something is loading, and finally populate the followersLabel
along with stopping the animation. You can do something like that
func callAlamo(url: String, completion: @escaping ([User]) -> Void) {
if Connectivity.isConnectedToInternet {
Alamofire.request(url).validate().responseJSON { response in
let userData = self.parseData(data: response.data!)
completion(userData)
}
}
}
Additionally you need to let the parseData
method to return the parsed array of Users
, so the callAlamo function could use it.
func parseData(data : Data) -> [User] {
do {
return try JSONDecoder().decode([User].self, from: data)
} catch let jsonErr {
print("Error serializing", jsonErr)
return [User]()
}
}
Finally, you can execute the callAlamo
function on inside the configureView
method, performing an action when the server request has been completed. In our case, we want to populate the label.
private func configureView(){
followersLabel.text = String(followers)
// Starting the loading animation
startAnimation()
callAlamo(url: "Hello") { userData in
// Assigning the callAlamo result to your followers array
// once the server request has been completed
self.followersAndFollowingArray = userData
// This will return the number you'd expect
print(self.followersAndFollowingArray.count)
// Stopping the loading animation
stopAnimation()
}
}
Right now you probably won't have the startAnimation
and stopAnimation
methods, but you can feel free to implement them, I just wanted to give you an idea of a classic implementation.
edited Nov 22 '18 at 14:27
answered Nov 22 '18 at 10:01
Lorenzo ZanottoLorenzo Zanotto
1365
1365
@MattAndrei ops, you're right, I forgot that you're dealing with a do/catch block. I fixed the parseData method to work correctly and avoid that error :)
– Lorenzo Zanotto
Nov 22 '18 at 14:28
add a comment |
@MattAndrei ops, you're right, I forgot that you're dealing with a do/catch block. I fixed the parseData method to work correctly and avoid that error :)
– Lorenzo Zanotto
Nov 22 '18 at 14:28
@MattAndrei ops, you're right, I forgot that you're dealing with a do/catch block. I fixed the parseData method to work correctly and avoid that error :)
– Lorenzo Zanotto
Nov 22 '18 at 14:28
@MattAndrei ops, you're right, I forgot that you're dealing with a do/catch block. I fixed the parseData method to work correctly and avoid that error :)
– Lorenzo Zanotto
Nov 22 '18 at 14:28
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53426291%2fsetting-a-text-on-the-label-using-json-data%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
Alamofire call is on another background thread..before the response is received the statement of print after callAlamo is executed. Please do your operation after the completion handler ie response is received in {response in block
– Mukul More
Nov 22 '18 at 8:08
Mat I am not sure what you are asking, do you, I mean based on what I understood, if you write
followersLabel.text = String(followersAndFollowingArray.count)
That should solve the problem. I am assuming that you know these are asynchronous calls and that is why delegate function will need to be used in order to update the code.– rptwsthi
Nov 22 '18 at 8:09