2015-03-14 5 views
1

Я пытаюсь создать словарь в swift, но я получаю сообщение об ошибке. Я попробовал развернуть переменную, добавив '?'. Не уверен, что правильный способ для создания словаряНевозможно преобразовать тип выражения «Словарь» в тип «StringLiteralConvertible»

class Event: NSObject { 

// When I remove the '?' on the variables it works but im not quite sure why 
// Should I not be declaring variable as optional unwrapped? 

var title:String? 
var eventDescription:String? 
var duration:Double? 
var eventID:String? 
var hostID:String? 
var location:CLLocation? 
var category:String? 
var invitedUsers:[String?] 

func createEvent(){ 

    // setting up event information to save 
    var postEventData = [ 
     "title": self.title, 
     "description":self.eventDescription, 
     "duration":self.duration, 
     "host":self.hostID, 
     "category":self.category 
    ] 

} 
func setTitle(title:String?){ 
    self.title = title 
} 

func setEventDescription(eventDescription:String?){ 
    self.eventDescription = eventDescription 
} 
..... 
} 

ответ

3

Вот вы говорите, что title (и другие свойства) может или не может иметь значение:

var title:String? 

Тогда здесь вы пытаетесь использовать значение title:

var postEventData = [ 
    "title": self.title, 
    "description":self.eventDescription, 
    "duration":self.duration, 
    "host":self.hostID, 
    "category":self.category 
] 

Вам нужно решить, что вы хотите сделать, если title не имеет значения. Должно ли создаваться postEventData? Должны ли они использовать значения по умолчанию? Теоретически вы можете создать словарь [String : String?], но это вообще не полезно (поскольку выборка из словарей уже возвращает необязательный).

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

  • Сделайте свои объекты не факультативными. Действительно ли это нормально, что эти свойства не имеют ценности? Возможно, они должны по умолчанию быть "", а не быть необязательными. позволяют

  • Только createEvent() если все свойства установлены (я переписан createEvent возвращать значение, потому что ваш текущий код просто создает переменную, а затем выбрасывает его, так что я не был уверен, что цель была):


func createEvent() -> [String: String] { 
    if let title = self.title, 
      description = self.eventDescription, 
      duration = self.duration, 
      host = self.hostID, 
      category = self.category { 
     return [ 
      "title": title, 
      "description": description, 
      "duration": duration, 
      "host": host, 
      "category": category 
     ] 
    } 
    return nil 
} 

  • Использовать значения по умолчанию, если свойства не установлены:

func createEvent() -> [String: String] { 
    return [ 
     "title": self.title ?? "", 
     "description": self.eventDescription ?? "", 
     "duration": self.duration ?? "", 
     "host": self.hostID ?? "", 
     "category": self.category ?? "" 
    ] 
} 
  • Или спросите себя, почему вы создаете словарь. Для этого у вас уже есть структура данных; вам действительно нужно его преобразовать?

В качестве побочного примечания нет причин для ваших методов set.... Префикс set имеет особое значение в Swift. Вызывающий должен просто сказать event.title = .... Если вам нужна какая-то специальная обработка сеттера, используйте опцию set, чтобы определить ее на свой объект.

+0

Благодарим вас за это объяснение, очень кратким и понятным. – jshah

+0

"title": self.title ?? "", развернуть значение self.titles, если оно объявлено как 'String?' – jshah

+0

Да, но лучше подумать об этом, так как принимает значение self.title, если оно есть, в противном случае берет значение следующего операнда. Я думаю, что люди слишком увлекаются «разворачиванием». –

0

Я полагаю, что не позволяет использовать его таким образом, потому что типа с «?» означает, что он не является обязательным, поэтому он может быть небезопасным из-за возможности отсутствия внутри. Вы должны сначала проверить эти свойства на nil и явно или неявно развернуть их для последующего использования в словаре.

... 
var category:String? 

if let cat = self.category? { 

    // setting up event information to save 
    var postEventData = [ 
     "category":cat 
    ] 
} 

В моем примере вы можете видеть, что я сделал только категорию необязательной, затем развернул ее и использовал в вашем словаре. Он отлично работает, так как никакая нулевая ценность никогда не попадет внутрь под ключом «категория».

Исправлено для более четкого понимания.

+0

Нужно ли это делать для всех переменных? Кажется странным только делать это для 1 из них. – jshah

+0

Да, вы должны проверить каждый из них. Я просто привел пример по одной переменной. –

+0

Зачем вы устанавливаете остальные из них вместе с переменной 1, которую вы проверили? Не могли бы вы просто переписать их, если бы вы их не проверили? – jshah

0

Прежде всего, вам нужен инициализатор для необязательных свойств, а во-вторых, словари Swift нуждаются в наличии всех ключей и значений одного и того же типа.

class Event: NSObject { 

    // When I remove the '?' on the variables it works but im not quite sure why 
    // Should I not be declaring variable as optional unwrapped? 

    // initialiser because of non-optional property 
    override init() { 
     self.invitedUsers = [] 
    } 

    var title:String? 
    var eventDescription:String? 
    var duration:Double? 
    var eventID:String? 
    var hostID:String? 
    var category:String? 
    var invitedUsers:[String?] 

    func createEvent(){ 

     // setting up event information to save 
     // explicitly set the values types as Any 
     var postEventData : Dictionary<String, Any> = [ 
      "title": self.title, 
      "description":self.eventDescription, 
      "duration":self.duration, 
      "host":self.hostID, 
      "category":self.category 
     ] 
    } 
} 
Смежные вопросы