0

我在发送字典列表作为字典中我的一个键的值时遇到问题。我正在发送一个代表游戏的字典,其中一个键值对是一个点列表。因此,对于我的“点”键,相应的值是字典列表。

var allPoints : [[String: String] = []
for playerScoreTracker in playerScoreTrackers!{
    for point in playerScoreTracker.points{
        let tempDict : [String : String] = ["type": point.typeOfPoint.rawValue, "scorer" : point.scorer.uuid]
        allPoints.append(tempDict)
    }
}
    
var parameters : Dictionary<String, Any> = [
    "playerOne": playerOne.uuid,
    ...
    "team_two_score": scoreboard.teamTwoScore,
    "confirmed": false,
    "points": allPoints
]

问题是,当我使用 Alamofire(据我所知使用 JSONEncoding.default)发送此字典时,它最终发送的内容与我想要的不同。我的 Alamofire 发送功能如下所示

static func post<T: Decodable>(url: String, parameters: [String: Any], returnType: T.Type, completion: @escaping (Bool, Any) -> Void) {
    AF.request(url, method: .post, parameters: parameters, headers: getHeaders()).responseDecodable(of: returnType.self) { response in
        guard let returnStatusCode = response.response?.statusCode else {
            let returnData : [String] = ["No connection."]
            completion(false, returnData)
            return
        }
        switch returnStatusCode {
        case 200, 201:
            let returnData = response.value!
            completion(true, returnData)
        case 400:
            var errorsDict : [String: [String]] = [:]
            do {
                errorsDict = try JSONDecoder().decode(Dictionary<String, [String]>.self, from: response.data!)
            } catch {
                errorsDict["my_side_errors"] = ["Couldn't decode json response."]
            }
            let errors : [String] = getErrorsFromParams(params: parameters, errorsDict: errorsDict)
            completion(false, errors)
        default:
            let errors : [String] = ["Error."]
            completion(false, errors)
        }
    }
}

出于某种原因,当它对我的参数进行编码时,它会像这样发送它们......

{
    'confirmed': ['0'], 
    'playerFour': ['8b52d186-ab60-438e-92f1-a3d35430ea81'], 
    'playerOne': ['f33e09b5-be8b-49e7-99c2-1e2df7512a71'], 
    'playerThree': ['583e0143-7352-4907-a806-a3b16baceefc'], 
    'playerTwo': ['24da0653-7fbc-41c3-8a47-bdefb9323eb2'], 
    'points[][type]': ['tk', 'tk'], 
    'points[][scorer]': ['8b52d186-ab60-438e-92f1-a3d35430ea81', '8b52d186-ab60-438e-92f1-a3d35430ea81'], 
    'team_one_score': ['12'], 
    'team_two_score': ['0'], 
    'time_ended': ['2021-09-11 10:54:00'], 
    'time_started': ['2021-09-11 10:53:57']
}

我作为点发送的字典列表被分成两个列表,一个列表用于数组中的每个键。

如果我在 Postman 中发送相同的 JSON,它可以正常工作并且完全符合我的要求。这是我在 Postman 中发送的 JSON...

{
    "playerOne": "f33e09b5-be8b-49e7-99c2-1e2df7512a71", 
    "playerTwo": "99028402-abdd-42dd-a8d9-48c05ba2787e", 
    "type": "pu", 
    "team_two_score": 0, 
    "time_started": "2021-09-11 12:33:44", 
    "time_ended": "2021-09-11 12:33:48", 
    "points": [
        {"scorer": "f33e09b5-be8b-49e7-99c2-1e2df7512a71", "type": "tk"}, 
        {"scorer": "f33e09b5-be8b-49e7-99c2-1e2df7512a71", "type": "tk"}, 
        {"type": "tk", "scorer": "f33e09b5-be8b-49e7-99c2-1e2df7512a71"}, 
        {"type": "tk", "scorer": "f33e09b5-be8b-49e7-99c2-1e2df7512a71"}, 
        {"type": "tk", "scorer": "f33e09b5-be8b-49e7-99c2-1e2df7512a71"}, 
        {"scorer": "f33e09b5-be8b-49e7-99c2-1e2df7512a71", "type": "tk"}
    ],
    "playerThree": "24da0653-7fbc-41c3-8a47-bdefb9323eb2", 
    "playerFour": "583e0143-7352-4907-a806-a3b16baceefc", 
    "team_one_score": 12, 
    "confirmed": false
}

发送的这个 JSON 可以在我的后端正常工作。我一生都无法弄清楚如何让 Swift 以这种方式对我的参数进行编码。

这是我发送参数之前的打印输出。

params: [
    "team_one_score": 13, 
    "points": [
        ["type": "tk", "scorer": "f33e09b5-be8b-49e7-99c2-1e2df7512a71"], 
        ["scorer": "f33e09b5-be8b-49e7-99c2-1e2df7512a71", "type": "tk"], 
        ["type": "tk", "scorer": "f33e09b5-be8b-49e7-99c2-1e2df7512a71"], 
        ["type": "tk", "scorer": "f33e09b5-be8b-49e7-99c2-1e2df7512a71"], 
        ["type": "tk", "scorer": "f33e09b5-be8b-49e7-99c2-1e2df7512a71"], 
        ["scorer": "f33e09b5-be8b-49e7-99c2-1e2df7512a71", "type": "sk"]
    ], 
    "time_started": "2021-09-11 12:12:26", 
    "confirmed": false, 
    "time_ended": "2021-09-11 12:12:30", 
    "playerThree": "583e0143-7352-4907-a806-a3b16baceefc",
    "team_two_score": 0, 
    "playerTwo": "24da0653-7fbc-41c3-8a47-bdefb9323eb2",
    "playerFour": "8b52d186-ab60-438e-92f1-a3d35430ea81",
    "playerOne": "f33e09b5-be8b-49e7-99c2-1e2df7512a71"
]

这是 cURLDescription 的输出

$ curl -v \
    -X POST \
    -H "User-Agent: DayOfDie/1.0 (aberard.DayOfDie; build:1; iOS 14.5.0) Alamofire/5.4.1" \
    -H "Accept-Encoding: br;q=1.0, gzip;q=0.9, deflate;q=0.8" \
    -H "Accept-Language: en;q=1.0" \
    -H "Authorization: Token be1d6e220931d0249e3d600ef9682909f39252ec" \
    -H "Content-Type: application/x-www-form-urlencoded; charset=utf-8" \
    -d "confirmed=0&playerFour=8b52d186-ab60-438e-92f1-a3d35430ea81&playerOne=f33e09b5-be8b-49e7-99c2-1e2df7512a71&playerThree=583e0143-7352-4907-a806-a3b16baceefc&playerTwo=24da0653-7fbc-41c3-8a47-bdefb9323eb2&points%5B%5D%5Btype%5D=sk&points%5B%5D%5Bscorer%5D=f33e09b5-be8b-49e7-99c2-1e2df7512a71&points%5B%5D%5Btype%5D=tk&points%5B%5D%5Bscorer%5D=f33e09b5-be8b-49e7-99c2-1e2df7512a71&points%5B%5D%5Btype%5D=tk&points%5B%5D%5Bscorer%5D=f33e09b5-be8b-49e7-99c2-1e2df7512a71&points%5B%5D%5Bscorer%5D=f33e09b5-be8b-49e7-99c2-1e2df7512a71&points%5B%5D%5Btype%5D=tk&points%5B%5D%5Bscorer%5D=f33e09b5-be8b-49e7-99c2-1e2df7512a71&points%5B%5D%5Btype%5D=tk&team_one_score=11&team_two_score=0&time_ended=2021-09-11%2012%3A18%3A55&time_started=2021-09-11%2012%3A18%3A51" \
"http://127.0.0.1:8000/games/"

拉尔姆想通了。出于某种原因,我的 alamofire 请求使用 url 编码而不是 json 编码对其进行编码。我刚刚在我的请求参数中添加了“编码:JSONEncoding.default”,现在一切正常。

4

0 回答 0