使用日期字符串 Swift 解析大型 json 数据时的高 CPU 使用率

High CPU Usage when parsing large json data with Date Strings Swift

我正在开发一个聊天应用程序。我得到包含与对话相关的数据的对话列表。 Json 响应如下所示

[
  {
    "id": "1021",
    "title": "Test Group",
    "memberCount": 250,
    "isGroup": true,
    "ownerId": "18646",
    "createdAt": "2017-08-24T12:05:06.000Z",
    "type": "private",
    "lastReadAt": {
      "18646": "2020-01-29T06:48:53.700Z",
      "18664": "2020-01-29T07:12:41.613Z",
      "18714": "2020-01-29T07:12:41.613Z",
      // 247 More Records
    },
    "unreadMessageCount": 0,
    "mute": false,
    "isActive": true,
    "isAdmin": true,
    "isDeleted": false,
    "updatedAt": "2020-01-29T07:12:41.124Z",
    "lastMessage": {
      "id": "18a16164-657c-420a-887d-5408f1479619",
      "conversationId": "1021",
      "type": "normal",
      "createdAt": "2020-01-29T07:12:41.124Z",
      "updatedAt": "2020-01-29T07:12:41.124Z",
      "body": "hi",
      "ownerId": "18646",
      "attachments": [],
      "owner": {
          "id": "18646",
          "displayName": "sydney millers",
          "profileImageUrl": "https://sample-file-url/media/fbef1bb47eb85fb2979b135ed04e0eb3.png"
      },
      "mentionedUsers": []
    }
  },
  {
    "id": "1021",
    "title": "Test Group 2",
    "memberCount": 250,
    "isGroup": true,
    "ownerId": "18646",
    "createdAt": "2017-08-24T12:05:06.000Z",
    "type": "private",
    "lastReadAt": {
      "18646": "2020-01-29T06:48:53.700Z",
      "18664": "2020-01-29T07:12:41.613Z",
      "18714": "2020-01-29T07:12:41.613Z",
      // 247 More Records
    },
    "unreadMessageCount": 0,
    "mute": false,
    "isActive": true,
    "isAdmin": true,
    "isDeleted": false,
    "updatedAt": "2020-01-29T07:12:41.124Z",
    "lastMessage": {
      "id": "18a16164-657c-420a-887d-5408f1479619",
      "conversationId": "1021",
      "type": "normal",
      "createdAt": "2020-01-29T07:12:41.124Z",
      "updatedAt": "2020-01-29T07:12:41.124Z",
      "body": "hi",
      "ownerId": "18646",
      "attachments": [],
      "owner": {
          "id": "18646",
          "displayName": "sydney millers",
          "profileImageUrl": "https://sample-file-url/media/fbef1bb47eb85fb2979b135ed04e0eb3.png"
      },
      "mentionedUsers": []
    }
  }
]

lastReadAt 基本上包含群组成员最后一次阅读对话时的信息。现在要获取最后一条消息的状态,无论它是否被所有人阅读并将其放入 table 单元格中,我必须找到最旧的日期并将其与消息日期进行比较。但是要比较日期,我必须将它们从字符串转换为日期。现在假设有 10 个对话,每个对话包含 250 个成员。所以有很多任务,所以我的 cpu 使用率达到 100%。任何更好的解决方案。对于 swift 我使用下面的函数

func getMessageStatus(itemMessageDate: Date) -> BaseMessageStatus {
        let dateTransformer = ISODateTransform() // Custom Date Transformer Same as of ios default but with a fixed date format.
        if let lastReadInfoDic = self.conversation?.lastReadDictionary {
            var lastReadData = [String:Date]()
            lastReadInfoDic.forEach({(id,date) in
                if let memberReadDate = dateTransformer.transformFromJSON(date) {
                    lastReadData.updateValue(memberReadDate, forKey: id)
                }
            })
            let sortedData = lastReadData.sorted(by: {[=14=].value < .value})
            if let oldestReader = sortedData.first {
                let oldestReadDate = oldestReader.value
                if itemMessageDate <= oldestReadDate {
                    return .seen
                } else {
                    return .sent
                }
            }
        }
        return .sent
    }

如果我没看错的话,您需要 self.conversation?.lastReadDictionary 中的最短日期。看起来 lastReadDictionary[String: String].

如果是,则使用compactMapValues(_:)[String: String]变成[String: Date]。接下来,使用 min(_:) 查找最早的日期。

func getMessageStatus(itemMessageDate: Date) -> BaseMessageStatus {
    let dateTransformer = ISODateTransform()

    let oldestReader = conversation?.lastReadDictionary
        .compactMapValues { dateTransformer.transformFromJSON([=10=]) }
        .min { [=10=].value < .value } // NOTE: Comparing Date objects.

    guard let oldestDate = oldestReader?.value else {
        return .sent
    }

    if itemMessageDate <= oldestDate {
        return .seen
    } else {
        return .sent
    }
}

是否所有时间字符串都使用 Z 时区?如果是这样,那么您可以使用字符串比较来查找最早的 ISO 时间字符串。获得最早的字符串后,将那个 ISO 时间字符串转换为 Date.

func getMessageStatus(itemMessageDate: Date) -> BaseMessageStatus {
    let dateTransformer = ISODateTransform()

    let oldestElement = conversation?.lastReadDictionary
        .min { [=11=].value < .value } // NOTE: Comparing String objects.

    guard let string = oldestElement?.value, let oldestDate = dateTransformer.transformFromJSON(string) else {
        return .sent
    }

    if itemMessageDate <= oldestDate {
        return .seen
    } else {
        return .sent
    }
}