diff --git a/Example/SwifttorExample/Podfile.lock b/Example/SwifttorExample/Podfile.lock index f0499c5..6e6da70 100644 --- a/Example/SwifttorExample/Podfile.lock +++ b/Example/SwifttorExample/Podfile.lock @@ -11,7 +11,7 @@ EXTERNAL SOURCES: CHECKOUT OPTIONS: Swifttor: - :commit: 999302b5a6ebcd776cfc417c7311ba01d5c48053 + :commit: e38b8500900f0ace7a1929407ac5bed8bea7e9b5 :git: https://github.com/josete89/swifttor.git SPEC CHECKSUMS: diff --git a/Example/SwifttorExample/Pods/Manifest.lock b/Example/SwifttorExample/Pods/Manifest.lock index f0499c5..6e6da70 100644 --- a/Example/SwifttorExample/Pods/Manifest.lock +++ b/Example/SwifttorExample/Pods/Manifest.lock @@ -11,7 +11,7 @@ EXTERNAL SOURCES: CHECKOUT OPTIONS: Swifttor: - :commit: 999302b5a6ebcd776cfc417c7311ba01d5c48053 + :commit: e38b8500900f0ace7a1929407ac5bed8bea7e9b5 :git: https://github.com/josete89/swifttor.git SPEC CHECKSUMS: diff --git a/Example/SwifttorExample/Pods/Swifttor/Swifttor/Actor.swift b/Example/SwifttorExample/Pods/Swifttor/Swifttor/Actor.swift index cf49bc4..0ab0d79 100644 --- a/Example/SwifttorExample/Pods/Swifttor/Swifttor/Actor.swift +++ b/Example/SwifttorExample/Pods/Swifttor/Swifttor/Actor.swift @@ -24,10 +24,10 @@ public protocol ActorTell: Actor { public protocol ActorAsk: Actor { associatedtype ResultType - func reiciveAsk(message:MessageType) -> ResultType + func reiciveAsk(message:MessageType,completion:@escaping(ResultType)->()) } -extension Actor { +public extension Actor { var queue:DispatchQueue { return DispatchQueue(label: "com.josete89.swifttor.\(name)") @@ -57,8 +57,7 @@ extension ActorAsk { func putPromise(message:MessageType) -> Future { return Future(compute: { (completion) in self.queue.async(execute: { - let result = self.reiciveAsk(message: message) - completion(result) + self.reiciveAsk(message: message,completion: completion) }) }) } diff --git a/Example/SwifttorExample/Pods/Swifttor/Swifttor/ActorSystem.swift b/Example/SwifttorExample/Pods/Swifttor/Swifttor/ActorSystem.swift index 28afcaf..7d13cae 100644 --- a/Example/SwifttorExample/Pods/Swifttor/Swifttor/ActorSystem.swift +++ b/Example/SwifttorExample/Pods/Swifttor/Swifttor/ActorSystem.swift @@ -12,18 +12,20 @@ public struct ActorSystem { fileprivate static var actors:[String:Any] = [:] - static func actorOfInstance(_ actor:T) -> ActorRef { + static public func actorOfInstance(_ actor:T) -> ActorRef { return ActorRef(actor: actor) } - static func actorOf(actorType:T.Type) -> ActorRef { + static public func actorOf(actorType:T.Type) -> ActorRef { let key = "\(actorType)" let act = actorType.init() let actorRef:ActorRef - +print(key) if let instance = actors[key] as? ActorRef { + print("cached actor") actorRef = instance } else { + print("new actor") let instance = ActorRef(actor: act) actors[key] = instance actorRef = instance diff --git a/Example/SwifttorExample/Pods/Swifttor/Swifttor/Future.swift b/Example/SwifttorExample/Pods/Swifttor/Swifttor/Future.swift index b89d1cc..7c832c5 100644 --- a/Example/SwifttorExample/Pods/Swifttor/Swifttor/Future.swift +++ b/Example/SwifttorExample/Pods/Swifttor/Swifttor/Future.swift @@ -9,14 +9,14 @@ import Foundation final public class Future { - private var callbacks: [(A) -> Void] = [] - private var cached: A? + private var callbacks: [(Result) -> Void] = [] + private var cached: Result? - init(compute: (@escaping (A) -> Void) -> Void) { + public init(compute: (@escaping (Result) -> Void) -> Void) { compute(self.send) } - private func send(_ value: A) { + private func send(_ value: Result) { assert(cached == nil) cached = value for callback in callbacks { @@ -25,7 +25,7 @@ final public class Future { callbacks = [] } - public func onResult(callback: @escaping (A) -> Void) { + public func onResult(callback: @escaping (Result) -> Void) { if let value = cached { callback(value) } else { @@ -34,24 +34,40 @@ final public class Future { } public func map(transform: @escaping (A) -> B) -> Future { - return self.flatMap { (response) -> Future in - Future(compute: { (completion) in - completion(transform(response)) - }) - } + self.cached = self.cached?.map(transform) as! Result<_> + return self } public func flatMap(transform: @escaping (A) -> Future) -> Future { return Future { completion in self.onResult { result in - transform(result).onResult(callback: completion) + switch result { + case .success(let value): + transform(value).onResult(callback: completion) + case .failure(let error): + completion(Result.failure(error: error)) + } } } } } +public enum Result { + case success(result:A) + case failure(error:String) +} +extension Result { + func map(_ transform: (A) -> B) -> Result { + switch self { + case .success(let value): return .success(result: transform(value)) + case .failure(let error): return .failure(error: error) + } + } +} + infix operator >>>:AdditionPrecedence public func >>>(left:Future, right: @escaping (A) -> Future) -> Future { return left.flatMap(transform: right) } + diff --git a/Example/SwifttorExample/SwifttorExample.xcodeproj/project.pbxproj b/Example/SwifttorExample/SwifttorExample.xcodeproj/project.pbxproj index 87ebc89..e7855d0 100644 --- a/Example/SwifttorExample/SwifttorExample.xcodeproj/project.pbxproj +++ b/Example/SwifttorExample/SwifttorExample.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 03A9D3A4D0AC69805744ADDB /* Pods_SwifttorExample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C00D26609ED77AEBACAA827 /* Pods_SwifttorExample.framework */; }; B5708FEC7AA4B8152CD1097F /* Pods_SwifttorExampleUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 49E9846B6F961486DA9D1B04 /* Pods_SwifttorExampleUITests.framework */; }; + D8150D151FC6CA5800E84EFF /* ParserActor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8150D141FC6CA5800E84EFF /* ParserActor.swift */; }; D89045041FC5F59800DC6AA3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D89045031FC5F59800DC6AA3 /* AppDelegate.swift */; }; D89045061FC5F59800DC6AA3 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D89045051FC5F59800DC6AA3 /* ViewController.swift */; }; D89045091FC5F59800DC6AA3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D89045071FC5F59800DC6AA3 /* Main.storyboard */; }; @@ -17,6 +18,8 @@ D89045191FC5F59900DC6AA3 /* SwifttorExampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D89045181FC5F59900DC6AA3 /* SwifttorExampleTests.swift */; }; D89045241FC5F59900DC6AA3 /* SwifttorExampleUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D89045231FC5F59900DC6AA3 /* SwifttorExampleUITests.swift */; }; D89045321FC5F70D00DC6AA3 /* MainActor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D89045311FC5F70D00DC6AA3 /* MainActor.swift */; }; + D89045341FC6C34900DC6AA3 /* Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = D89045331FC6C34900DC6AA3 /* Model.swift */; }; + D89045361FC6C3D500DC6AA3 /* NetworkActor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D89045351FC6C3D500DC6AA3 /* NetworkActor.swift */; }; DAA8354DF87B48D66C463535 /* Pods_SwifttorExampleTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1B73DF7353300151FA650774 /* Pods_SwifttorExampleTests.framework */; }; /* End PBXBuildFile section */ @@ -46,6 +49,7 @@ 621BDE24AAD48B52E860F1CE /* Pods-SwifttorExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwifttorExampleTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-SwifttorExampleTests/Pods-SwifttorExampleTests.release.xcconfig"; sourceTree = ""; }; B7810D5EA23F8FF9029DA795 /* Pods-SwifttorExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwifttorExampleTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SwifttorExampleTests/Pods-SwifttorExampleTests.debug.xcconfig"; sourceTree = ""; }; BC26DC9D0C325DCF1D10D4D4 /* Pods-SwifttorExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwifttorExample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SwifttorExample/Pods-SwifttorExample.debug.xcconfig"; sourceTree = ""; }; + D8150D141FC6CA5800E84EFF /* ParserActor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParserActor.swift; sourceTree = ""; }; D89045001FC5F59800DC6AA3 /* SwifttorExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwifttorExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; D89045031FC5F59800DC6AA3 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; D89045051FC5F59800DC6AA3 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; @@ -60,6 +64,8 @@ D89045231FC5F59900DC6AA3 /* SwifttorExampleUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwifttorExampleUITests.swift; sourceTree = ""; }; D89045251FC5F59900DC6AA3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; D89045311FC5F70D00DC6AA3 /* MainActor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainActor.swift; sourceTree = ""; }; + D89045331FC6C34900DC6AA3 /* Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Model.swift; sourceTree = ""; }; + D89045351FC6C3D500DC6AA3 /* NetworkActor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkActor.swift; sourceTree = ""; }; F98F9FEEBB507B4B82801AB0 /* Pods-SwifttorExampleUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwifttorExampleUITests.release.xcconfig"; path = "Pods/Target Support Files/Pods-SwifttorExampleUITests/Pods-SwifttorExampleUITests.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -146,6 +152,9 @@ D890450C1FC5F59800DC6AA3 /* LaunchScreen.storyboard */, D890450F1FC5F59800DC6AA3 /* Info.plist */, D89045311FC5F70D00DC6AA3 /* MainActor.swift */, + D89045331FC6C34900DC6AA3 /* Model.swift */, + D89045351FC6C3D500DC6AA3 /* NetworkActor.swift */, + D8150D141FC6CA5800E84EFF /* ParserActor.swift */, ); path = SwifttorExample; sourceTree = ""; @@ -462,8 +471,11 @@ buildActionMask = 2147483647; files = ( D89045321FC5F70D00DC6AA3 /* MainActor.swift in Sources */, + D89045361FC6C3D500DC6AA3 /* NetworkActor.swift in Sources */, D89045061FC5F59800DC6AA3 /* ViewController.swift in Sources */, D89045041FC5F59800DC6AA3 /* AppDelegate.swift in Sources */, + D8150D151FC6CA5800E84EFF /* ParserActor.swift in Sources */, + D89045341FC6C34900DC6AA3 /* Model.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Example/SwifttorExample/SwifttorExample/Assets.xcassets/AppIcon.appiconset/Contents.json b/Example/SwifttorExample/SwifttorExample/Assets.xcassets/AppIcon.appiconset/Contents.json index 1d060ed..d8db8d6 100644 --- a/Example/SwifttorExample/SwifttorExample/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/Example/SwifttorExample/SwifttorExample/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -84,6 +84,11 @@ "idiom" : "ipad", "size" : "83.5x83.5", "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" } ], "info" : { diff --git a/Example/SwifttorExample/SwifttorExample/Info.plist b/Example/SwifttorExample/SwifttorExample/Info.plist index 16be3b6..f87da23 100644 --- a/Example/SwifttorExample/SwifttorExample/Info.plist +++ b/Example/SwifttorExample/SwifttorExample/Info.plist @@ -20,6 +20,11 @@ 1 LSRequiresIPhoneOS + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile diff --git a/Example/SwifttorExample/SwifttorExample/MainActor.swift b/Example/SwifttorExample/SwifttorExample/MainActor.swift index 03ec24c..578578f 100644 --- a/Example/SwifttorExample/SwifttorExample/MainActor.swift +++ b/Example/SwifttorExample/SwifttorExample/MainActor.swift @@ -8,32 +8,28 @@ import Swifttor +enum MainActorMessages { + case displayInfo(callback:(Model) -> (),data:Model) + case refreshStuffWithData(callback:(String) -> (),data:String) + case refreshStuff(callbac:() -> ()) +} -struct MainActor: ActorTell { - + +struct MainActor: ActorTell { + typealias MessageType = MainActorMessages - var name:String { - return "etes" - } - var queue: DispatchQueue { - return DispatchQueue.main - } - - enum MainActorMessages { - case refreshStuffWithData(callback:(T) -> (),data:T) - case refreshStuff(callbac:() -> ()) - } - - - func reiciveTell(message: MainActor.MainActorMessages) { + func reiciveTell(message: MainActorMessages) { switch message { + case .refreshStuffWithData(let callback,let data): + callback(data) case .refreshStuff(let callback): callback() - case .refreshStuffWithData(let callback, let data): + case .displayInfo(let callback,let data): callback(data) } + } } diff --git a/Example/SwifttorExample/SwifttorExample/Model.swift b/Example/SwifttorExample/SwifttorExample/Model.swift new file mode 100644 index 0000000..2d164c6 --- /dev/null +++ b/Example/SwifttorExample/SwifttorExample/Model.swift @@ -0,0 +1,13 @@ +// +// Model.swift +// SwifttorExample +// +// Created by Alcala, Jose Luis on 11/23/17. +// Copyright © 2017 Alcala, Jose Luis. All rights reserved. +// + +import Foundation + +struct Model:Codable{ + let origin:String +} diff --git a/Example/SwifttorExample/SwifttorExample/NetworkActor.swift b/Example/SwifttorExample/SwifttorExample/NetworkActor.swift new file mode 100644 index 0000000..1fbfb7e --- /dev/null +++ b/Example/SwifttorExample/SwifttorExample/NetworkActor.swift @@ -0,0 +1,39 @@ +// +// NetworkActor.swift +// SwifttorExample +// +// Created by Alcala, Jose Luis on 11/23/17. +// Copyright © 2017 Alcala, Jose Luis. All rights reserved. +// + +import Swifttor +import Foundation +enum NetWorkMessages{ + case fetchFromNetwork(url:URL) +} + +struct NetworkActor: ActorAsk { + + typealias ResultType = Result + + typealias MessageType = NetWorkMessages + + func reiciveAsk(message: NetWorkMessages,completion:@escaping (Result)->()) { + switch message { + case .fetchFromNetwork(let url): + perfomNetWorkCall(url: url, completion: completion) + } + } + + + func perfomNetWorkCall(url:URL,completion:@escaping (Result)->()){ + let session = URLSession(configuration: .ephemeral) + session.dataTask(with: url, completionHandler: { (data, response, err) in + if let dat = data{ + completion(Result.success(result: dat)) + }else{ + completion(Result.failure(error: "error happend")) + } + }).resume() + } +} diff --git a/Example/SwifttorExample/SwifttorExample/ParserActor.swift b/Example/SwifttorExample/SwifttorExample/ParserActor.swift new file mode 100644 index 0000000..ec45152 --- /dev/null +++ b/Example/SwifttorExample/SwifttorExample/ParserActor.swift @@ -0,0 +1,31 @@ +// +// ParserActor.swift +// SwifttorExample +// +// Created by Alcala, Jose Luis on 11/23/17. +// Copyright © 2017 Alcala, Jose Luis. All rights reserved. +// + +import Swifttor + +enum ParserkMessages{ + case parseToModel(data:Data) +} + +struct ParserActor: ActorAsk { + + typealias ResultType = Result + typealias MessageType = ParserkMessages + + func reiciveAsk(message: Result, completion: @escaping (Result) -> ()) { + switch message { + case .parseToModel(let data): + if let result = try? JSONDecoder().decode(Model.self, from: data){ + completion(Result.success(result: result)) + }else{ + completion(Result.failure(error: "Cannot parse")) + } + } + } + +} diff --git a/Example/SwifttorExample/SwifttorExample/ViewController.swift b/Example/SwifttorExample/SwifttorExample/ViewController.swift index 6123306..8365d9f 100644 --- a/Example/SwifttorExample/SwifttorExample/ViewController.swift +++ b/Example/SwifttorExample/SwifttorExample/ViewController.swift @@ -10,12 +10,38 @@ import UIKit import Swifttor class ViewController: UIViewController { - let actorRef = ActorSystem. + override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. + let actorRef = ActorSystem.actorOf(actorType: MainActor.self) + + + let networkActor = ActorSystem.actorOf(actorType: NetworkActor.self) + let parserActor = ActorSystem.actorOf(actorType: ParserActor.self) + networkActor.ask(.fetchFromNetwork(url: URL(string: "https://httpbin.org/ip")!)) >>> parserActor.ask + res.onResult(callback: { r in + switch r{ + case .success(result: let res): + parserActor.ask(ParserkMessages.parseToModel(data: res)).onResult(callback: { res1 in + switch res1{ + case .success( let res2): + actorRef.tell(MainActorMessages.refreshStuffWithData(callback: { input in + print(input) + }, data: res2.origin)) + case .failure(let error): + actorRef.tell(MainActorMessages.refreshStuffWithData(callback: { input in + print(input) + }, data: error)) + } + + }) + case .failure(error: let err): + print("hack") + } + }) }