1

I am writing an iOS app in Swift and the app collects user input from multiple app screens and in the last screen its supposed to POST the information collected to the server via API.

Now my question is, what is the best way to manage the collected data on the app? Should I use plist to save my form data ? It also has one image which I want to upload to my server from the final screen. How should I go about this?

PS: I also read about http://developer.apple.com/CoreData, but I'm not sure if this is the right way to go forward.

Any suggestion is greatly appreciated.

Nagendra Rao
  • 7,016
  • 5
  • 54
  • 92
  • 1
    Use NSUserDfault. You can convert image to data because NSUserDfault support only serialization objects like string, nsnumbers, nsdata, nsdate etc. – Blind Ninja Aug 31 '15 at 09:21
  • Better yet just save then on disk, use the document directory. You can save the array to disk directly if you make sure all object contain are `NSCoding` compliant. Putting it in the `NSUserDefaults` is not a good idea, it is ment for small settings data. Not images. – rckoenes Aug 31 '15 at 09:29
  • @rckoenes Save to disk as in I create an xml or json file (for saving variables ) and png/jpeg for saving images? – Nagendra Rao Aug 31 '15 at 09:39
  • 2
    You can also just save the hole `NSArray` to disk. Read the [Archives and Serializations Programming Guide](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Archiving/Archiving.html) – rckoenes Aug 31 '15 at 09:41
  • I did something similar, I just made a txt file and saved it in documents. CoreData and NSUserDefaults is too hardcore for this type of thing – TurtleFan Aug 31 '15 at 09:43

1 Answers1

1

UPDATE: to save your time - this is Swift 1.2 solution. I didn't test it on Swift 2 (likely secureValue flow have to be updated)

Looks like you are talking about user's details/profile (correct me if I wrong), for this amount of data - using NSUserDefault is totally ok.

For user preferences (if that the case!!) I would use something like Preference Manager:

import Foundation
import Security

class PreferencesManager {

    class  func saveValue(value: AnyObject?, key: String) {

        NSUserDefaults.standardUserDefaults().setObject(value, forKey: key)
        NSUserDefaults.standardUserDefaults().synchronize()

    }
    class  func loadValueForKey(key: String) -> AnyObject? {
        let r : AnyObject? = NSUserDefaults.standardUserDefaults().objectForKey(key)
        return r

    }

    class  func saveSecureValue(value: String?, key: String) {
        var dict = dictForKey(key)
        if let v = value {
            var data: NSData = v.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
            (SecItemDelete(dict as NSDictionary as CFDictionary))
            dict[kSecValueData as NSString] = v.dataUsingEncoding(NSUTF8StringEncoding,
                allowLossyConversion:false);
            var status = SecItemAdd(dict as NSDictionary as CFDictionary, nil)
        } else {
            var status = SecItemDelete(dict as NSDictionary as CFDictionary)
        }
    }

    class  func loadSecureValueForKey(key: String) -> String? {
        var dict = dictForKey(key)
        dict[kSecReturnData as NSString] = kCFBooleanTrue
        var dataRef: Unmanaged<AnyObject>?
        var value: NSString? = nil
        var status = SecItemCopyMatching(dict as NSDictionary as CFDictionary, &dataRef)
        if 0 == status {
            let opaque = dataRef?.toOpaque()
            if let op = opaque {
                value = NSString(data: Unmanaged<NSData>.fromOpaque(op).takeUnretainedValue(),
                    encoding: NSUTF8StringEncoding)
            }
        }

        let val :String? =  value as? String
        return val
    }

    class private func dictForKey(key: String) -> NSMutableDictionary {
        var dict = NSMutableDictionary()
        dict[kSecClass as NSString] = kSecClassGenericPassword as NSString
        dict[kSecAttrService as NSString] = key
        return dict
    }

}

You can use PreferencesManager.saveSecureValue for secure data (like password etc) and PreferencesManager.saveValue for the rest of values

Eugene Braginets
  • 856
  • 6
  • 16
  • Its similar to a user profile, but its more of an app that creates, say 100 profiles a day. Its not just one user profile information. – Nagendra Rao Aug 31 '15 at 09:59
  • I just want the data to be stored on the device until the final API call is made. Once that is done, I no longer need the data. – Nagendra Rao Aug 31 '15 at 10:00
  • 1
    No, then it's not the case: I would go then with writing to file in the Documents folder. In case of NSDictionary - just writeToFile, Also couple of good advices are here: http://stackoverflow.com/questions/27197658/writing-swift-dictionary-to-file – Eugene Braginets Aug 31 '15 at 10:05