Hi Brian. This is now introduced in SDK but this concept was already present in SwiftyJSON and Moya from a very long time. Also we can do it in 4.2 too
This is a nice touch! By the way, just go and purchase all of Brian's courses and thank me later! Wish I had Brian to guide me when I was starting Swift development. But its never too late!
Hi Brian. , this is very good info .I have a problem to support iPad Pro(12.9 inch) screen. I added different font for iPhone and iPad. its working properly in other devices but in iPad Pro(12.9 inch) screen the text is too small and unable to read. need your help on this
nice video Brian. I got this working to fetch data & update my storyboard labels during viewDidLoad. My question is this... my URL string is 'http...(myhost)...?channel=' and I append the channel# when I send it. My API returns different data sets (same struc) for each channel, so after viewDidLoad channel=1, I would like to re-hit the API with channel 2 after 5secs, then channel 3, etc. How do I do this? I tried looping in viewDidLoad but it only updated my labels the last hit. Thanks :)
why does moving .self to the outside of the bracket return the entire array? @ 5:56 a little confused on how .self is operating in this scenario. (new to swift)
That's just how it works, there's no explanation beyond that. You just have to look at more examples at parsing JSON objects. For more lessons on JSON, please visit these episodes: www.letsbuildthatapp.com/course_video?id=4662
Yes, if you're writing a lot of APIs then it becomes tedious typing out both closures. You'll get used to this concept quick enough when other APIs adopt this syntax.
What if we have category key with course name inside each array dict object under array and want to display list of objects based on category using segment selection in single tableview controller ? How can we achieve this ?
We can make a generic typealias Completion = (Result) -> () and later we can simply use completion: @escaping Completion if we want to make only one function for decoding and api response
My only problem with the Result approach, which Alamofire uses, is when I want data and an error. For example, Instagram’s API sets the http status code AND returns JSON. I still want that JSON.
Hey Brian, Thanks for this tutorial. I have a question for you. I am curious if you have any information on handling the "response" var from the URL session completion. I assume response is the http error, like 200s for success, 400s for client error, etc. Is there much use to handling this response? I am currently building a simple backend with flask and I can return a json and a response code back with each route if I want. Are http responses necessary for mobile development?
I have a question, I am hoping you or someone here can help me. I need to send a POST request to a server that is both json and base64 encoded. The problem being, when I attempt to assign the base64encoded string to the request.httpBody I get the error 'cannot assign value of type String to type Data?'. I have tried using request.httpBody = Data(jsonData!).base64EncodedData(), but the server is getting an empty array and the request fails. I can't find a way to actually send base64 encoded string in a POST request. Any help would be really appreciated. Thank you.
Have you tried using DispatchGroup to turn callbacks into an async-await style function? It is by far the best way to handle callbacks. So I enjoy the video explaining the new Result type in Swift 5, but I think you should mention that there are better ways to handle callbacks.
I like async-awaits as much as the next guy, it's disappointing that this doesn't come native with Foundation. That being said, the Result type has its place and can diversify your API toolset a lot.
@@LetsBuildThatApp Can you clarify a little bit? I think you could replace any function callback with an async-await style function and make the code more readable using DispatchGroup which is included in Foundation.
The purpose of a dispatch group is to synchronize a group of asynchronous calls and provide a proper callback mechanism when all tasks are finished. Even though they are similar, I wouldn't necessarily conflate DispatchGroup with the async-await pattern. Out of curiosity, how would you handle the potential errors of 3 async calls using a top down DispatchGroup block of code?
Hi i am trying to do a NEWS APP and i faced this problem! Failed to download data: typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array but found a dictionary instead.", underlyingError: nil)) I tried to find nil as i saw some different answers in stack overflow but nothing!
You need to double-check your data model - Looks like you've got it wrong Look at this for an example - stackoverflow.com/questions/52265674/expected-to-decode-int-but-found-a-string
I start to learn developing IOS apps with Swift. I want to ask something. I always use libraries like 'Moya' or 'Alamofire' to request API. What do you think should i use libraries or is NSURLSession enough ?
Hi, i am using swift 5, i am beginner to iOS, i am using WKWebview to convert for my web application to iOS app, in my application i have social login options like facebook and google login, when i successful log In, Facebook login popup or google login page not closing, i need add close button or back button. is it possible, please help me, thanks in advance.
hi When i import Alamofire and try "Result" . I have got an error Generic type 'Result' specialized with too many type parameters (got 2, but expected 1). when i delete Alamofire Import there is no problem ?
Its definitely a lot cleaner but it almost seems like its performing the same task (as in checking if an error is present and reporting nothing) still interesting nonetheless!!
@@LetsBuildThatApp Brian.... I would suggest using only compression and eq during post. I am a believer that reverb on vocals should be reserved for songs only. But that's just me. Good luck!
this doesn't work if you are already using Generic types for your decoding. like completion( Result) you need to mention the class you are decoding like Result, too bad
@@LetsBuildThatApp hey thanks for the reply, I actually imported Alamofire also in that same class and it was picking up Alamofire’s Result instead of Apple’s Result Enum, removing Alamofire import solved it for me
Thank you for sharing this, Brian! Great explanation as well :-) What should I do with the completion call to make my fetchUsers function below work? fileprivate func fetchGenericJSONData(urlString: String, completion: @escaping (Result) -> ()) { guard let url = Bundle.main.url(forResource: urlString, withExtension: "json") else { return } if let data = try? Data(contentsOf: url) { do { let objects = try JSONDecoder().decode(T.self, from: data) completion(.success(objects)) } catch let jsonError { completion(.failure(jsonError)) } } } func fetchUsers(completion: @escaping ([User]?, Error?) -> ()) { fetchGenericJSONData(urlString: "Users", completion: completion) }
@@pradeepkumar-tm5et Hi Pradeep! Check out my code below :-) I am working with local JSON files for testing purposes, so my generic function is a little bit different. The parameters should be the same I believe. I hope my code can help you out! func fetchUsers(completion: @escaping (Result) -> ()) { fetchGenericJSONData(urlString: "Users", completion: completion) } fileprivate func fetchGenericJSONData(urlString: String, completion: @escaping (Result) -> ()) { guard let url = Bundle.main.url(forResource: urlString, withExtension: "json") else { return } if let data = try? Data(contentsOf: url) { do { let objects = try JSONDecoder().decode(T.self, from: data) completion(.success(objects)) } catch let jsonError { completion(.failure(jsonError)) } } } fileprivate func fetchUserData() { Service.shared.fetchUsers { (result) in switch result { case .success(let user): self.userViewModel = user ?? [] case .failure(let err): print("Failed to fetch data:", err) } } }
This video is by far the most mind clearing tutorial on Swift Result type. good job Brian.
Hi Brian. This is now introduced in SDK but this concept was already present in SwiftyJSON and Moya from a very long time. Also we can do it in 4.2 too
This is a nice touch! By the way, just go and purchase all of Brian's courses and thank me later! Wish I had Brian to guide me when I was starting Swift development. But its never too late!
Number one favorite tutor!
I did not know abouzt this feature, but it will make my callbacks a lot easier and more readable - thank you!
Glad to see this make it into Swift.
You, sir, get mad kudos for this
It's very useful video!!!
I was confused about how to use "Associate Value" before
Now It's all clear
thank you so much Brian
Hey Brian!, what a nice tutorial. Indeed a practical example clarifies the concept very clearly.
Thanks for the video and keep Up!
thanks man, it makes my alamofire implementation more cleaner
Hi Brian. , this is very good info .I have a problem to support iPad Pro(12.9 inch) screen. I added different font for iPhone and iPad. its working properly in other devices but in iPad Pro(12.9 inch) screen the text is too small and unable to read. need your help on this
It is just fun to watch your videos . It will be a few months before I can/would use this.
Very nice, I’ll implement this tomorrow since I’m refactoring some network code. Thanks Brian
Thank you Brain! This video help me
nice video Brian. I got this working to fetch data & update my storyboard labels during viewDidLoad. My question is this... my URL string is 'http...(myhost)...?channel=' and I append the channel# when I send it. My API returns different data sets (same struc) for each channel, so after viewDidLoad channel=1, I would like to re-hit the API with channel 2 after 5secs, then channel 3, etc. How do I do this? I tried looping in viewDidLoad but it only updated my labels the last hit. Thanks :)
Thank you Brian for this tutorial.
why does moving .self to the outside of the bracket return the entire array? @ 5:56 a little confused on how .self is operating in this scenario. (new to swift)
That's just how it works, there's no explanation beyond that. You just have to look at more examples at parsing JSON objects. For more lessons on JSON, please visit these episodes: www.letsbuildthatapp.com/course_video?id=4662
@@LetsBuildThatApp Will do, thanks for the reply, you are an amazing teacher!
Hi Brain! Nice tutorial!
As for me, I prefer to make an API with separate success and failure closures. Is there something that I may lost with it?
Yes, if you're writing a lot of APIs then it becomes tedious typing out both closures. You'll get used to this concept quick enough when other APIs adopt this syntax.
Even though i switched to Web development , still following Brian for the vids
r u using golang for web development?
@@vkray yeah
Are you doing fullstack or just backend?
@@thegeeksides fullstack
Waiting for this! :)
hi ..brain, I interest with your setup hackintosh , can u make video about that....thanks
if you want a smaller better looking mac mini go for nuc8i5bek or nuc10i5
What if we have category key with course name inside each array dict object under array and want to display list of objects based on category using segment selection in single tableview controller ? How can we achieve this ?
Great video man
We can make a generic typealias Completion = (Result) -> ()
and later we can simply use completion: @escaping Completion
if we want to make only one function for decoding and api response
Thank you for that great tutorial
Is it possible to configure Result so that it includes more than just success and error? What if you need a few success objects?
Hi nice tutorial..can you please made tutorial on clean architecture with API request example?
This is funny - I’ve been doing this since Swift 2 with generics, I’ve just been building the Result type myself.
My only problem with the Result approach, which Alamofire uses, is when I want data and an error.
For example, Instagram’s API sets the http status code AND returns JSON. I still want that JSON.
Awesome tutorial 😎
Hey Brian, Thanks for this tutorial. I have a question for you.
I am curious if you have any information on handling the "response" var from the URL session completion. I assume response is the http error, like 200s for success, 400s for client error, etc. Is there much use to handling this response? I am currently building a simple backend with flask and I can return a json and a response code back with each route if I want. Are http responses necessary for mobile development?
You simply check the status code of the response for errors, just like any other error.
Can I call this from a class located in another Swift File? Trying to focus on OOP in Swift.
Oh so they made "native" the result framework we had to import to use alamofire and Moya... Interesting
This video is awesome!!!
I use strict rules for using MVVM, this will break that. Or not?
Try it out and see
Very useful
Hi
What if we need to use Alamofire with responseDecodabl?
Nice tutorial.
I have a question, I am hoping you or someone here can help me. I need to send a POST request to a server that is both json and base64 encoded. The problem being, when I attempt to assign the base64encoded string to the request.httpBody I get the error 'cannot assign value of type String to type Data?'. I have tried using request.httpBody = Data(jsonData!).base64EncodedData(), but the server is getting an empty array and the request fails. I can't find a way to actually send base64 encoded string in a POST request. Any help would be really appreciated. Thank you.
Good stuff
Can you make a tutorial on how to create search UI in table view with API data
Yes, you can find a lesson here www.letsbuildthatapp.com/course_video?id=4662
Hey how do you select these lines so fast with the keyboard at 06:05 ?
Shift + down arrow
I just hold SHIFT and hit DOWN.
@@LetsBuildThatApp Thanks. Can you make a new keyboard shortcut video to just code very fast instead of clicking etc with the trackpad.
I just a mouse and full size keyboard, its much easier than typing on a laptop and trackpad.
Thanks Brian
Nice Tutorial...
It is very helpful thanks
Does this work if success has more than one parameter?
For example with the URLSession completion, it has data and response as “success”
You'll need to wrap the multiple values into your associated value class for the Result.
Lets Build That App oh I see, thank you!
nice and helpfull. Thank you
Have you tried using DispatchGroup to turn callbacks into an async-await style function? It is by far the best way to handle callbacks. So I enjoy the video explaining the new Result type in Swift 5, but I think you should mention that there are better ways to handle callbacks.
I like async-awaits as much as the next guy, it's disappointing that this doesn't come native with Foundation. That being said, the Result type has its place and can diversify your API toolset a lot.
@@LetsBuildThatApp Can you clarify a little bit? I think you could replace any function callback with an async-await style function and make the code more readable using DispatchGroup which is included in Foundation.
The purpose of a dispatch group is to synchronize a group of asynchronous calls and provide a proper callback mechanism when all tasks are finished. Even though they are similar, I wouldn't necessarily conflate DispatchGroup with the async-await pattern.
Out of curiosity, how would you handle the potential errors of 3 async calls using a top down DispatchGroup block of code?
I've written some code in a Playground to share with you, but I am not sure the best way to send it to you. Any ideas?
GitHub link
Hi i am trying to do a NEWS APP and i faced this problem!
Failed to download data: typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array but found a dictionary instead.", underlyingError: nil))
I tried to find nil as i saw some different answers in stack overflow but nothing!
You need to double-check your data model - Looks like you've got it wrong
Look at this for an example - stackoverflow.com/questions/52265674/expected-to-decode-int-but-found-a-string
How can I make it generic?
I start to learn developing IOS apps with Swift. I want to ask something. I always use libraries like 'Moya' or 'Alamofire' to request API. What do you think should i use libraries or is NSURLSession enough ?
Barış Sağlam nsurlsession does its job very well so you can easily use it
Hi,
i am using swift 5, i am beginner to iOS, i am using WKWebview to convert for my web application to iOS app,
in my application i have social login options like facebook and google login, when i successful log In, Facebook login popup or google login page not closing, i need add close button or back button. is it possible, please help me, thanks in advance.
Thanks a lot
Nice!
We can already do this in swift 4.2 .. Result
Awesome
hi
When i import Alamofire and try "Result" . I have got an error
Generic type 'Result' specialized with too many type parameters (got 2, but expected 1).
when i delete Alamofire Import there is no problem ?
This is because it's using Alamofire's Result class, instead of native UIKit version. It took me a while to figure this out too.
How generic work with result type
nice
Its definitely a lot cleaner but it almost seems like its performing the same task (as in checking if an error is present and reporting nothing) still interesting nonetheless!!
It’s a rather subtle difference but definitely a good one.
roulette app tutorial
This new features remind that how Vue.js do the REST, basically that's the same idea.
It’s not compatible with Objective-C unfortunately.
Indeed, objc is great but lacks modern programming language features.
Great video but I think reverb is unnecessary. I vote for no reverb. Thanks
New mic, getting used to how to adjust the sound but will tone down the post processing.
@@LetsBuildThatApp Brian.... I would suggest using only compression and eq during post. I am a believer that reverb on vocals should be reserved for songs only. But that's just me. Good luck!
this doesn't work if you are already using Generic types for your decoding. like completion( Result) you need to mention the class you are decoding like Result, too bad
It still works, you just need to specify the result type in your closure block.
@@LetsBuildThatApp hey thanks for the reply, I actually imported Alamofire also in that same class and it was picking up Alamofire’s Result instead of Apple’s Result Enum, removing Alamofire import solved it for me
Thanks but I can't get this tutorial, its very long and breathtaking!
Who is this man which put dislike to this video? 🤣🤣🤣
Anyone who is from a nodeJs or Python background will dislike this(language not this video) for its verbosity.
Thanks for the video, Brian. the more it goes, the less I find swift easier to read or to use compared to Obj-C. I think I'm a dino!
Thank you for sharing this, Brian! Great explanation as well :-) What should I do with the completion call to make my fetchUsers function below work?
fileprivate func fetchGenericJSONData(urlString: String, completion: @escaping (Result) -> ()) {
guard let url = Bundle.main.url(forResource: urlString, withExtension: "json") else { return }
if let data = try? Data(contentsOf: url) {
do {
let objects = try JSONDecoder().decode(T.self, from: data)
completion(.success(objects))
} catch let jsonError {
completion(.failure(jsonError))
}
}
}
func fetchUsers(completion: @escaping ([User]?, Error?) -> ()) {
fetchGenericJSONData(urlString: "Users", completion: completion)
}
Forget I asked :-P had to add the same Result type to the other function and remove the optional Error.
@@Dennisvm82 Hi I am also facing the issue while using Result type in generic types can you share the code how is it working..
@@pradeepkumar-tm5et Hi Pradeep! Check out my code below :-) I am working with local JSON files for testing purposes, so my generic function is a little bit different. The parameters should be the same I believe. I hope my code can help you out!
func fetchUsers(completion: @escaping (Result) -> ()) {
fetchGenericJSONData(urlString: "Users", completion: completion)
}
fileprivate func fetchGenericJSONData(urlString: String, completion: @escaping (Result) -> ()) {
guard let url = Bundle.main.url(forResource: urlString, withExtension: "json") else { return }
if let data = try? Data(contentsOf: url) {
do {
let objects = try JSONDecoder().decode(T.self, from: data)
completion(.success(objects))
} catch let jsonError {
completion(.failure(jsonError))
}
}
}
fileprivate func fetchUserData() {
Service.shared.fetchUsers { (result) in
switch result {
case .success(let user):
self.userViewModel = user ?? []
case .failure(let err):
print("Failed to fetch data:", err)
}
}
}
@@Dennisvm82 Than you very much. You have resolved my issue...
@@pradeepkumar-tm5et You are welcome :-)
You don’t type faster. you just type which happens to be fast.😁
Yeah, I just can't stand slow typers when I watch tutorials.
Thank you Brian for this tutorial.
Great video, as always