Индекс массива Swift 4 вне диапазона [дубликат]

Установите CSS для #footer :

  position: absolute;  bottom: 0;   

Затем вам нужно будет добавить поле padding или в нижней части вашего #sidebar и #content , чтобы соответствовать высоте #footer , или когда они перекрываются, #footer покроет их.

Также , если я правильно помню, IE6 имеет проблему с дном : 0 CSS. Возможно, вам придется использовать JS-решение для IE6 (если вам небезразличен IE6).

10
задан teo751 22 November 2014 в 19:42
поделиться

3 ответа

Вы должны добавить свой собственный параметр закрытия completionHandler и вызвать его, когда задача завершится:

func googleDuration(origin: String, destination: String, completionHandler: (Int?, NSError?) -> Void ) -> NSURLSessionTask {
    // do calculations origin and destiantion with google distance matrix api

    let originFix = origin.stringByReplacingOccurrencesOfString(" ", withString: "+", options: NSStringCompareOptions.LiteralSearch, range: nil);
    let destinationFix = destination.stringByReplacingOccurrencesOfString(" ", withString: "+", options: NSStringCompareOptions.LiteralSearch, range: nil);

    let urlAsString = "https://maps.googleapis.com/maps/api/distancematrix/json?origins="+originFix+"&destinations="+destinationFix
    println(urlAsString)

    let url = NSURL(string: urlAsString)!
    let urlSession = NSURLSession.sharedSession()

    let task = urlSession.dataTaskWithURL(url) { data, response, error -> Void in
        if error != nil {
            // If there is an error in the web request, print it to the console
            // println(error.localizedDescription)
            completionHandler(nil, error)
            return
        }

        //println("parsing JSON");
        let json = JSON(data: data)
        if (json["status"].stringValue == "OK") {
            if let totalTime = json["rows"][0]["elements"][0]["duration"]["value"].integerValue {
                // println(totalTime);
                completionHandler(totalTime, nil)
                return
            }
            let totalTimeError = NSError(domain: kAppDomain, code: kTotalTimeError, userInfo: nil) // populate this any way you prefer
            completionHandler(nil, totalTimeError)
        }
        let jsonError = NSError(domain: kAppDomain, code: kJsonError, userInfo: nil) // again, populate this as you prefer
        completionHandler(nil, jsonError)
    }
    task.resume()
    return task
}

У меня также будет это возвращение NSURLSessionTask в случае, если вызывающий хочет быть в состоянии для отмены задачи.

В любом случае, вы бы назвали это так:

googleDuration(origin, destination: destination) { totalTime, error in
    if let totalTime = totalTime {
        // use totalTime here
    } else {
        // handle error     
    }
}
10
ответ дан Rob 15 August 2018 в 14:43
поделиться
  • 1
    Есть ли способ сделать это неасинхронным? Мне нужно, чтобы он подождал, пока не будет обработан ответ, но я не знаю, как это сделать. Ваше решение было правильным, я думаю, что мой вопрос был просто неправильным – teo751 22 November 2014 в 22:50
  • 2
    Вы можете, , но это серьезно неодобрительно. Это ужасный UX, и если вы сделаете это в неподходящее время, процесс watchdog может убить ваше приложение. Правильное решение - отключить пользовательский интерфейс, настоящий счетчик (в iOS, UIActivityIndicatorView) и отменить этот процесс, когда запрос будет выполнен. Вы действительно должны принять асинхронный шаблон, а не бороться с ним. – Rob 22 November 2014 в 23:02
  • 3
    Кстати, часто люди отправляют тех обработчиков завершения в основную очередь (потому что вызывающий абонент обычно занимается обновлением пользовательского интерфейса). Если вы хотите, чтобы я обновил ответ, чтобы показать вам, как это сделать, дайте мне знать. Это, вероятно, объяснительно, если вы владеете GCD, но я счастлив показать вам, если вы этого не сделали. – Rob 22 November 2014 в 23:04
  • 4
    Если я это сделаю, он устанавливает timeLabel как -999, а не то, что я хочу. var tripTime = -999; googleDuration(startLabel.text, destination: endLabel.text) { totalTime, error in if let totalTime = totalTime { // use totalTime here tripTime = totalTime; println(tripTime); } } println("Returning: "); println(tripTime); timeLabel.text = String(tripTime); – teo751 22 November 2014 в 23:13
  • 5
    Да, это self.timerLabel.text = .... Вы отправили это в основную очередь? – Rob 22 November 2014 в 23:36

Другой пример:

   class func getExchangeRate(#baseCurrency: String, foreignCurrency:String, completion: ((result:Double?) -> Void)!){
    let baseURL = kAPIEndPoint
    let query = String(baseCurrency)+"_"+String(foreignCurrency)

    var finalExchangeRate = 0.0
    if let url = NSURL(string: baseURL + query) {
        NSURLSession.sharedSession().dataTaskWithURL(url) { data, response, error in

            if ((data) != nil) {
                let jsonDictionary:NSDictionary = NSJSONSerialization.JSONObjectWithData(data!, options: nil, error: nil) as NSDictionary

                if let results = jsonDictionary["results"] as? NSDictionary{
                    if let queryResults = results[query] as? NSDictionary{
                        if let exchangeRate = queryResults["val"] as? Double{
                            let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
                            dispatch_async(dispatch_get_global_queue(priority, 0)) {
                                dispatch_async(dispatch_get_main_queue()) {
                                    completion(result: exchangeRate)
                                }
                            }

                        }
                    }
                }
            }
            else {
                completion(result: nil)
            }

        }.resume()
    }
}

Вызов:

 Currency.getExchangeRate(baseCurrency: "USD", foreignCurrency: "EUR") { (result) -> Void in
        if let exchangeValue = result {
            print(exchangeValue)
        }
    }
2
ответ дан ericgu 15 August 2018 в 14:43
поделиться

Другой пример:

func getJason(url: NSURL, completionHandler: (String?, NSError?) -> Void ) -> NSURLSessionTask {

    var finalData: String!
    let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) -> Void in

        if error != nil{

            completionHandler(nil, error)
            return
        }
        else{

        if let urlContent = data{

            do{
                let jsonData = try NSJSONSerialization.JSONObjectWithData(urlContent, options: NSJSONReadingOptions.MutableContainers)

                if let ip = jsonData["ip"]{

                    finalData = ip as? String
                    completionHandler(finalData, nil)
                    return
                }

            }catch{
                print("EMPTY")
            }

        }

    }
}
    task.resume()
    return task
}

Затем я назвал его в viewDidLoad

getJason(url) { (ipAddress, error) -> Void in

        if error != nil{

            print(error)
        }
        else{
            if let ip = ipAddress{          //To get rid of optional

        self.ipLabelDisplay.text = "Your Ip Address is: \(ip)"

            }

        }
    }
0
ответ дан Kegham K. 15 August 2018 в 14:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: