You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS开发:使用HandyJSON解析String类型JSON报错,求解决方案

Fixing "Type 'String' does not conform to protocol 'HandyJSON'" Error

Hey there! Let's break down why you're hitting this error and how to fix it quickly.

Why the Error Happens

Your BaseResponse class requires its generic type T to conform to the HandyJSON protocol, but Swift's native String type doesn't implement this protocol out of the box. That's exactly what the compiler is complaining about when you try to use BaseResponse<String>.

The cleanest way to handle string values in HandyJSON is to create a simple wrapper class that conforms to HandyJSON and wraps your string content. Here's how:

First, add this wrapper class to your project:

import HandyJSON

class StringWrapper: HandyJSON {
    var value: String?
    
    // Required empty initializer for HandyJSON
    required init() {}
    
    // Optional convenience initializer
    init(value: String?) {
        self.value = value
    }
    
    // Custom mapping to handle raw string values from JSON
    func mapping(mapper: HelpingMapper) {
        mapper <<< self.value <-- CustomTransform(
            fromJSON: { rawValue in
                return rawValue as? String
            },
            toJSON: { stringValue in
                return stringValue
            }
        )
    }
}

Then update your API call code to use StringWrapper instead of String:

func updateMedicalHelpStatus(username: String, password: String, access_token: String, status: Int) {
    AF.request(MainApi.feedsListBegin,
               parameters: ParametersApi.parametersTokenStatus(access_token: access_token, status: status),
               encoding: URLEncoding.default,
               headers: HTTPHeadersApi.headersLoginPassword(username: username, password: password)).responseJSON { response in
        switch response.result {
        case .success:
            // Skip unnecessary JSONSerialization step - use response.data directly
            if let data = response.data, let reqJSONStr = String(data: data, encoding: .utf8) {
                let jsonResponse = BaseResponse<StringWrapper>.deserialize(from: reqJSONStr)
                if jsonResponse?.success == true {
                    // Access the string value with jsonResponse?.body?.value if needed
                    self.view.updateMedicalHelpStatusSuccessfully()
                } else {
                    self.view.error(message: jsonResponse?.errorMessage ?? "Unknown error")
                }
            }
        case .failure(let error):
            self.view.error(message: "\(error)")
        }
    }
}

Solution 2: Extend String to Conform to HandyJSON

If you prefer not to use a wrapper, you can extend Swift's String to conform to HandyJSON. Note that this works best if your JSON's body field is a raw string:

import HandyJSON

extension String: HandyJSON {
    // Required empty initializer for HandyJSON
    public required init() {}
    
    // Empty mapping since we're dealing with a raw string
    public mutating func mapping(mapper: HelpingMapper) {}
}

With this extension, your original BaseResponse<String>.deserialize(from: reqJSONStr) call will work without modification. However, be cautious with this approach—if your JSON's body ever changes to an object instead of a string, this extension might cause unexpected behavior.

Bonus: Optimize Your JSON Handling

You can simplify your code by skipping the JSONSerialization step entirely. The response.data from Alamofire already contains the raw JSON data, so you can convert it directly to a string without re-serializing the parsed JSON object. This makes your code more efficient and cleaner.


内容的提问来源于stack exchange,提问作者Gennadii Ianchev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:27:07