将代码从 Objective C 转换为 SWIFT 时的常见函数问题



目前我一直在研究将代码从目标c转换为swift的任务。工作进展顺利,直到我遇到了一个在目标 c 中工作的通用可修复代码,但我不知道我应该如何在 swift 中做到这一点。

在目标 c 中工作的场景是。

我的 dataManager 类中有一个通用函数

- (void)saveRequest:(id)request forId:(NSNumber *)requestId {
WebRequest *requestData = [[WebRequest alloc] initWithEntity:[NSEntityDescription entityForName:WEB_REQUEST inManagedObjectContext:self.context] insertIntoManagedObjectContext:self.context];
requestData.data = [request toJSON];
requestData.requestId = requestId;
requestData.timestamp = [NSDate date];
[self save];
}

在我的项目中,已经创建了包含 toJSON 函数的请求类。 根据用户更改从我的控制器中,我创建了请求对象并将请求对象传递给此函数,该函数在请求类中调用 toJSON 函数,并且一切都在目标 c 中工作。

但是当我在 swift 中转换这个函数时,它不支持 id 作为函数输入变量,如果我使用 Any 代替 id,那么它会给出一个错误,即 Any 没有任何 toJSON 函数。

由于此函数很常见,因此不同的请求对象将来自不同的控制器。 我不知道我应该如何从听到更远的地方,如果有人有任何想法,请帮助我

你的类应该是这样的

class WebRequest:NSObject
{
var data :Data?
var requestId: NSNumber?
var timestamp: Date?
init(entity:String , insertIntoManagedObjectContext:NSManagedObjectContext)
{
//your code here
}
}

你的代码将如下所示

func saveRequest(request:Request, requestId:NSNumber)
{
let requestData = WebRequest(entity: "entityName", insertIntoManagedObjectContext:self.context)            
requestData.data = request.toJSON();
requestData.requestId = requestId;
requestData.timestamp = Date()
}

和 toJson(( 存在的请求类

class Request: NSObject
{
//has some members
func toJSON()->Data
{
return Data()
}
}

有一个现有的 Swift 协议,Codable(或者如果你愿意,你可以只做Encodable,因为Codable只是EncodableDecodable(,它明确设计用于表示 JSON(或其他格式(中的对象。

然后使用JSONEncoder(而不是JSONSerialization,例如(将对象编码为 JSON。请参阅编码和解码自定义类型:

考虑一个存储地标名称和创始年份的Landmark结构:

struct Landmark {
var name: String
var foundingYear: Int
}

Codable添加到继承列表中Landmark会触发满足EncodableDecodable的所有协议要求的自动一致性:

struct Landmark: Codable {
var name: String
var foundingYear: Int
}

然后您可以执行以下操作:

let landmark = Landmark(name: "Big Ben", foundingYear: 1859)
do {
let data = try JSONEncoder().encode(landmark)
print(String(data: data, encoding: .utf8)!)
} catch {
print(error)
}

这将产生这样的JSON:

{
"name": "Big Ben",
"foundingYear": 1859
}

有关详细信息,请参阅编码和解码自定义类型。

但是,如果你把你的类型Codable/Encodable,你可以完全停用你的toJSON方法。无需再编写代码来对 JSON 进行编码。


如果你在将项目从 Objective-C 转换为 Swift 时正在寻找更具战术性的编辑,你可以定义你自己的协议,比如JsonRepresentable,它有一个单一的方法要求,你的toJSON(或者你在转换过程中重命名了这种方法的任何内容(。

protocol JsonRepresentable {
func toJSON() -> Data
}

然后,对于已实现此方法的所有类型,只需添加此一致性。

理想情况下,返回到这些单独的文件并将方法移动到该协议的扩展名中,例如,对于您的第一个对象类型:

extension RequestObject1: JsonRepresentable { 
func toJSON() -> Data {
...
}
}

对于你的第二个:

extension RequestObject2: JsonRepresentable { 
func toJSON() -> Data {
...
}
}

等。

没有更简单的方法而不是在整个项目中更改它

我建议以上是最好的,但是,如果您不想回到所有这些单独的类型声明,您可以在定义JsonRepresentable的位置添加带有空扩展名的一致性:

extension RequestObject1: JsonRepresentable { }
extension RequestObject2: JsonRepresentable { }

只要这些类型实现了该方法,这些扩展就会让编译器知道它们是否符合你的协议。

无论如何,此方法可以使用此协议:

func save(_ request: JsonRepresentable, requestId: Int) {
let requestData = ...
requestData.data = request.toJSON()
requestData.requestId = requestId
requestData.timestamp = Date()
save()
}

相关内容

  • 没有找到相关文章

最新更新