访问字典Swift 3的数组

时间:2017-09-21 04:24:05

标签: ios swift facebook-graph-api facebook-sdk-4.0

我需要访问字典数组中的工作数据,我对此有点混淆。我使用swift 3.有人可以给我一些编码来完成它吗?

我正在使用此

let work: NSArray! = fbData.value(forKey: "work") as! NSArray
            if let position: NSArray = work[0] as! NSArray {
                let positionName: String = position.value(forKey: "name") as! String
                self.userWorkExpLabel.text = "\(positionName)" as String
            }

但我有这个答案: 无法投射类型' __ NSDictionaryI' (0x1106c7288)到NSArray' (0x1106c6e28)。

有API

{
"work": [
{
  "employer": {
    "id": "93643283467",
    "name": "Oracast"
  },
  "location": {
    "id": "111983945494775",
    "name": "Calgary, Alberta"
  },
  "position": {
    "id": "146883511988628",
    "name": "Mobile Developer"
  },
  "start_date": "2017-04-30",
  "id": "1446626725564198"
}
],

好的伙计们。我试过你发布的内容,现在我的内容是这样的:

一个结构类:

import Foundation

struct Worker{
let employer: Employer
let location: Location
let position: Position
let startDate:String
let id: String

init?(fromDict dict: Dictionary<String, Any>){
    guard let employer = Employer(fromDict: dict["employer"] as? Dictionary<String, String>),
        let location = Location(fromDict: dict["location"] as? Dictionary<String, String>),
        let position = Position(fromDict: dict["position"] as? Dictionary<String, String>),
        let startDate = dict["start_date"] as? String,
        let id = dict["id"] as? String else {
            return nil
    }

    self.employer = employer
    self.location = location
    self.position = position
    self.startDate = startDate
    self.id = id
}

}

struct Employer{
let id: String
let name: String

init?(fromDict dict:Dictionary<String, String>?){
    guard let id = dict?["id"],
        let name = dict?["name"] else{
            return nil
    }

    self.id = id
    self.name = name
 }
 }

struct Location {
let id:String
let name:String

init?(fromDict dict:Dictionary<String, String>?) {
    guard let id = dict?["id"],
        let name = dict?["name"] else {
        return nil
    }
    self.id = id
    self.name = name
}
}

struct Position {
let id:String
let name:String

init?(fromDict dict:Dictionary<String, String>?) {
    guard let id = dict?["id"],
        let name = dict?["name"] else {
        return nil
    }
    self.id = id
    self.name = name
}
} 

我创建了一个名为facebookGraphRequest的类。

import Foundation
import UIKit
import FBSDKCoreKit
import FBSDKLoginKit
import FBSDKShareKit

class facebookGraphRequest: NSObject {

class func graphRequestWork(completion: @escaping(_ error: Error?, _ facebookUserWork: Worker)-> Void){
    if ((FBSDKAccessToken.current()) != nil){
    let parameters = ["fields": "name, picture.width(198).height(198), location{location}, work{employer}, education, about, id"]

        let graphRequest: FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: parameters)
        graphRequest.start { (connection, result, error) in

            if ((error) != nil ){
                print(error!)
            }else {
                print(result!)

                func workersArray(data:Dictionary<String, Any>)->[Worker]?{
                    guard let arrayOfDict = data["work"] as? Array<Dictionary<String, Any>> else {
                        return nil
                    }

                    return arrayOfDict.flatMap({ Worker(fromDict: $0)})
                }

            }
        }
    }
}
}

我在viewController中使用:

调用此数据
func facebookLogin(){
    facebookGraphRequest.graphRequestWork { (error: Error?, facebookUserWork: Worker) in

        self.userNameJobPositionLabel.text = "\(facebookUserWork.position)"
        self.companyNameLabel.text = "\(facebookUserWork.employer)"
    }
}

有人知道发生了什么?标签没有任何变化。

