NSUserdefaults - Set<UITouch> und UIEvent - Objekte abspeichern

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • NSUserdefaults - Set<UITouch> und UIEvent - Objekte abspeichern

    Hallo Community,

    ich habe ein Problem bzgl. UserDefaults und UITouch bzw UIEvent Objekte.. wie es aussieht kann man nur eine Reihe von Objekten abspeichern. Darunter Strings, Ints, Bools etc... Wenn man Objekte anderer Art persistieren möchte, soll man ja laut Doku NSData verwenden und es entsprechend casten.

    Ich habe zu UserDefaults eine Extensions geschrieben um genau UIEvent-Objekte abzuspeichern:

    Quellcode

    1. extension UserDefaults {
    2. // UIEvent
    3. func event(forKey defaultName: String) -> UIEvent? {
    4. var event: UIEvent?
    5. if let eventData = data(forKey: defaultName) {
    6. event = NSKeyedUnarchiver.unarchiveObject(with: eventData) as? UIEvent
    7. }
    8. return event
    9. }
    10. func setEvent(_ value: UIEvent?, forKey defaultName: String) {
    11. var eventData: NSData?
    12. if let event = value {
    13. eventData = NSKeyedArchiver.archivedData(withRootObject: event) as NSData?
    14. }
    15. set(eventData, forKey: defaultName)
    16. }
    17. }
    Alles anzeigen



    Eine andere Klasse "Foil" hat so eine UIEvent Property die folgendermaßen aussieht:



    Quellcode

    1. class Foil: NSObject, NSCoding {
    2. var event: UIEvent? {
    3. get {
    4. return UserDefaults.standard.event(forKey: "Event")
    5. }
    6. set {
    7. UserDefaults.standard.setEvent(newValue, forKey: "Event")
    8. }
    9. }
    10. // .... NSCoding Methoden .....
    11. }
    Alles anzeigen


    Allerdings schmiert die App jedes mal ab, wenn ich ein UIEvent Objekt hinterlege.. Und zwar genau an dieser Stelle:


    Quellcode

    1. eventData = NSKeyedArchiver.archivedData(withRootObject: event) as NSData?



    Das selbe Spiel habe ich mit UIColor Objekten gespielt.. Da klappt es jedoch einwandfrei..

    Hat wer eine Idee, woran das liegen könnte? Was habe ich vergessen?

    Die Konsole spuckt mir folgendes aus:


    Quellcode

    1. 2017-08-09 16:50:47.911 LectureNotes[8444:9857872] Unbalanced calls to begin/end appearance transitions for <UINavigationController: 0x7f856601fe00>.
    2. 2017-08-09 16:50:56.332 LectureNotes[8444:9857872] -[UIEvent encodeWithCoder:]: unrecognized selector sent to instance 0x600000236060
    3. 2017-08-09 16:51:02.369 LectureNotes[8444:9857872] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIEvent encodeWithCoder:]: unrecognized selector sent to instance 0x600000236060'
    4. *** First throw call stack:
    5. (
    6. 0 CoreFoundation 0x0000000107c52b0b __exceptionPreprocess + 171
    7. 1 libobjc.A.dylib 0x00000001076b7141 objc_exception_throw + 48
    8. 2 CoreFoundation 0x0000000107cc2134 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
    9. 3 CoreFoundation 0x0000000107bd9840 ___forwarding___ + 1024
    10. 4 CoreFoundation 0x0000000107bd93b8 _CF_forwarding_prep_0 + 120
    11. 5 Foundation 0x00000001071f5b16 _encodeObject + 1224
    12. 6 Foundation 0x00000001072293fe +[NSKeyedArchiver archivedDataWithRootObject:] + 156
    13. 7 LectureNotes 0x0000000107056457 _TFE12LectureNotesCSo12UserDefaults8setEventfTGSqCSo7UIEvent_6forKeySS_T_ + 215
    14. 8 LectureNotes 0x00000001070565f7 _TToFE12LectureNotesCSo12UserDefaults8setEventfTGSqCSo7UIEvent_6forKeySS_T_ + 87
    15. 9 LectureNotes 0x0000000107050fed _TFC12LectureNotes4Foils5eventGSqCSo7UIEvent_ + 157
    16. 10 LectureNotes 0x000000010704e141 _TFC12LectureNotes26PresentationViewController11savetouchesfTGSqGVs3SetCSo7UITouch__4withGSqCSo7UIEvent__T_ + 481
    17. 11 LectureNotes 0x000000010704f613 _TTWC12LectureNotes26PresentationViewControllerS_12DrawDelegateS_FS1_11savetouchesfTGSqGVs3SetCSo7UITouch__4withGSqCSo7UIEvent__T_ + 99
    18. 12 LectureNotes 0x0000000107035d5d _TFC12LectureNotes8DrawView12touchesEndedfTGVs3SetCSo7UITouch_4withGSqCSo7UIEvent__T_ + 525
    19. 13 LectureNotes 0x0000000107035e36 _TToFC12LectureNotes8DrawView12touchesEndedfTGVs3SetCSo7UITouch_4withGSqCSo7UIEvent__T_ + 102
    20. 14 UIKit 0x00000001087ce7ea -[UIWindow _sendTouchesForEvent:] + 2707
    21. 15 UIKit 0x00000001087cff00 -[UIWindow sendEvent:] + 4114
    22. 16 UIKit 0x000000010877ca84 -[UIApplication sendEvent:] + 352
    23. 17 UIKit 0x0000000108f605d4 __dispatchPreprocessedEventFromEventQueue + 2926
    24. 18 UIKit 0x0000000108f58532 __handleEventQueue + 1122
    25. 19 CoreFoundation 0x0000000107bf8c01 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    26. 20 CoreFoundation 0x0000000107bde0cf __CFRunLoopDoSources0 + 527
    27. 21 CoreFoundation 0x0000000107bdd5ff __CFRunLoopRun + 911
    28. 22 CoreFoundation 0x0000000107bdd016 CFRunLoopRunSpecific + 406
    29. 23 GraphicsServices 0x000000010d7efa24 GSEventRunModal + 62
    30. 24 UIKit 0x000000010875f134 UIApplicationMain + 159
    31. 25 LectureNotes 0x00000001070543d7 main + 55
    32. 26 libdyld.dylib 0x000000010bc9965d start + 1
    33. 27 ??? 0x0000000000000001 0x0 + 1
    34. )
    35. libc++abi.dylib: terminating with uncaught exception of type NSException
    Alles anzeigen


    Ich danke im Voraus und schöne Grüße
    Onur :)
  • Eigentlich steht es schon in der Console: UIEvent implementiert nicht das NSCoding-Protokoll (siehe auch hier). Daher funktionieren die Archieving-Methoden nicht.

    Du müsstest UIEvent subclassen und die "initWithCode"- und "encodeWithCoder"-Methoden implementieren.

    Mattes

    Edit: Eine Extension ginge natürlich auch... UIColor implementiert übrigens NSSecureCoding, was wiederum von NSCoding erbt.
    Diese Seite bleibt aus technischen Gründen unbedruckt.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von MyMattes ()

  • ah verstehe, danke

    macmoonshine schrieb:

    BTW: Wofür willst du denn Events speichern?

    Ich baue ein App wo man mit dem Apple Pencil was zeichnen kann.. Eine einfache Linie mit Start- und Endpunkten will ich nicht abspeichern, da ich auf gewissen Eigenschaften von Set<UITouch> und UIEvent angewiesen bin (für gewisse Apple-Pencil Berechnungen).
  • Hallo,

    onur schrieb:

    ah verstehe, danke

    macmoonshine schrieb:

    BTW: Wofür willst du denn Events speichern?
    Ich baue ein App wo man mit dem Apple Pencil was zeichnen kann.. Eine einfache Linie mit Start- und Endpunkten will ich nicht abspeichern, da ich auf gewissen Eigenschaften von Set<UITouch> und UIEvent angewiesen bin (für gewisse Apple-Pencil Berechnungen).
    Das riecht für mich nach einem eigenen Dateiformat…

    Du kannst Dir ja für jede Zeichnung ein Datei schreiben, eine Plist und statt sie abc.plist zu nennen, nennst Du sie halt abc.mydrawfile
    Somit könntest Du dem Anwender später auch ermöglichen unterschiedliche Zeichnungen wieder zu öffnen.

    Viele Grüße
  • little_pixel schrieb:

    Das riecht für mich nach einem eigenen Dateiformat…


    Du kannst Dir ja für jede Zeichnung ein Datei schreiben, eine Plist und statt sie abc.plist zu nennen, nennst Du sie halt abc.mydrawfile
    Somit könntest Du dem Anwender später auch ermöglichen unterschiedliche Zeichnungen wieder zu öffnen.
    die Idee find ich interessant. Ist dieser Lösungsansatz auch performant? Weil zur Zeit ist Performance auch noch ein Problem.. Wenn ich sehr viele Linien gezeichnet habe, beginnt es langsam aber sicher an zu ruckeln und bei weiteren Linien laggt es dann doch ganz schön. Ich baue mir auch jedes mal eine neue UIImage und zeichne darauf.. Zeichne ich wieder was darauf, verwerfe ich die alte und überschreibe sie mit einem neuen Image usw...

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von onur ()

  • Und wie wäre JSON? Oder besser SQlite? Oder Protocol Buffers oder MessagePack oder Cap'n Proto? Bedenke es hängt auch davon ab, was dann damit geschieht. Bleibt es auf dem Device? Wird es verschickt? Oder Gar gestreamt? Und was ist wichtiger Speicherbedarf oder Geschwindigkeit (schreiben/lesen/packen/entpacken)?
    * Kann Spuren von Erdnüssen enthalten.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von NSObject ()

  • onur schrieb:

    sondern? CoreData?
    Eine dokumenten-basierte App ist ein guter Ansatz. Ich würde mir auch noch mal überlegen, inwieweit du wirklich Events bzw. Event-Daten speichern willst. Ein Dokument soll ja schließlich eine Zeichnung und keine Abfolge von Stiftbewegungen sein. So eine Abstraktion bzw. Unterscheidung ist vielleicht am Anfang etwas nervig, erweist sich im Laufe der Zeit in der Regel als vorteilhaft.
    „Meine Komplikation hatte eine Komplikation.“
  • NSObject schrieb:

    Und wie wäre JSON? Oder besser SQlite? Oder Protocol Buffers oder MessagePack oder Cap'n Proto? Bedenke es hängt auch davon ab, was dann damit geschieht. Bleibt es auf dem Device? Wird es verschickt? Oder Gar gestreamt? Und was ist wichtiger Speicherbedarf oder Geschwindigkeit (schreiben/lesen/packen/entpacken)?
    Das ganze lässt sich mit der Notes App vergleichen.. dort kann man ja auch mit dem Apple Pencil malen.. Der Unterschied dabei ist, dass die View etwas anders aussieht (klar) und dass ein gewisser Anteil an View an einem Beamer mit ner eigenen View projiziert wird. Am Ende wird das gezeichnete per Mail verschickt (PDF Export), soll aber am Ende trotzdem noch auf dem Device sein. Und ich würde mal eher die Geschwindigkeit vorziehen.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von onur ()

  • Wenn es um Performance geht würde ich zu Flatbuffers oder Cape'n Porto tendieren. Wenn es eher um den Speicherbedarf geht mal MessagePack ansehen. Und soll es universell sein Protobuffer oder SQLite.

    Aber wenn Du es nicht über Plattformgrenzen hinweg verarbeiten / speichern musst, kannst Du auch bequem Core Data nehmen.
    * Kann Spuren von Erdnüssen enthalten.