1656393360
Features | |
---|---|
🦄 powerful primitives | Future , Promise , Channel , Producer , Sink , Cache , ... |
🤘 versatile transformations | map , filter , recover , debounce , distinct , ... |
✌️ convenient combination | flatMap , merge , zip , sample , scan , reduce , ... |
🙌 improves existing things | Key-Value Observing, target-action, notifications, bindings |
🍳 less boilerplate code | neat cancellation, threading, memory manament |
🕶 extendable | powerful extensions for URLSession , UI controls, CoreData , ... |
🍱 all platforms | 🖥 macOS 10.10+ 📱 iOS 8.0+ 📺 tvOS 9.0+ ⌚️ watchOS 2.0+ 🐧 Linux |
🤓 documentation | 100% + sample code, see full documentation |
🔩 simple integration | SPM, CocoaPods, Carthage |
let searchResults = searchBar.rp.text
.debounce(interval: 0.3)
.distinct()
.flatMap(behavior: .keepLatestTransform) { (query) -> Future<[SearchResult]> in
return query.isEmpty
? .just([])
: searchGitHub(query: query).recover([])
}
.observeOn(MainScheduler.instance)
and .disposed(by: disposeBag)
class MyViewController: UIViewController {
/* ... */
@IBOutlet weak var myLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
UIDevice.current.rp.orientation
.map { $0.description }
.bind(myLabel.rp.text)
}
/* ... */
}
[weak self]
DispatchQueue.main.async { ... }
.observeOn(MainScheduler.instance)
class MyViewController: NSViewController {
let service: MyService
/* ... */
func fetchAndPresentItems(for request: Request) {
service.perform(request: request)
.map(context: self, executor: .primary) { (self, response) in
return self.items(from: response)
}
.onSuccess(context: self) { (self, items) in
self.present(items: items)
}
.onFailure(context: self) { (self, error) in
self.present(error: error)
}
}
func items(from response: Response) throws -> [Items] {
/* ... extract items from response ... */
}
func present(items: [Items]) {
/* ... update UI ... */
}
}
class MyService {
func perform(request: Request) -> Future<Response> {
/* ... */
}
}
Let's assume that we have:
Person
is an example of a struct that contains information about the person.MyService
is an example of a class that serves as an entry point to the model. Works in a background.MyViewController
is an example of a class that manages UI-related instances. Works on the main queue.extension MyViewController {
func present(personWithID identifier: String) {
myService.fetch(personWithID: identifier) {
(person, error) in
/* do not forget to dispatch to the main queue */
DispatchQueue.main.async {
/* do not forget the [weak self] */
[weak self] in
guard let strongSelf = self
else { return }
if let person = person {
strongSelf.present(person: person)
} else if let error = error {
strongSelf.present(error: error)
} else {
fatalError("There is neither person nor error. What has happened to this world?")
}
}
}
}
}
extension MyService {
func fetch(personWithID: String, callback: @escaping (Person?, Error?) -> Void) {
/* ... */
}
}
extension MyViewController {
func present(personWithID identifier: String) {
myService.fetch(personWithID: identifier)
/* do not forget to dispatch to the main queue */
.onComplete(executor: .main) {
/* do not forget the [weak self] */
[weak self] (completion) in
if let strongSelf = self {
completion.onSuccess(strongSelf.present(person:))
completion.onFailure(strongSelf.present(error:))
}
}
}
}
extension MyService {
func fetch(personWithID: String) -> Future<Person> {
/* ... */
}
}
extension MyViewController {
func present(personWithID identifier: String) {
myService.fetch(personWithID: identifier)
.onSuccess(context: self) { (self, person) in
self.present(person: person)
}
.onFailure(context: self) { (self, error) in
self.present(error: error)
}
}
}
extension MyService {
func fetch(personWithID: String) -> Future<Person> {
/* ... */
}
}
Let's assume that we have function that finds all prime numbers lesser than n
func primeNumbers(to n: Int) -> [Int] { /* ... */ }
let futurePrimeNumbers: Future<[Int]> = future { primeNumbers(to: 10_000_000) }
let futureSquaredPrimeNumbers = futurePrimeNumbers
.map { (primeNumbers) -> [Int] in
return primeNumbers.map { (number) -> Int
return number * number
}
}
if let fallibleNumbers = futurePrimeNumbers.wait(seconds: 1.0) {
print("Number of prime numbers is \(fallibleNumbers.success?.count)")
} else {
print("Did not calculate prime numbers yet")
}
futurePrimeNumbers.onComplete { (falliblePrimeNumbers) in
print("Number of prime numbers is \(falliblePrimeNumbers.success?.count)")
}
let futureA: Future<A> = /* ... */
let futureB: Future<B> = /* ... */
let futureC: Future<C> = /* ... */
let futureABC: Future<(A, B, C)> = zip(futureA, futureB, futureC)
class MyService {
/* implementation */
func fetchPerson(withID personID: Person.Identifier) -> Future<Person> {
let promise = Promise<Person>()
self.fetchPerson(withID: personID, callback: promise.complete)
return promise
}
}
class MyService {
/* implementation */
func fetchPerson(withID personID: Person.Identifier,
callback: @escaping (Fallible<Person>) -> Void) {
self.fetchPerson(withID: personID)
.onComplete(callback)
}
}
Let's assume we have function that returns channel of prime numbers: sends prime numbers as finds them and sends number of found numbers as completion
func makeChannelOfPrimeNumbers(to n: Int) -> Channel<Int, Int> { /* ... */ }
let channelOfSquaredPrimeNumbers = channelOfPrimeNumbers
.map { (number) -> Int in
return number * number
}
for number in channelOfPrimeNumbers {
print(number)
}
if let fallibleNumberOfPrimes = channelOfPrimeNumbers.wait(seconds: 1.0) {
print("Number of prime numbers is \(fallibleNumberOfPrimes.success)")
} else {
print("Did not calculate prime numbers yet")
}
let (primeNumbers, numberOfPrimeNumbers) = channelOfPrimeNumbers.waitForAll()
channelOfPrimeNumbers.onUpdate { print("Update: \($0)") }
channelOfPrimeNumbers.onComplete { print("Completed: \($0)") }
Channel
func makeChannelOfPrimeNumbers(to n: Int) -> Channel<Int, Int> {
return channel { (update) -> Int in
var numberOfPrimeNumbers = 0
var isPrime = Array(repeating: true, count: n)
for number in 2..<n where isPrime[number] {
numberOfPrimeNumbers += 1
update(number)
// updating seive
var seiveNumber = number + number
while seiveNumber < n {
isPrime[seiveNumber] = false
seiveNumber += number
}
}
return numberOfPrimeNumbers
}
}
Author: AsyncNinja
Source Code: https://github.com/AsyncNinja/AsyncNinja
License: MIT license
1600430400
Swift is a fast and efficient general-purpose programming language that provides real-time feedback and can be seamlessly incorporated into existing Objective-C code. This is why developers are able to write safer, more reliable code while saving time. It aims to be the best language that can be used for various purposes ranging from systems programming to mobile as well as desktop apps and scaling up to cloud services.
Below here, we list down the 10 best online resources to learn Swift language.
(The list is in no particular order)
#developers corner #free online resources to learn swift language #learn swift #learn swift free #learn swift online free #resources to learn swift #swift language #swift programming
1609999986
A thoroughly researched list of top Swift developers with ratings & reviews to help find the best Swift development companies around the world.
#swift development service providers #best swift development companies #top swift development companies #swift development solutions #top swift developers #swift
1594193714
Want to create a native iOS application for your Startup?
Hire Dedicated Swift Developers for end-to-end services like development, migration, upgrade, testing, and support & maintenance. Trust HourlyDeveloper.io our Swift development team for iOS device apps that are high on performance and security.
Consult with experts:- https://bit.ly/2C5M6cz
#hire dedicated swift developers #swift developers #swift development company #swift development services #swift development #swift
1602151260
Here is a list of four fun reasons you should avoid using data types such as Int
and String
to pass along and process the data in your Swift code. And a list of alternatives to use instead, so you can write much better code with just a few small changes to your current habits.
Note: I’ll troll around a bit because technical articles can be boring.
Note that I use the word Fun in a slightly sarcastic way, as in: “Losing is Fun”.
When you see a function definition like this one, do you instantly know what both of the String
will actually be?
func getData(for identifier: String) -> String {
Here, String
can be anything, both the input String
and the output String
. If you’re developing the code alone, you will probably remember what is the typical content of those two.
I say probably, because as any developer knows — by Monday you may not remember what the code written on Friday does. It’s something I can promise you. Give this project a few months of a break and it will be easier for you to write the thing from scratch than to try to understand “what the poet had in mind”.
To (try to) ensure the inputs and outputs stay at least a bit clear, you will need to add comments to explain the details of what you expect those Strings to actually contain.
From the above function definition alone we only know we’re looking for some identifier. We may understand from the context of the app what that may be, but what is the result of this function exactly?
Will it give us some kind of person’s name? Or maybe a large chunk of JSON data? Maybe a specific number of animal emojis such as a 🐐 and a 🐠? For no reason. But a String
can be all those, so make sure that your code will handle every possible case now. I think you see my point.
In reality, nobody knows what those are until they check the actual code of the function.
We have powerful IDEs (such as Xcode), which provide developers with previews of possible completions. They are useless in this case. Imagine what you would think if you were working on someone else’s code and you stumbled upon the above definition as an Xcode suggestion. My guess is: some rude words will be included in your reaction.
You can’t understand what is happening until you check the code or documentation. And chances are, if you see this kind of String
usage, you won’t find any docs for that package or pod or repository. **And also, most docs can’t be trusted because we don’t like to write docs, maintain docs and keep up with the changes in the code. **There is nothing that would force developers to keep the docs and comments in sync.
#swift #swift-programming #programming-languages #ios-app-development #programming
1600095600
To start explaining the microservices it’s useful to compare it to the monolithic application. An application is said to be a monolith when it is deployed as a single unit. Monoliths have a single shared database. They communicate with synchronous method calls where you send a message and expect a response immediately.
#reactive-systems #reactive-microservice #reactive-programming #reactive-architecture