我认为这种api比那更容易。我真的对这个过程感到困惑...对不起,如果它看起来像愚蠢的问题,但我真的因为这件事而弄乱我的想法......我真的需要你帮助的人。我的工作取决于:(

3 个答案:

答案 0 :(得分:1)

理想情况下,您应该引入如下的模型类:

struct Worker {
    let employer:Employer
    let location:Location
    let position:Position
    let startDate:String
    let id:String

    init?(fromDict dict:Dictionary<String, Any>) {
        guard let employer = Employer(fromDict: dict["employer"] as? Dictionary<String, String>), let location = Location(fromDict: dict["location"] as? Dictionary<String, String>), let position = Position(fromDict: dict["position"] as? Dictionary<String, String>), let startDate = dict["start_date"] as? String, let id = dict["id"] as? String else {
            return nil
        }

        self.employer = employer
        self.location = location
        self.position = position
        self.startDate = startDate
        self.id = id
    }
}

struct Employer {
    let id:String
    let name:String

    init?(fromDict dict:Dictionary<String, String>?) {
        guard let id = dict?["id"], let name = dict?["name"] else {
            return nil
        }
        self.id = id
        self.name = name
    }
}

struct Location {
    let id:String
    let name:String

    init?(fromDict dict:Dictionary<String, String>?) {
        guard let id = dict?["id"], let name = dict?["name"] else {
            return nil
        }
        self.id = id
        self.name = name
    }
}

struct Position {
    let id:String
    let name:String

    init?(fromDict dict:Dictionary<String, String>?) {
        guard let id = dict?["id"], let name = dict?["name"] else {
            return nil
        }
        self.id = id
        self.name = name
    }
}

现在,您可以引入如下函数:

func workersArray(data:Dictionary<String, Any>)->[Worker]?{
        guard let arrayOfDict = data["work"] as? Array<Dictionary<String, Any>> else {
            return nil
        }

        return arrayOfDict.flatMap({ Worker(fromDict: $0)})
    }

答案 1 :(得分:1)

在尝试使用Swift 4并朝着@PuneetSharma演示的方向前进后,我发现使用原始JSON文本CodableJSONDecoder时更容易:

import Foundation

// define the nested structures

struct Work: Codable {
  let work: [Worker]
}

struct Worker: Codable {
  let employer: Employer
  let location: Location
  let position: Position
  let startDate: String
  let id: String

  // needed a custom key for start_date
  enum CodingKeys : String, CodingKey {
    case employer, location, position, startDate = "start_date", id
  }
}

struct Employer: Codable {
  let id: String
  let name: String
}

struct Location: Codable {
  let id: String
  let name: String
}

struct Position: Codable {
  let id: String
  let name: String
}

// turn the text into `Data` and then 
// decode as the outermost structure

if let jsonData = json.data(using: .utf8),
  let work = try? JSONDecoder().decode(Work.self, from: jsonData) {
  print(work)
}

结果是Work结构,包含所有数据:

Work(work: [
  Model.Worker(employer : Model.Employer(id  : "93643283467",
                                         name: "Oracast"),
               location : Model.Location(id  : "111983945494775",
                                         name: "Calgary, Alberta"),
               position : Model.Position(id  : "146883511988628",
                                         name: "Mobile Developer"),
               startDate: "2017-04-30", 
               id       : "1446626725564198")
])

(我对输出进行了格式化以澄清产生的结构。)

只需使用Codable即可免费获得大量功能。从另一个方面走,并从任何结构中生成JSON文本也很简单。

答案 2 :(得分:0)

使用此代码

        long lngSum = 0;


        Parallel.ForEach(Partitioner.Create(0L, lngMax + 1), range =>
        {
            long local = 0;
            //4cores : 9 ranges
            //64cores : 97 ranges
            for (long i = range.Item1; i <= range.Item2 - 1; i++)
            {
                if (i % 2 == 0)
                {
                    local += i;
                }
                else
                {
                    local -= i;
                }
            }
            Interlocked.Add(ref lngSum,  local);
        });