Я запускаю проект мобильного приложения с использованием Swift, SwiftUI и Cloud Firestore, где мне нужно найти пользователей на основе их различных настроек / предпочтений. Я решил это с помощью запроса collectionGroup. Но иногда (возможно, в 1 из 10 раз) запрос вылетает без какого-либо (для меня) понятного сообщения об ошибке. Составные индексы были созданы с использованием http-ссылок, предоставленных из XCode.
Я использую эту функцию:
func getUsersFromActivityPrefs(genders:[String], activities:[Int],skillScore_min:Int, skillScore_max:Int,completion:@escaping ([String]) -> ()) {
var matchUsers = [String]()
var count = 0
let db = Firestore.firestore()
for gender in genders {
for activity in activities {
let dbRef = db.collectionGroup("activity_preferences")
.whereField("gender", isEqualTo: gender)
.whereField("activityid", isEqualTo: activity)
.whereField("status", isEqualTo: true)
.whereField("skill_score", isGreaterThanOrEqualTo: skillScore_min)
.whereField("skill_score", isLessThanOrEqualTo: skillScore_max)
.limit(to: 100)
dbRef.getDocuments {( snap, err) in
count+=1
if err != nil {
print(err!.localizedDescription)
}
for i in snap!.documentChanges{
let uid = i.document.get("uid") as? String ?? ""
if uid != "" && !matchUsers.contains(uid) {
matchUsers.append(uid)
if matchUsers.count == 100 {
count = genders.count * activities.count
completion(matchUsers) //escaping completion handler
return
}
}
}
if count == genders.count * activities.count {
completion(matchUsers)
return
}
}
}
}
}
Я прикрепил журнал трассировки и сообщение о сбое от XCode. Я использую последнюю версию Firebase SDK, цель развертывания - iOS14. Это журнал трассировки, который я получаю:
thread # 1, queue = 'com.apple.main-thread', причина остановки = EXC_BAD_ACCESS (code = 1, address = 0x4f) frame # 0: 0x00007fff4b80dd66 AttributeGraphAG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, AGSwiftMetadata const*, bool*, long) + 322 frame #1: 0x00007fff4b81f1a5 AttributeGraph
AGGraphGetValue + 203 frame # 2: 0x00007fff55e7ffab_SwiftUIift_SwiftUIift_ ›() + 294 кадр № 4: 0x00007fff55b9583a SwiftUIpartial apply forwarder for implicit closure #2 (Swift.UnsafeMutableRawPointer, __C.AGAttribute) -> () in implicit closure #1 (A1.Type) -> (Swift.UnsafeMutableRawPointer, __C.AGAttribute) -> () in closure #1 () -> (Swift.UnsafeMutableRawPointer, __C.AGAttribute) -> () in closure #1 (Swift.UnsafePointer<A1>) -> AttributeGraph.Attribute<A> in AttributeGraph.Attribute.init<A where A == A1.Value, A1: AttributeGraph.StatefulRule>(A1) -> AttributeGraph.Attribute<A> + 26 frame #5: 0x00007fff4b808d03 AttributeGraph
AG :: Graph :: UpdateStack :: update () + 505 кадр № 6: 0x00007fff4b809199 AttributeGraphAG::Graph::update_attribute(AG::data::ptr<AG::Node>, bool) + 335 frame #7: 0x00007fff4b80d8e8 AttributeGraph
AG :: Graph :: value_ref (AG :: AttributeID, AGSwiftMetadata *, bool 130 кадр № 8: 0x00007fff4b81f1f3 AttributeGraphAGGraphGetValue + 281 frame #9: 0x00007fff561aeeb7 SwiftUI
SwiftUI.GraphHost.updatePreferences () - ›Swift.Bool + 39 кадр № 10: 0x00007fff55c9a8cf SwiftUISwiftUI.ViewGraph.updateOutputs(at: SwiftUI.Time) -> () + 95 frame #11: 0x00007fff5611310c SwiftUI
closure # 1 () -› () в (расширение в SwiftIost. .Double, updateDisplayList: Swift.Bool) - ›() + 1308 кадр # 12: 0x00007fff56112327 SwiftUI(extension in SwiftUI):SwiftUI.ViewRendererHost.render(interval: Swift.Double, updateDisplayList: Swift.Bool) -> () + 343 frame #13: 0x00007fff55ba07de SwiftUI
closure # 1 () -› () в SwiftUI. 12 кадр # 16: 0x0000000112ebea88 libdispatch.dylib_dispatch_client_callout + 8 frame #17: 0x0000000112eccf23 libdispatch.dylib
_dispatch_ma in_queue_callback_4CF + 1152 кадр № 18: 0x00007fff203a8276 CoreFoundation__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9 frame #19: 0x00007fff203a2b06 CoreFoundation
__CFRunLoopRun + 2685 кадр № 20: 0x00007fff203a1b9e CoreFoundationCFRunLoopRunSpecific + 567 frame #21: 0x00007fff2b773db3 GraphicsServices
GSEventRunModal + 139000 кадр # 22: 0x00007103b1b_art_freepik_f2_c0000_i_fxf246
nil
, если нужно, просто верните что-нибудь (возможно, рассмотрите возможность возврата объектаResult
). Вызывающий (этой функции) всегда должен ожидать какой-то ответ, чтобы общий поток работы всегда продолжался. 22.10.2020