Swift - Dynamic cast class unconditional? - ios

It doesn't seem like I can cast a generic type to another? Swift is throwing DynamicCastClassException.
Basically here is the problem:
// T is defined as T: NSObject
let oebj1 = NetworkResponse<User>()
let oebj2 = oebj1 as NetworkResponse<NSObject>
Here is why I need to do this casting
class BaseViewController: UIViewController {
// Not allowed to make a generic viewController and therefore have to cast the generic down to NSObject
func fetchData(completion: (NetworkResponse<NSObject>)->()) {
fatalError("You have to implement fetchData method")
}
}
class UsersViewController: BaseViewController {
override func fetchData(completion: (NetworkResponse<NSObject>)->()) {
userNetworkManager.fetchUsers { networkUSerResponse in
completion(networkUSerResponse as NetworkResponse<NSObject>)
}
}
}
class UserNetworkManager {
func fetchUsers(completion: (NetworkResponse<User>)->()) {
// Do stuff
}
}

In general, there doesn't seem to be a way to do this. The basic problem is that NetworkResponse<NSObject> and NetworkResponse<User> are essentially completely unrelated types that happen to have identical functionality and similar naming.
In this specific case, it really isn't necessary since you're throwing away the known Userness of the result anyway, meaning that if you really want to treat it as a User later you'll have to do a conditional cast back. Just remove the generic from NetworkResponse and it will all work as expected. The major drawback is that within UserVC.fetchData you won't have access to the returned User result without a (conditional) cast.
The alternative solution would be to separate out whatever additional information is in NetworkResponse from the payload type (User/NSObject) using a wrapper of some sort (assuming there's significant sideband data there). That way you could pass the NetworkResponse to super without mutilation and down-cast the payload object as needed.
Something like this:
class User : NSObject {
}
class Transaction {
let request:NSURLRequest?
let response:NSURLResponse?
let data:NSData?
}
class Response<T:NSObject> {
let transaction:Transaction
let payload:T
init(transaction:Transaction, payload:T) {
self.transaction = transaction
self.payload = payload
}
}
class UserNetworkManager {
func fetchUsers(completion: (Response<User>) -> ()) {
completion(Response(transaction:Transaction(), payload:User()))
}
}
let userNetworkManager = UserNetworkManager();
class BaseVC {
func fetchData(completion: (Response<NSObject>) -> ()) {
fatalError("Gotta implement fetchData")
}
}
class UserVC : BaseVC {
override func fetchData(completion: (Response<NSObject>) -> ()) {
userNetworkManager.fetchUsers { response -> () in
completion(Response(transaction: response.transaction, payload: response.payload))
}
}
}
Although at that point, you're probably better off just separating the transaction information and payload information into separate arguments to the callback.

Related

iOS/Swift - What is the difference between Closure/Completion blocks and Delegates/functions?

I don't clear about these two, Nowadays the world is shifting to the closure types. But I'm not clearly understanding this. Can someone explain me with a real-time example?
So a real life example of both would be something like this:
protocol TestDelegateClassDelegate: class {
func iAmDone()
}
class TestDelegateClass {
weak var delegate: TestDelegateClassDelegate?
func doStuff() {
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
self.delegate?.iAmDone()
}
}
}
class TestClosureClass {
var completion: (() -> Void)?
func doStuff() {
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
self.completion?()
}
}
}
class ViewController: UIViewController, TestDelegateClassDelegate {
func iAmDone() {
print("TestDelegateClassDelegate is done")
}
override func viewDidLoad() {
super.viewDidLoad()
let testingDelegate = TestDelegateClass()
testingDelegate.delegate = self
testingDelegate.doStuff()
let testingClosure = TestClosureClass()
testingClosure.completion = {
print("TestClosureClass is done")
}
testingClosure.doStuff()
}
}
Here we have 2 classes TestDelegateClass and TestClosureClass. Each of them have a method doStuff which waits for 3 seconds and then reports back to whoever is listening where one uses delegate procedure and the other one uses closure procedure.
Although they do nothing but wait you can easily imagine that they for instance upload an image to server and notify when they are done. So for instance you might want to have an activity indicator running while uploading is in progress and stop it when done. It would look like so:
class ViewController: UIViewController, TestDelegateClassDelegate {
#IBOutlet private var activityIndicator: UIActivityIndicatorView?
func iAmDone() {
print("TestDelegateClassDelegate is done")
activityIndicator?.stopAnimating()
}
override func viewDidLoad() {
super.viewDidLoad()
activityIndicator?.startAnimating()
let testingDelegate = TestDelegateClass()
testingDelegate.delegate = self
testingDelegate.doStuff()
activityIndicator?.startAnimating()
let testingClosure = TestClosureClass()
testingClosure.completion = {
self.activityIndicator?.stopAnimating()
print("TestClosureClass is done")
}
testingClosure.doStuff()
}
}
Naturally you would only use one of the two procedures.
You can see there is a huge difference in code. To do a delegate procedure you need to create a protocol, in this case TestDelegateClassDelegate. A protocol is what defines the interface of a listener. And since an iAmDone method is defined it must be defined in ViewController as well as long as it is defined as TestDelegateClassDelegate. Otherwise it will not compile. So anything declared as TestDelegateClassDelegate will have that method and any class can call it. In our case we have weak var delegate: TestDelegateClassDelegate?. That is why we can call delegate?.iAmDone() without caring what delegate actually is. For instance we can create another class:
class SomeClass: TestDelegateClassDelegate {
func iAmDone() {
print("Something cool happened")
}
init() {
let testingDelegate = TestDelegateClass()
testingDelegate.delegate = self
testingDelegate.doStuff()
}
}
So a good example for instance is an UITableView that uses a delegate and dataSource (both are delegates, just properties are named differently). And table view will call the methods of whatever class you set to those properties without needing to know what that class is as long as it corresponds to the given protocols.
Same could be achieved with closures. A table view could have been defined using properties giving closures like:
tableView.onNumberOfRows { section in
return 4
}
But that would most likely lead into one big mess of a code. Also closures would in this case be giving many programmers headaches due to potential memory leaks. It is not that closures are less safe or anything, they just do a lot of code you can't see which may produce retain cycles. In this specific case a most likely leak would be:
tableView.onNumberOfRows { section in
return self.dataModel.count
}
and a fix to it is simply doing
tableView.onNumberOfRows { [weak self] section in
return self?.dataModel.count ?? 0
}
which now looks overcomplicated.
I will not go into depths of closures but in the end when you have repeated call to callbacks (like in case of table view) you will need a weak link either at delegate or in closure. But when the closure is called only once (like uploading an image) there is no need for a weak link in closures (in most but not all cases).
In retrospective use closures as much as possible but avoid or use caution as soon as a closure is used as a property (which is ironically the example I gave). But you would rather do just this:
func doSomethingWithClosure(_ completion: #escaping (() -> Void)) {
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
completion()
}
}
And use it as
doSomethingWithClosure {
self.activityIndicator?.stopAnimating()
print("TestClosureClass is done")
}
This has now removed all potential risks. I hope this clears a thing or two for you.
In Swift/obj-c the term delegate is used to refer to a protocol that responds to specific selectors.
Thing about it just like calling a method on an object.
E.g.
protocol CalculatorDelegate : class { // : class so it can be made 'weak'
func onCalculation(result: Int) -> Void
}
Now if we have a Calculator class, to use the delegate we'd do something like
class Calculator() {
weak var delegate: CalculatorDelegate?
func calculate(_ a: Int, _ b: Int) -> Int {
let result = a + b
self.delegate?.onCalculation(result: result)
return result
}
}
Then in some other class (e.g. in iOS - a View Controller) we might do:
class MyClass : CalculatorDelegate {
func onCalculation(result: Int) {
print("Delegate method on calculation called with result \(result)")
}
func someButtonPress() {
let calculator = Calculator()
calculator.delegate = self
calculator.calculate(42, 66)
}
}
So you can see how the setup is quite elaborate.
Now closures are simply blocks of code that can be called in other places, so you could change all of the code like so:
class Calculator2() {
weak var delegate: CalculatorDelegate?
func calculate(_ a: Int, _ b: Int, onCalculation: (#escaping (Int) -> Void) -> Int)?) {
let result = a + b
onCalculation?(result)
return result
}
}
class MyClass {
func someButtonPress() {
let calculator = Calculator2()
calculator.calculate(42, 66, onCalculation: { (result: Int) in
print("Closure invoked with \(result)")
})
}
}
However, with closures you need to be aware that it is a lot easier to shoot yourself in the foot by capturing variables (e.g. self) strongly, which will lead to memory leaks even under ARC regime.
Closures are first-class objects so that they can be nested and passed around
Simply,
In swift, functions are primitive data types like int, double or character that is why you can pass a function in the function parameter. In swift mechanism simplify in closures syntax like lambda expression in other languages.
E.g. If you want to call rest API through URSSession or Alamofire and return response data then you should use completionHandler(it's closure).
Void closure : - {(paramter:DataType)->Void}
Return closure : - {(paramter:DataType)->DataType}
e.g. (int, int) -> (int)
https://docs.swift.org/swift-book/LanguageGuide/Closures.html

Best practice for using callbacks with structs?

I want to use a callback on a struct which fails with the error 'Closure cannot implicitly capture a mutating self parameter' on the line self.pictures = catPictures
How I understand it that has something to do with structs are value types and a closure holding a copy of it isn't really safe.
The usage is similar to the following:
final class APIService {
static func loadFunnyCatPicturesAsync(completion: #escaping ([UIImage]) -> () ) {
DispatchQueue.main.async {
// Do a lot of fancy stuff here
let decodedImages = [UIImage()]
// DispatchQueue.main.async or .sync? - I'm not sure about that :|
DispatchQueue.main.async {
completion(decodedImages)
}
}
}
}
struct viewModel {
var pictures: [UIImage] {
didSet {
// Do synchronous stuff here again
}
}
mutating func loadPicture() {
APIService.loadCatPicturesAsync { (catPictures) in
self.pictures = catPictures
}
}
}
.
So should I just make the viewModel a class or is there a nice way to make this work with structs.
And when I make the callback should I use DispatchQueue.main.async or .sync
Note: I don't really want to use the delegate pattern, because I think it adds too much overhead.

Swift : Create a multi-function multicast delegate

I'm wanting to use a multicast delegate to inform multiple objects when things change. The tutorials I've read that explain this, have a protocol that only has one function that is called directly on the array of delegates. That works fine when there is only one function defined. My Protocol has 6 functions. I want to avoid creating 6 separate functions and reuse a single function that can be applied to my array of delegates.
Quick example: (I understand this is none working, but I just want to get my idea across.
protocol MyProtocol {
func method1()
func method2()
func method3()
}
class TestClass {
var delegates = [MyProtocol]()
func invokeDelegates(delegateMethod: () -> ()) {
for delegate in delegates {
delegate.delegateMethod()
}
}
}
The obvious problem is the compiler complains that "delegateMethod" isn't defined in the original protocol. Is there a way that I cast the method as being part of MyProtocol and the compiler will trust me?
Is this even possible?
Here is a gist of an Multicast Delegate pattern that I use in my projects. It also prevents from having strong reference cycles (memory leaks). WeakWrapper handles this.
Ok. In some of the solutions I see mistakes (strong retain cycles, race conditions, ...)
Here is what I combine based on 1 day research. For the stack of delegates I used NSHashTable, so all the delegates are having weak reference.
class MulticastDelegate <T> {
private let delegates: NSHashTable<AnyObject> = NSHashTable.weakObjects()
func add(delegate: T) {
delegates.add(delegate as AnyObject)
}
func remove(delegate: T) {
for oneDelegate in delegates.allObjects.reversed() {
if oneDelegate === delegate as AnyObject {
delegates.remove(oneDelegate)
}
}
}
func invoke(invocation: (T) -> ()) {
for delegate in delegates.allObjects.reversed() {
invocation(delegate as! T)
}
}
}
func += <T: AnyObject> (left: MulticastDelegate<T>, right: T) {
left.add(delegate: right)
}
func -= <T: AnyObject> (left: MulticastDelegate<T>, right: T) {
left.remove(delegate: right)
}
How to set delegate:
object.delegates.add(delegate: self)
How to execute function on the delegates:
instead of
delegate?.delegateFunction
you use
delegates.invoke(invocation: { $0.delegateFunction })
You need to change the signature of invokeDelegates to take a closure of type (MyProtocol) -> (), and then you need to pass each delegate to the closure.
protocol MyProtocol {
func method1()
func method2()
func method3()
}
class TestClass {
var delegates = [MyProtocol]()
func invokeDelegates(delegateMethod: (MyProtocol) -> ()) {
for delegate in delegates {
delegateMethod(delegate)
}
}
}
The closure should just invoke the appropriate delegate method on its argument. Swift can infer the argument and return types of the closure, and you can use the shorthand $0 to refer to the argument, so the closure can be quite short:
let tester = TestClass()
tester.invokeDelegates(delegateMethod: { $0.method1() })
On the other hand, you could just use Collection.forEach directly on the delegates array (if it's accessible) and skip the invokeDelegates method:
tester.delegates.forEach { $0.method1() }

Return an array of type Self

I'm having trouble figuring out a way to return an array of instances of a specific dynamic class type, at runtime, in Swift.
I successfully compiled and tested this version which returns a single instance of a class:
class Generic {
class func all() -> Self {
return self.init()
}
required init() {
}
}
class A: Generic {
}
let a = A.all() // is of type A
The challenge here is to get compilation to allow the all function to be prototyped as follows: class func all() -> [Self] (i.e return an array of instances, working with subclasses, without any cast).
class Generic {
class func all() -> [Self] {
return [self.init()]
}
required init() {
}
}
class A: Generic {
}
let a = A.all() // won't compile
I could return an array of Generic instances with class func all() -> [Generic] but this requires an additional cast with as! to get the correct type A. I'd like to take advantage of begin in the context of class A and using the Self keyword, to let the compiler infer the 'real' type. Do you guys think it's possible?
It seems to be only possible to return single instances, not arrays.
EDIT: Got this to work using AnyObject. Better, but not optimal as it requires a cast to the correct type.
class Generic {
class func all() -> [AnyObject] {
return [self.init()]
}
required init() {
}
}
class A: Generic {
}
let a = A.all() as! [A]
Thanks!
PS: Any other way to do this using generics or protocols/protocol extensions is also an option. If you have a more "Swifty" version in mind, please be my guest. Can't help myself thinking there's maybe a better way to do this, but can't figure out how.
The only option I can see of doing something like that is using protocols instead of a base class, like this:
protocol Generic {
func all() -> [Self]
init()
}
extension Generic {
func all() -> [Self] {
return [self.dynamicType.init()]
}
}
final class A : Generic {
}
A().all()
You have two limitations doing it like this. First, all classes that conform to your protocol have to be final. Second, all classes must obviously implement the init defined in the protocol, otherwise we wouldn't be able to have the all method defined.
Edit: you don't actually need to define the init as long as you don't define any other initializers
Edit 2: I didn't notice you used class functions, you can modify my example to use class functions instead of instance methods by replacing func all() -> [Self] with static func all() -> [Self] and
func all() -> [Self] {
return [self.dynamicType.init()]
}
with
static func all() -> [Self] {
return [self.init()]
}
Unfortunately, there doesn't seem to be a way to do this using Self. Self cannot be used in expressions, so [Self] or Array<Self> are not allowed.
However, I think that your use case is completely valid and you should repot it as a bug.

Swift, Self from AnyObject

Is it possible to get Self from AnyObject?
Take this example:
// Superclass
class ManagedObject {
class func findByID(id: String) -> AnyObject? {
let objects = objectsWithPredicate(NSPredicate(format: "id == %#", id))
return objects.firstObject() // Returns AnyObject
}
}
// Subclass
class User : ManagedObject {
class func returnFirstSelf() -> Self? {
return findById("1") // This doesn't work because it returns AnyObject, but I need Self.
}
}
If not, what is the best alternative way to ensure that when calling User.returnFirstSelf(), the compiler gives back a User, and when calling UserSubclass.returnFirstSelf(), it gives back a UserSubclass.
You can simply return User? from your class function, if this is an option:
public class func returnFirstSelf() -> User? {
if let found = findByID("1") as? User {
return found
}
return nil
}
There's currently no way (I'm aware of) to return Self? with Swift as it stands. The problem is that Self has a somewhat... "dynamic" meaning, separate from concrete types, protocols, and even generics. A particular example that demonstrates this is: What if you have a class StudentUser that extends User? If you tried to implement it like this:
class func returnFirstSelf() -> Self? {
if let found = findById("1") as? Self { // Note the check that 'found' is a 'Self'
return found
}
return nil
}
Then you encounter a compiler error because you cannot use Self outside the result of a protocol or class method. And if you try to implement it like this:
class func returnFirstSelf() -> Self? {
if let found = findById("1") as? User { // Note 'User' instead of 'Self'
return found
}
return nil
}
Then you run the risk of Self actually meaning StudentUser, and even if you pass the check that requires found to be a User, it doesn't guarantee that found will be a StudentUser. This will occur in the case that StudentUser does not override the method to ensure that the as? checks against StudentUser.
The critical flaw here in my opinion is that you cannot use the required keyword on class methods, requiring subclasses to override them. This would allow the compiler to ensure that any subclasses have overridden the method and provided an implementation that can guarantee type safety.
Craig Otis' answer is spot on. However, one option is to create a copy constructor. This may not work for the asker's scenario where they're inheriting from a NSManagedObject, but it should work for non-managed objects.
required init(user: User) {
super.init(user: User) // or super.init() if top of inheritance.
self.name = user.name
self.email = user.email
// etc.
}
class func returnFirstSelf() -> Self? {
if let found = findById("1") { // Note the check that 'found' is a 'Self'
return self.init(copy: found as! User)
}
return nil
}

Resources