独自Documentクラス

<p>Traditional version of MVC as a compound pattern</p>

![MVC.png](https://qiita-image-store.s3.amazonaws.com/0/12540/a1618124-cd47-afd7-9544-c6a6f97af7ba.png)

<p>Cocoa version of MVC as a compound design pattern</p>

![Cocoa.png](https://qiita-image-store.s3.amazonaws.com/0/12540/ae3e1086-ac7a-4f1b-6acc-ce95cfda4bf0.png)

![NS.png](https://qiita-image-store.s3.amazonaws.com/0/12540/8956fe3b-7543-0214-43ee-131b939c2e78.png)

<ul>
<li>iOS 5 からUIDocumentクラスが用意されたが、少々、オーバースペック。</li>
<li>筆者は、以前から、独自のDocumentクラスを用意していた。</li>
</ul>

<p>Documentクラスはモデル・コントローラ</p>

![Document.png](https://qiita-image-store.s3.amazonaws.com/0/12540/95ac1172-f16b-0434-70e2-7381a4fc8353.png)

<p>Documentクラスの例</p>

```swift
class Document {
    var version: String
    
    private var _uniqueIdentifier: String
    var uniqueIdentifier: String {
        return _uniqueIdentifier
    }

    static let sharedInstance: Document = {
        let instance = Document()
        return instance
    }()
    
    init() {
        let infoDictionary = Bundle.main.infoDictionary! as Dictionary
        self.version = infoDictionary["CFBundleShortVersionString"]! as! String
        self._uniqueIdentifier = ""
    }
    
    deinit {
    }
    
    func load() {
        loadDefaults()
    }
    
    func save() {
        updateDefaults()
    }
    
    private func clearDefaults() {
        let userDefaults = UserDefaults.standard
        if userDefaults.object(forKey: "version") != nil {
            userDefaults.removeObject(forKey: "version")
        }
        if userDefaults.object(forKey: "uniqueIdentifier") != nil {
            userDefaults.removeObject(forKey: "uniqueIdentifier")
        }
    }
    
    private func updateDefaults() {
        let userDefaults = UserDefaults.standard
        
        var versionString: String = ""
        if userDefaults.object(forKey: "version") != nil {
            versionString = userDefaults.object(forKey: "version") as! String
        }
        if versionString.compare(self.version) != .orderedSame {
            userDefaults.setValue(self.version, forKey: "version")
            userDefaults.synchronize()
        }
        
        var uniqueIdentifier: String = ""
        if userDefaults.object(forKey: "uniqueIdentifier") != nil {
            uniqueIdentifier = userDefaults.object(forKey: "uniqueIdentifier") as! String
        }
        if uniqueIdentifier.compare(self.uniqueIdentifier) != .orderedSame {
            userDefaults.setValue(self.uniqueIdentifier, forKey: "uniqueIdentifier")
            userDefaults.synchronize()
        }
    }
   private func loadDefaults() {
        let userDefaults = UserDefaults.standard
        
        var versionString: String = ""
        if userDefaults.object(forKey: "version") != nil {
            versionString = userDefaults.object(forKey: "version") as! String
        }
        if versionString.compare(self.version) != .orderedSame {
            /* バージョン不一致対応 */
            clearDefaults()
            _uniqueIdentifier = UUID.init().uuidString
        }
        else {
            /* 読み出し */
            if userDefaults.object(forKey: "uniqueIdentifier") != nil {
                _uniqueIdentifier = userDefaults.object(forKey: "uniqueIdentifier") as! String
            }
        }
    }
    
    private func modelDir() -> String {
        let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
        if paths.count < 1 {
            return ""
        }
        var path = paths[0]
        
        path = path.appending(".model")
        return path
    }
    
    private func modelPath() -> String {
        let path = modelDir().appending("/model.dat")
        return path;
    }
}
```

<p>シングルトンを使わない例</p>


```swift
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
   public let document = Document()
    :
}
```

```swift
let delegate = UIApplication.shared.delegate as! AppDelegate
let document = delegate.document
print(document)
```


【関連情報】
<a href="https://cocoa-kanto.connpass.com/">BUKURO.swift</a><br />
<a href="https://www.facebook.com/groups/cocoa.kanto/">Cocoa勉強会 関東</a><br />
<a href="https://mosa.connpass.com/">MOSA</a><br />
<a href="http://www.bitz.co.jp/weblog/">Cocoa練習帳</a><br />
<a href="https://qiita.com/m_yukio>Qiita</a><br />