Skip to content

Instantly share code, notes, and snippets.

@florentmorin
Last active July 16, 2020 15:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save florentmorin/6b466b44ffb85a97c07337c8515546be to your computer and use it in GitHub Desktop.
Save florentmorin/6b466b44ffb85a97c07337c8515546be to your computer and use it in GitHub Desktop.
Affichage d'un élément de TodoList depuis le web
import Foundation
import SwiftUI
import Combine
struct Todo: Codable {
let userId: Int
let id: Int
let title: String
let completed: Bool
}
struct TodoView: View {
@State var title: String = "Loading..."
var body: some View {
Text($title.wrappedValue)
.onReceive(buildPublisher()) { title in
self.title = title
}
}
private func buildPublisher() -> AnyPublisher<String, Never> {
let url = URL(string: "https://jsonplaceholder.typicode.com/todos/1")!
return URLSession.shared
.dataTaskPublisher(for: url)
.tryMap { $0.data }
.decode(type: Todo.self, decoder: JSONDecoder())
.compactMap { $0.title }
.replaceError(with: "Error!")
.eraseToAnyPublisher()
}
}
import Foundation
import UIKit
import Combine
struct Todo: Codable {
let userId: Int
let id: Int
let title: String
let completed: Bool
}
class TodoViewController : UIViewController {
let label = UILabel()
var cancellable: AnyCancellable?
override func loadView() {
super.loadView()
let view = UIView()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.textAlignment = .center
label.text = "Loading..."
view.addSubview(label)
label.centerYAnchor
.constraint(equalTo: view.centerYAnchor)
.isActive = true
label.centerXAnchor
.constraint(equalTo: view.centerXAnchor)
.isActive = true
label.widthAnchor
.constraint(lessThanOrEqualTo: view.layoutMarginsGuide.widthAnchor)
.isActive = true
label.heightAnchor
.constraint(lessThanOrEqualTo: view.layoutMarginsGuide.heightAnchor)
.isActive = true
self.view = view
}
private func loadData() {
let url = URL(string: "https://jsonplaceholder.typicode.com/todos/1")!
cancellable = URLSession.shared
.dataTaskPublisher(for: url)
.tryMap { $0.data }
.decode(type: Todo.self, decoder: JSONDecoder())
.compactMap { $0.title }
.replaceError(with: "Error!")
.receive(on: DispatchQueue.main)
.assign(to: \.text, on: label)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
loadData()
}
}
@import Foundation;
@import UIKit;
@import JSONModel;
@interface Todo : JSONModel
@property (nonatomic) NSInteger userId;
@property (nonatomic) NSInteger id;
@property (nonatomic) NSString *title;
@property (nonatomic) BOOL completed;
@end
@implementation Todo
@end
@interface TodoViewController : UIViewController
@property (nonatomic, strong) UILabel *label;
@end
@implementation TodoViewController
- (void)loadView {
[super loadView];
UIView *view = [[UIView alloc] init];
UILabel *label = [[UILabel alloc] init];
label.translatesAutoresizingMaskIntoConstraints = NO;
label.numberOfLines = 0;
label.textAlignment = NSTextAlignmentCenter;
label.text = @"Loading...";
[view addSubview:label];
[label.centerYAnchor constraintEqualToAnchor:view.centerYAnchor].active = YES;
[label.centerXAnchor constraintEqualToAnchor:view.centerXAnchor].active = YES;
[label.widthAnchor constraintLessThanOrEqualToAnchor:view.layoutMarginsGuide.widthAnchor].active = YES;
[label.heightAnchor constraintLessThanOrEqualToAnchor:view.layoutMarginsGuide.heightAnchor].active = YES;
self.label = label;
self.view = view;
}
- (void)loadData {
NSURL *url = [NSURL URLWithString:@"https://jsonplaceholder.typicode.com/todos/1"];
[[NSURLSession.sharedSession dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (data == nil) {
dispatch_async(dispatch_get_main_queue(), ^{
self.label.text = @"Error!";
});
return;
}
Todo *todo = [[Todo alloc] initWithData:data error:nil];
if (todo == nil) {
dispatch_async(dispatch_get_main_queue(), ^{
self.label.text = @"Error!";
});
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
self.label.text = todo.title;
});
}] resume];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self loadData];
}
@end
import Foundation
import UIKit
struct Todo: Codable {
let userId: Int
let id: Int
let title: String
let completed: Bool
}
final class TodoViewController: UIViewController {
let label = UILabel()
override func loadView() {
super.loadView()
let view = UIView()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.textAlignment = .center
label.text = "Loading..."
view.addSubview(label)
label.centerYAnchor
.constraint(equalTo: view.centerYAnchor)
.isActive = true
label.centerXAnchor
.constraint(equalTo: view.centerXAnchor)
.isActive = true
label.widthAnchor
.constraint(lessThanOrEqualTo: view.layoutMarginsGuide.widthAnchor)
.isActive = true
label.heightAnchor
.constraint(lessThanOrEqualTo: view.layoutMarginsGuide.heightAnchor)
.isActive = true
self.view = view
}
private func loadData() {
let url = URL(string: "https://jsonplaceholder.typicode.com/todos/1")!
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data else {
DispatchQueue.main.async {
self.label.text = "Error!"
}
return
}
guard let todo = try? JSONDecoder().decode(Todo.self, from: data) else {
DispatchQueue.main.async {
self.label.text = "Error!"
}
return
}
DispatchQueue.main.async {
self.label.text = todo.title
}
}.resume()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.loadData()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment