2017-12-09 4 views
-1

現在、シングルトンでJSONを解析して複数のクラスが持つことができる最善の方法を判断しようとしています。そうすることで、シングルトンに格納されたデータはなくなり、デカップリングされたままになります。私はJSON解析関数を考え出しましたが、それを行うにはより良い方法があるのだろうかと疑問に思っています。現在使用している機能は次のとおりです。JSONをシングルトンで解析する

func parseJSONData(_ jsonData: Data?) -> [String : AnyObject]? 
    { 
    if let data = jsonData { 

     do { 
     let jsonDictionary = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String : AnyObject]//Parses data into a dictionary 

      // print(jsonDictionary) 

     return jsonDictionary 

     } catch let error as NSError { 
      print("Error: \(error.localizedDescription)") 
     } 
    } 
     return nil 
    } 
+0

'[String:AnyObject]'から '[String:Any]'への正しい辞書タイプの変更を使用して開始することができます。 'options:.mutableContainers'を使ったBtwは無意味です。 let optionsパラメータを省略して、メソッドをスローし、戻り値の型をオプションでないものに変更します。 'JSONSerialization.jsonObject(with:data)を次のように試してみてください。 [文字列:任意] ?? [:] ' –

+0

JSONデータを辞書に変換するのではなく、データを構造化してコード化してデコードしてから、Singletonプロパティに格納することをお勧めします –

答えて

1

以下のコードを試してみてください。これは、URLからデータを取得するためのSingletonの単なる例です。シングルトンを呼び出すために

final class Network { 

static let sharedInstance = Network() 

private init(){} 


var arrayJson = [[String : String]]() 




func get(completition: @escaping (_ json: [[String : String]]) -> Void){ 
    let Url = "Your String URL" 
    guard let loanUrl = URL(string: Url) else { return } 

    let request = URLRequest(url: loanUrl) 
    let task = URLSession.shared.dataTask(with: request, completionHandler: {(data, response, error) -> Void in 

     if let error = error { 
      print(error) 
      return 
     } 

     // Parse JSON data 

     if let data = data { 
      print(data) 
       do { 
       let jsonResult = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String:Any] 

       let jsons = jsonResult?["root"] as! [[String : String]] 
       self.arrayJson = jsons 
       DispatchQueue.main.async { 
        completition(jsons) 
       } 


      } catch {print(error)} 
     } 
    }) 
    task.resume() 
} 

、あなたはあなたのViewController.swiftに書き込みます:

Network.sharedInstance.get{ (tmp) in 
     print("ok") 
    } 

あなたが「OK」コンソールに印刷され表示されるとき、それはarrayJsonは人口であることを意味し、あなたがチェックすることができます

print(Network.sharedInstance.arraJson.count) 

配列にはいくつの要素があるかを見ることができます。

0

このような場合は、シングルトンは必要ありません。これは有効なアプローチですが、アプリ内のすべてにアクセスできる関数を提供する他の方法があります:

1)プロトコルを作成し、プロトコル拡張に関数を入れます。そうすれば、型を採用することでこれらの関数を自由に得ることができます。

2)それをグローバルな機能にします。あなたは単に任意のクラスや構造体の外に関数を宣言することができますし、あなたのアプリケーション全体は接頭辞なしで関数を呼び出すことができます。

3)静的関数またはクラス関数にします。次に、それを使用するために何かを初期化する必要はありません。

0

ネットワーク管理シングルトンで解析を実行することに実際のポイントはありません。もちろん、この問題への適切なアプローチは、アプリケーションで行う必要があるすべての接続に対してNetworkManagerを構築することですが、個人的にはモデルを構築するクラスに解析メソッドを実装することを提案します。あなたのアプローチは間違っているわけではなく、私を誤解しないでください。クラス定義にパーサメソッドを入れると、すべてのクラスが独自のパーサーを持つようになります。

また、return nilステートメントはparseJSONData関数の最後にあることに注意してください。したがって、この関数は常にnilを返します。その方法を正しい方法で動作させるには、return nil文をcatchブロックに入れるか、常にそうであるように、返す同じ型の関数内でローカル変数を宣言しなければならず、解析する場合そうです、それを記入してください。それが助けてくれたらと思います。