Post

Replies

Boosts

Views

Activity

Reply to Showing Alert or Sheet after Some Delay?
I've figured out a way of doing it with StateObject. It's something like the following. import SwiftUI import Combine struct ContentView2: View { @State var disabled: Bool = false @StateObject var delayMonitor = DelayMonitor() @State private var showingAlert = false var body: some View { VStack { Spacer() Button("Tap to connect me") { disabled = true delayMonitor.start() } .font(.system(size: 24.0)) .disabled(disabled) Spacer() .frame(height: 30.0) }.onChange(of: delayMonitor.failed) { newValue in print("You've failed?: \(newValue)") disabled = !newValue showingAlert = newValue } .alert("Something is wrong...", isPresented: $showingAlert) { Button("OK", role: .cancel) { } } } } class DelayMonitor: ObservableObject { var timer = Timer() var seconds: Double = 0.0 @Published var failed: Bool = false func start() { timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { _ in self.seconds += 1.0 if self.seconds == 5.0 { // arbitrary timeout self.timer.invalidate() DispatchQueue.main.async() { [weak self] in guard let strongSelf = self else { return } strongSelf.failed = true } } }) } } The onChange guy will let me know only if the value (delayMonitor.failed) has changed. Since its initial value is set to false, I'll get a call only if it changes to true.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jan ’22
Reply to Publishers.CombineLatest in SwiftUI
I guess ObservableObject is a ticket to using Combine in SwiftUI. So I can write the following. import SwiftUI import Combine struct ContentView: View { @State var cancellables = Set<AnyCancellable>() @StateObject var login = Login() @State var canSave: Bool = false var body: some View { VStack { Text("Login") TextField("Enter username", text: $login.user) TextField("Enter password", text: $login.pass) Button("Save") { } .foregroundColor(canSave ? Color.orange : Color.gray) .font(.system(size: 40.0)) .disabled(!canSave) } .padding(.horizontal, 40.0) .onAppear { Publishers.CombineLatest(login.$user, login.$pass) .sink { completion in print(completion) } receiveValue: { (result0, result1) in let bool = (result0.count > 3 && result1.count > 3) canSave = bool }.store(in: &cancellables) } } } class Login: ObservableObject { @Published var user: String = "" @Published var pass: String = "" } This is really good stuff.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jan ’22
Reply to Publishers.CombineLatest in SwiftUI
I could do something like the following. class ValidateLogin { var good: Bool = false let user: String let pass: String init(user: String, pass: String) { self.user = user self.pass = pass } func validateMe() -> Bool { if user.count > 3 && pass.count > 3 { good = true } return good } } struct ContentView: View { @State var userText: String = "" @State var passText: String = "" @State var canSave: Bool = false var body: some View { ZStack { VStack { TextField("Username", text: $userText) { }.onChange(of: userText) { newValue in let validateLogin = ValidateLogin(user: userText, pass: passText) canSave = validateLogin.validateMe() } SecureField("Password", text: $passText) { }.onChange(of: passText) { newValue in let validateLogin = ValidateLogin(user: userText, pass: passText) canSave = validateLogin.validateMe() } }.padding(.horizontal, 20.0) }.onAppear { //Publishers.CombineLatest($userText, $passText) } } } The code above doesn't involve Combine at all. I want to do it in a Combine way.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jan ’22
Reply to Horizontal List with NavigationView and NavigationLink
I've solved the problem by having NavigationView before ScrollView like the following. ZStack { VStack { NavigationView { ScrollView(.horizontal, showsIndicators: false) { HStack(alignment: .top, spacing: 0) { ForEach(horizonModels, id: \.self) { model in if model.id == 0 { NavigationLink(model.name) { MenuView0() } .font(.system(size: 20.0)) .padding(.horizontal, 20.0) .foregroundColor(Color.white) } else { NavigationLink(model.name) { MenuView1() } .font(.system(size: 20.0)) .padding(.horizontal, 20.0) .foregroundColor(Color.white) } } } } .frame(height: 40.0) .background(Color.orange) } } } That's kind of odd to me.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Dec ’21
Reply to Sign in with Apple not working on Xcode 13 simulators
I've tested my sample app with Apple Sign In with two simulators. They don't go further after I enter my password. When I tested it for a macOS application two weeks ago, I ended up restarting my iMac. The same is true for an iOS sample that I created at the same time. I had to restart my iPhone. Anyway, in your case, I wouldn't be worried as long as it works on an actual device. Some features simply don't work with the simulator.
Topic: App & System Services SubTopic: General Tags:
Dec ’21
Reply to Using Combine-Future to Fetch Server Data
I guess the following is better. But I'm not completely satisfied. // ViewController // import UIKit import Combine class ViewController: UIViewController { // MARK: - Variables var cancellable: AnyCancellable? private var cancellableSet: Set<AnyCancellable> = [] // MARK: - Life cycle override func viewDidLoad() { super.viewDidLoad() let urlStr = "https://api.github.com/repos/ReactiveX/RxSwift/events" let viewModel = ViewModel(urlStr: urlStr, waitTime: 7.0) viewModel.fetchData(urlText: viewModel.urlStr, timeInterval: viewModel.waitTime) .sink { completion in print("Done!") } receiveValue: { dataModels in print("Count: \(dataModels.count)") } .store(in: &cancellableSet) } } // ViewModel // import UIKit import Combine class ViewModel { var anycancellables = Set<AnyCancellable>() var urlStr: String var waitTime: Double init(urlStr: String, waitTime: Double) { self.urlStr = urlStr self.waitTime = waitTime } func fetchData(urlText: String, timeInterval: Double) -> Future<[DataModel], Error> { return Future<[DataModel], Error> { promise in let url = URL(string: urlText)! var request = URLRequest(url: url) request.timeoutInterval = timeInterval let sessionConfiguration = URLSessionConfiguration.default let session = URLSession(configuration: sessionConfiguration) session.dataTask(with: request) { data, response, error in if let error = error { print("error: \(error.localizedDescription)") promise(.failure("Failure" as! Error)) } if let jsonData = data { do { let dataModels = try JSONDecoder().decode([DataModel].self, from: jsonData) promise(.success(dataModels)) } catch { print("Error while parsing: \(error)") } } }.resume() } } }
Topic: UI Frameworks SubTopic: UIKit Tags:
Dec ’21
Reply to Using Combine-Future to Fetch Server Data
The following works. import UIKit import Combine class ViewController: UIViewController { // MARK: - Variables private var cancellableSet: Set<AnyCancellable> = [] override func viewDidLoad() { super.viewDidLoad() let _ = Future<[DataModel], Error> { [weak self] promise in guard let strongSelf = self else { return } let url = URL(string: "https://api.github.com/repos/ReactiveX/RxSwift/events")! URLSession.shared.dataTaskPublisher(for: url) .timeout(2.0, scheduler: DispatchQueue.global(qos: .background)) .retry(3) .map { $0.data } .decode(type: [DataModel].self, decoder: JSONDecoder()) .sink(receiveCompletion: { (completion) in print("I'm done: \(completion)") }, receiveValue: { dataModels in for model in dataModels { print("\(model.id) \(model.type)") } promise(.success(dataModels)) }) .store(in: &strongSelf.cancellableSet) } } } I wonder why it doesn't work if I use ViewModel?
Topic: UI Frameworks SubTopic: UIKit Tags:
Dec ’21
Reply to UILabel with superscript text
override func viewDidLoad() { super.viewDidLoad() let text = "1:47PM" if let regularFont = UIFont(name: "Helvetica", size: 20.0), let subscriptFont = UIFont(name: "TamilSangamMN", size: 12.0) { let attString:NSMutableAttributedString = NSMutableAttributedString(string: text, attributes: [.font: regularFont]) attString.setAttributes([.font: subscriptFont, .baselineOffset: 6], range: NSRange(location: text.count - 2, length: 2)) label.attributedText = attString } }
Topic: Programming Languages SubTopic: Swift Tags:
Nov ’21
Reply to Combining More Than Four @Published Variables in Combine?
I guess it goes like the following. Publishers.CombineLatest4($variable0, $variable1, $variable2, $variable3) .combineLatest($variable4) .combineLatest($variable5) .sink { completion in } receiveValue: { response0, response1 in let variable = response0.0 let variable4 = response0.1 let variable5 = response1 let v0 = variable.0 let v1 = variable.1 let v2 = variable.2 let v3 = variable.3 }.store(in: &cancellables) It's kind of odd.
Topic: UI Frameworks SubTopic: UIKit Tags:
Nov ’21
Reply to Showing Alert or Sheet after Some Delay?
I've figured out a way of doing it with StateObject. It's something like the following. import SwiftUI import Combine struct ContentView2: View { @State var disabled: Bool = false @StateObject var delayMonitor = DelayMonitor() @State private var showingAlert = false var body: some View { VStack { Spacer() Button("Tap to connect me") { disabled = true delayMonitor.start() } .font(.system(size: 24.0)) .disabled(disabled) Spacer() .frame(height: 30.0) }.onChange(of: delayMonitor.failed) { newValue in print("You've failed?: \(newValue)") disabled = !newValue showingAlert = newValue } .alert("Something is wrong...", isPresented: $showingAlert) { Button("OK", role: .cancel) { } } } } class DelayMonitor: ObservableObject { var timer = Timer() var seconds: Double = 0.0 @Published var failed: Bool = false func start() { timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { _ in self.seconds += 1.0 if self.seconds == 5.0 { // arbitrary timeout self.timer.invalidate() DispatchQueue.main.async() { [weak self] in guard let strongSelf = self else { return } strongSelf.failed = true } } }) } } The onChange guy will let me know only if the value (delayMonitor.failed) has changed. Since its initial value is set to false, I'll get a call only if it changes to true.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jan ’22
Reply to Publishers.CombineLatest in SwiftUI
I guess ObservableObject is a ticket to using Combine in SwiftUI. So I can write the following. import SwiftUI import Combine struct ContentView: View { @State var cancellables = Set<AnyCancellable>() @StateObject var login = Login() @State var canSave: Bool = false var body: some View { VStack { Text("Login") TextField("Enter username", text: $login.user) TextField("Enter password", text: $login.pass) Button("Save") { } .foregroundColor(canSave ? Color.orange : Color.gray) .font(.system(size: 40.0)) .disabled(!canSave) } .padding(.horizontal, 40.0) .onAppear { Publishers.CombineLatest(login.$user, login.$pass) .sink { completion in print(completion) } receiveValue: { (result0, result1) in let bool = (result0.count > 3 && result1.count > 3) canSave = bool }.store(in: &cancellables) } } } class Login: ObservableObject { @Published var user: String = "" @Published var pass: String = "" } This is really good stuff.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jan ’22
Reply to Publishers.CombineLatest in SwiftUI
I could do something like the following. class ValidateLogin { var good: Bool = false let user: String let pass: String init(user: String, pass: String) { self.user = user self.pass = pass } func validateMe() -> Bool { if user.count > 3 && pass.count > 3 { good = true } return good } } struct ContentView: View { @State var userText: String = "" @State var passText: String = "" @State var canSave: Bool = false var body: some View { ZStack { VStack { TextField("Username", text: $userText) { }.onChange(of: userText) { newValue in let validateLogin = ValidateLogin(user: userText, pass: passText) canSave = validateLogin.validateMe() } SecureField("Password", text: $passText) { }.onChange(of: passText) { newValue in let validateLogin = ValidateLogin(user: userText, pass: passText) canSave = validateLogin.validateMe() } }.padding(.horizontal, 20.0) }.onAppear { //Publishers.CombineLatest($userText, $passText) } } } The code above doesn't involve Combine at all. I want to do it in a Combine way.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jan ’22
Reply to Horizontal List with NavigationView and NavigationLink
I've solved the problem by having NavigationView before ScrollView like the following. ZStack { VStack { NavigationView { ScrollView(.horizontal, showsIndicators: false) { HStack(alignment: .top, spacing: 0) { ForEach(horizonModels, id: \.self) { model in if model.id == 0 { NavigationLink(model.name) { MenuView0() } .font(.system(size: 20.0)) .padding(.horizontal, 20.0) .foregroundColor(Color.white) } else { NavigationLink(model.name) { MenuView1() } .font(.system(size: 20.0)) .padding(.horizontal, 20.0) .foregroundColor(Color.white) } } } } .frame(height: 40.0) .background(Color.orange) } } } That's kind of odd to me.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Dec ’21
Reply to Sign in with Apple not working on Xcode 13 simulators
I've tested my sample app with Apple Sign In with two simulators. They don't go further after I enter my password. When I tested it for a macOS application two weeks ago, I ended up restarting my iMac. The same is true for an iOS sample that I created at the same time. I had to restart my iPhone. Anyway, in your case, I wouldn't be worried as long as it works on an actual device. Some features simply don't work with the simulator.
Topic: App & System Services SubTopic: General Tags:
Replies
Boosts
Views
Activity
Dec ’21
Reply to Using Combine-Future to Fetch Server Data
I guess the following is better. But I'm not completely satisfied. // ViewController // import UIKit import Combine class ViewController: UIViewController { // MARK: - Variables var cancellable: AnyCancellable? private var cancellableSet: Set<AnyCancellable> = [] // MARK: - Life cycle override func viewDidLoad() { super.viewDidLoad() let urlStr = "https://api.github.com/repos/ReactiveX/RxSwift/events" let viewModel = ViewModel(urlStr: urlStr, waitTime: 7.0) viewModel.fetchData(urlText: viewModel.urlStr, timeInterval: viewModel.waitTime) .sink { completion in print("Done!") } receiveValue: { dataModels in print("Count: \(dataModels.count)") } .store(in: &cancellableSet) } } // ViewModel // import UIKit import Combine class ViewModel { var anycancellables = Set<AnyCancellable>() var urlStr: String var waitTime: Double init(urlStr: String, waitTime: Double) { self.urlStr = urlStr self.waitTime = waitTime } func fetchData(urlText: String, timeInterval: Double) -> Future<[DataModel], Error> { return Future<[DataModel], Error> { promise in let url = URL(string: urlText)! var request = URLRequest(url: url) request.timeoutInterval = timeInterval let sessionConfiguration = URLSessionConfiguration.default let session = URLSession(configuration: sessionConfiguration) session.dataTask(with: request) { data, response, error in if let error = error { print("error: \(error.localizedDescription)") promise(.failure("Failure" as! Error)) } if let jsonData = data { do { let dataModels = try JSONDecoder().decode([DataModel].self, from: jsonData) promise(.success(dataModels)) } catch { print("Error while parsing: \(error)") } } }.resume() } } }
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
Boosts
Views
Activity
Dec ’21
Reply to Using Combine-Future to Fetch Server Data
I've removed the comment.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
Boosts
Views
Activity
Dec ’21
Reply to Using Combine-Future to Fetch Server Data
The following works. import UIKit import Combine class ViewController: UIViewController { // MARK: - Variables private var cancellableSet: Set<AnyCancellable> = [] override func viewDidLoad() { super.viewDidLoad() let _ = Future<[DataModel], Error> { [weak self] promise in guard let strongSelf = self else { return } let url = URL(string: "https://api.github.com/repos/ReactiveX/RxSwift/events")! URLSession.shared.dataTaskPublisher(for: url) .timeout(2.0, scheduler: DispatchQueue.global(qos: .background)) .retry(3) .map { $0.data } .decode(type: [DataModel].self, decoder: JSONDecoder()) .sink(receiveCompletion: { (completion) in print("I'm done: \(completion)") }, receiveValue: { dataModels in for model in dataModels { print("\(model.id) \(model.type)") } promise(.success(dataModels)) }) .store(in: &strongSelf.cancellableSet) } } } I wonder why it doesn't work if I use ViewModel?
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
Boosts
Views
Activity
Dec ’21
Reply to UILabel with superscript text
override func viewDidLoad() { super.viewDidLoad() let text = "1:47PM" if let regularFont = UIFont(name: "Helvetica", size: 20.0), let subscriptFont = UIFont(name: "TamilSangamMN", size: 12.0) { let attString:NSMutableAttributedString = NSMutableAttributedString(string: text, attributes: [.font: regularFont]) attString.setAttributes([.font: subscriptFont, .baselineOffset: 6], range: NSRange(location: text.count - 2, length: 2)) label.attributedText = attString } }
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Nov ’21
Reply to Where do I start?
You should start by reading the Swift Programming Language.
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Nov ’21
Reply to Getting ignored by support
Call them up?
Replies
Boosts
Views
Activity
Nov ’21
Reply to Alnahda Dubai (Call) Girls +971589930402
Don't you have something else to have fun?
Replies
Boosts
Views
Activity
Nov ’21
Reply to Hottest 0529579100 Dubai Call Girls, Indian Call Girls in Dubai
Are you having fun?
Replies
Boosts
Views
Activity
Nov ’21
Reply to Combining More Than Four @Published Variables in Combine?
I guess it goes like the following. Publishers.CombineLatest4($variable0, $variable1, $variable2, $variable3) .combineLatest($variable4) .combineLatest($variable5) .sink { completion in } receiveValue: { response0, response1 in let variable = response0.0 let variable4 = response0.1 let variable5 = response1 let v0 = variable.0 let v1 = variable.1 let v2 = variable.2 let v3 = variable.3 }.store(in: &cancellables) It's kind of odd.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
Boosts
Views
Activity
Nov ’21
Reply to Combining More Than Four @Published Variables in Combine?
I thought let publishers = Publishers.CombineLatest4($variable0, $variable1, $variable2, $variable3) .combineLatest($variable4) .combineLatest($variable5) could work. But it doesn't.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
Boosts
Views
Activity
Nov ’21