5

So this is a function from a class that lets you have a double tap and a single tap gesture. It's working fine in Swift 2.3, but after converting to Swift 3 it's throwing a few errors. I can't understand/figure out for the life of me. I commented where they occur.

//  UIShortTapGestureRecognizer.swift
//
//

import Foundation
import UIKit


    func delayHelper(_ time:TimeInterval, task:@escaping ()->()) ->  DelayTask? {

        func dispatch_later(_ block:@escaping ()->()) {
            DispatchQueue.main.asyncAfter(
                deadline: DispatchTime.now() + Double(Int64(time * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC),
                execute: block)
        }

        var closure: ()->()? = task

        var result: DelayTask?

        let delayedClosure: DelayTask = {
            cancel in

//Initializer for conditional binding must have Optional type, not '() -> ()?'
            if let internalClosure = closure {
                if (cancel == false) {
                    DispatchQueue.main.async(execute: internalClosure)
                }
            }

// here it says Nil cannot be assigned to type '() -> ()?'
            closure = nil

            result = nil
        }

        result = delayedClosure

        dispatch_later {
            if let delayedClosure = result {
                delayedClosure(false)
            }
        }

        return result;
    }

    func cancel(_ task:DelayTask?) {
        task?(true)
    }
}
Pablo Escobar
  • 111
  • 2
  • 5
  • 3
    It means the return parameter is optional. Try (() -> ())? – totiDev Apr 22 '17 at 22:21
  • I am somewhat doubtful this would've compiled in Swift 2.3 either, it should have also considered `()->()?` to be a function that returns `Void?`. – Hamish Apr 22 '17 at 22:48

3 Answers3

6

Try with: var closure: (()->())? = task

A. Barone
  • 71
  • 3
0

From another topic:

func someFunction(someParameter: someType, completionClosure: @escaping @autoclosure () -> ()? = nil)

The use of @autoclosure allowed me to assign nil to the optional closure.

The full details of how exactly @autoclosure helps escape me (why "my" closure is "not good" but the Swift_generated_one_that_simply_wraps_mine is?) . But, it helped me get rid of ... enter image description here ...and call my function in either of two ways:

someFunction(x, { ... }) 

OR

someFunction(x)
Community
  • 1
  • 1
Florin Odagiu
  • 456
  • 6
  • 16
0

Here is the way how i could overcome this. Here clang is not aware about its type. I gave a typealias and optional declaration,

typealias appDelegateBlock = ()->()

In your class, just declare it as optional,

var block: appDelegateBlock?
block = task
Prabhu.Somasundaram
  • 1,380
  • 10
  • 13