2017-12-21 15 views
1

textMessagessendersMessages이라는 두 개의 배열이 있습니다. 내보기가로드되면 해당 배열을 읽고 각 메시지에 대한 새 레이블을 만들고 sendersMessages에 저장된 값에 따라 색을 변경하려고합니다.UserDefaults 배열은 계속적으로 nil을 반환합니다.

여기 내의 ViewController 코드 :

class ConversationViewController: UIViewController { 

    ///UserDefaults 
    let defaults = UserDefaults.standard 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     //Synchronise NSUserDefaults 
     defaults.synchronize() 

     //Load previous messages 
     let nMessages: Int = defaults.integer(forKey: "numberOfMessages") 
     let arrayOfMessages = defaults.array(forKey: "textMessages") 
     let arrayOfSenders = defaults.array(forKey: "sendersMessages") 

     var i = 1 
     for i in 0...nMessages { 
      let sender: String? = (arrayOfSenders?[i] as? String) 
      let text: String? = (arrayOfMessages?[i] as? String) 
      print("\(String(describing: sender)) sent the message: \(String(describing: text)) ; i = \(i)") 
      if text != nil { 
       if sender != nil { 
        displayNewMessage(text: text!, sentBy: sender!) 
       } 
      } 
     } 
    } 
} 

displayNewMessage() 기능은 sendMessage() (아래 참조 코드)를 호출하고 새 레이블을 만들지 만 UserDefaults을 읽거나 수정하지 않습니다. 당신이 볼 수 있듯이

func sendMessage(text: String, sentBy: String, time: Double){ 
    let defaults = UserDefaults.standard 
    var n = defaults.integer(forKey: "numberOfMessages") 
    var sentByArray = defaults.array(forKey: "sendersMessages") 
    var textArray = defaults.array(forKey: "textMessages") 

    sentByArray?.append(sentBy) 
    textArray?.append(text) 
    n = n + 1 

    defaults.set(sentByArray, forKey: "sendersMessages") 
    defaults.set(textArray, forKey: "textMessages") 
    defaults.set(n, forKey: "numberOfMessages") 

    //Synchronise NSUserDefaults 
    defaults.synchronize() 
} 

, 나는 (발신자를 저장하는 하나와 다른 하나는 텍스트를 저장하는) 두 개의 배열을 사용하고 int로 : 여기

내가 메시지를 저장하는 데 사용하는 기능입니다 얼마나 많은 메시지가 전송되었는지 알 수 있습니다. 콘솔 메시지의 다음

nil sent the message: nil ; i = 0 
nil sent the message: nil ; i = 1 
nil sent the message: nil ; i = 2 
nil sent the message: nil ; i = 3 
nil sent the message: nil ; i = 4 
nil sent the message: nil ; i = 5 
nil sent the message: nil ; i = 6 
nil sent the message: nil ; i = 7 
nil sent the message: nil ; i = 8 
nil sent the message: nil ; i = 9 
nil sent the message: nil ; i = 10 

이 아닌 내용을 인쇄하는 이유

은 누군가가 나에게 설명해 주시겠습니까?

답변

1

sendMessage 코드는 선택 사항이 nil이므로 배열의 값을 설정하지 않습니다.

func sendMessage(text: String, sentBy: String, time: Double){ 
    let defaults = UserDefaults.standard 
    var n = defaults.integer(forKey: "numberOfMessages") 
    var sentByArray = defaults.stringArray(forKey: "sendersMessages") ?? [] 
    var textArray = defaults.stringArray(forKey: "textMessages") ?? [] 

    sentByArray.append(sentBy) 
    textArray.append(text) 
    n = n + 1 

    defaults.set(sentByArray, forKey: "sendersMessages") 
    defaults.set(textArray, forKey: "textMessages") 
    defaults.set(n, forKey: "numberOfMessages") 
} 

을 그리고 당신은 특히 당신의 viewDidLoad 방법에 같은 값을 읽기 전에, synchronize를 호출 할 필요는 없습니다 :

당신이 필요합니다.

override func viewDidLoad() { 
    super.viewDidLoad() 

    //Load previous messages 
    let nMessages: Int = defaults.integer(forKey: "numberOfMessages") 
    let arrayOfMessages = defaults.stringArray(forKey: "textMessages") ?? [] 
    let arrayOfSenders = defaults.stringArray(forKey: "sendersMessages") ?? [] 

    for i in 0..<nMessages { 
     let sender = arrayOfSenders[i] 
     let text = arrayOfMessages[i] 
     print("\(sender) sent the message: \(text) ; i = \(i)") 
     displayNewMessage(text: text!, sentBy: sender!) 
    } 
} 

을 그리고 당신이 정말로 메시지의 수를 저장할 필요가 없습니다

그리고 당신은뿐만 아니라 viewDidLoad을 업데이트해야합니다. 배열에있는 객체의 수를 살펴보십시오.

다른 정보 - UserDefaults은 앱의 데이터를 저장할 장소가 아닙니다. 그리고 데이터의 각 인스턴스를 나타내는 struct이 있어야합니다. struct 코드 가능으로 만들고 (단일) 데이터 배열을 파일에 씁니다. 이 모든 것은 독자의 연습 문제로 남아 있습니다. 원래 질문의 범위를 훨씬 뛰어 넘기 때문입니다.

+0

빠른 답변 주셔서 감사합니다. 불행히도, 나는 여전히 응용 프로그램을 실행할 때 오류가 있습니다. my line'let sender : String? = (arrayOfSenders? [i] as String)'다음과 같은 오류가 발생합니다 :'스레드 1 : 치명적인 오류 : 인덱스가 범위를 벗어남'. 어떻게해야합니까? –

+0

1. 내 대답에 나와있는대로 그 줄을 변경해야합니다. 2. 'UserDefaults'가 이전 버그로 인해 울리지 않습니다. (장치/시뮬레이터에서) 앱을 삭제하고 깨끗한 사용자 기본값과 업데이트 된 코드로 다시 시작하십시오. – rmaddy

+0

고마워요! 그것은 효과가있다! –