2017-09-05 26 views
2

所以我一直在試圖建立一個「週期」類,具有以下屬性:iOS版雨燕方便初始化自稱爲

class PTPeriod { 

    // MARK: Stored Properties 

    var start: Date 
    var end: Date 
    var place: PTPlace? 


//MARK: DESIGNATED NITIALIZER 
init(start: Date, end: Date, place: PTPlace? = nil) { 
    self.start = start 
    self.end = end 
    self.place = place 

} 

而且我想用一個方便init初始化它是接受如下字典:

 { 
      "close" : { 
       "day" : 1, 
       "time" : "0000" 
      }, 
      "open" : { 
       "day" : 0, 
       "time" : "0900" 
      } 
     } 

這是我的初始化程序,最初我把繁重的工作放到了輔助方法中。然而,我現在得到了同樣的錯誤,所以我刪除了輔助方法,錯誤仍在發生。不確定它認爲我在稱自己的地方。

更新:將日期格式轉換爲日期格式化擴展,但錯誤仍然存​​在!不確定爲什麼。呈現出新的init:

我的新便利的init:

// MARK: Convenience init for initializing periods pulled from Google Place API 
convenience init?(placeData: [String:Any], place: PTPlace? = nil) throws { 
    var start: Date? = nil 
    var end: Date? = nil 
    var formatter = DateFormatter() 

    do { 
     for (key, value) in placeData { 
      let period = value as! [String: Any] 
      if (key == "open") { 
       start = try formatter.upcoming_date(with: period) 
      } else if (key == "close") { 
       end = try formatter.upcoming_date(with: period) 
      } else { 
       break 
      } 
     } 
     if (start != nil && end != nil) { self.init(start: start!, end: end!, place: place) } 
     else { print("we f'd up") } 

    } 

    catch { print(error.localizedDescription) } 
} 

這裏是我的DateFormatter.upcoming_date方法:

func upcoming_date(with googlePlacePeriod: [String: Any]) throws -> Date? { 
    if let day = googlePlacePeriod["day"] as? Int { 
     if (day < 0) || (day > 6) { throw SerializationError.invalid("day", day) } // throw an error if day is not between 0-6 
     if let time = googlePlacePeriod["time"] as? String { 
      if time.characters.count != 4 { throw SerializationError.invalid("time", time) } // throw an error if time is not 4 char long 
      var upcoming_date: Date 
      let gregorian = Calendar(identifier: .gregorian) 

      let current_day_of_week = Date().getDayOfWeekInt() 
      let dayOfPeriod = day + 1 

      ///TRUST THAT THIS WORKS... NO JODAS 
      var distance = dayOfPeriod - current_day_of_week // inverse = false 

      if (dayOfPeriod < current_day_of_week) { 
       switch distance { 
       case -1: distance = 6 
       case -2: distance = 5 
       case -3: distance = 4 
       case -4: distance = 3 
       case -5: distance = 2 
       case -6: distance = 1 
       default: break 
       } 
      } 
      /** time example: "1535" translates into 3:35PM 
      first two characters in string are "hour" (15) 
      last two characters in string are "minute(35) 
      **/ 

      let hour = Int(time.substring(to: time.index(time.startIndex, offsetBy: 2)))! 
      let minute = Int(time.substring(from: time.index(time.endIndex, offsetBy: -2))) 


      upcoming_date = Date().fastForward(amount: distance, unit: "days", inverse: false)! 
      var components = gregorian.dateComponents([.year, .month, .day, .hour, .minute, .second], from: upcoming_date) 
      components.hour = hour 
      components.minute = minute 
      upcoming_date = gregorian.date(from: components)! 
      return upcoming_date 
     } 
     else { throw SerializationError.missing("time") } 
    } 
    else { throw SerializationError.missing("day") } 
} 
+0

我不知道標題中的錯誤,但列出的代碼不會在'else'塊中調用'self.init'。同樣,如果發生錯誤,您正在捕獲它(而不是調用'self.init'),而不是讓它冒泡給調用者。 –

+0

@ Honey-我有一個指定的初始化程序,但它需要「開始」和「結束」被初始化。我會將其添加到問題的清晰度 –

+0

@ Kevin-感謝指出,我不確定我完全清楚什麼時候發現錯誤以及何時讓他們「冒泡」,儘管我已經完成了很多閱讀它。我在init失敗時添加了「return nil」(作爲其失敗的初始化程序) –

回答

1

你有failable初始化,因此,如果失敗,則必須return nil讓它知道它失敗:

if (start != nil && end != nil) { 
    self.init(start: start!, end: end!, place: place) } 
} else { 
    print("we f'd up") 
    return nil 
} 

另外,在你的do - catch,你需要或者

  • 重新throwcatch

    catch { 
        print(error.localizedDescription) 
        throw error 
    } 
    
  • 消除do錯誤 - catch塊完全;或

  • 只是return nil

    catch { 
        print(error.localizedDescription) 
        return nil 
    } 
    

    如果你這樣做,你大概沒有定義failable初始化爲一體,throws因爲你不再扔。


既然你不可能做任何有意義與拋出的錯誤,我只是使它成爲一個failable初始化不拋出:

convenience init?(placeData: [String: Any], place: PTPlace? = nil) { 
    var start: Date? 
    var end: Date? 
    let formatter = DateFormatter() 

    for (key, value) in placeData { 
     let period = value as! [String: Any] 
     if key == "open" { 
      start = try? formatter.upcoming_date(with: period) 
     } else if key == "close" { 
      end = try? formatter.upcoming_date(with: period) 
     } else { 
      break // I'm not sure why you're doing this; it seems extremely imprudent (esp since dictionaries are not ordered) 
     } 
    } 

    if let start = start, let end = end { 
     self.init(start: start, end: end, place: place) 
    } else { 
     print("either start or end were not found") 
     return nil 
    } 
} 
+0

它的工作,你讓問題消失!我不太明白(但)爲什麼這給我的問題,但謝謝。我不會懷疑這是問題 –

+1

訣竅是,在可分解的初始化程序中,每個執行路徑必須調用指定的初始化程序或必須返回nil(或者,如果初始化程序「拋出」,必須「拋出」一個實際的錯誤)。你有兩條執行路徑('else'子句和'catch'塊,但沒有這樣做)。編譯器錯誤信息只是誤導。 – Rob