Итак, мне было поручено реализовать в приложении (iOS, Swift) функциональность "retweet", используя Parse.
Это было задано до здесь, но это a) довольно высокий уровень и b) я получаю задание под рукой - я не обязательно прошу помощи архитектурные решения, хотя, если кажется, что я, очевидно, чего-то не хватает, я рад принять обратную связь.
В моем приложении есть ПРИЧИНЫ, которые создаются пользователем. Существует также таблица FOLLOW с пользователем TO и FROM. Поэтому для начала я просто запрашиваю таблицу CAUSES с ограничением, которое USER, который разместил, должен соответствовать объектуId пользователя TO (где текущий пользователь является пользователем FROM) в таблице FOLLOW. Более кратко:
let getFollowedUsersQuery = PFQuery(className: Constants.kParseClassFollowers)
getFollowedUsersQuery.whereKey(Constants.kParseFieldFromUser, equalTo: PFUser.currentUser()!)
let causesQuery = PFQuery(className: Constants.kParseClassCauses)
causesQuery.whereKey(Constants.kParseFieldFromUser, matchesKey: Constants.kParseFieldToUser, inQuery: getFollowedUsersQuery)
causesQuery.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in
if let causes = objects {
for cause in causes {
// populate the tableview cells, etc.
}
}
})
Теперь у меня есть все причины от пользователей, за которыми я следую... что все довольно стандартно.
Здесь, где это становится сложно.
Каждая ПРИЧИНА также имеет отношение, называемое SUPPORTERS.
Теперь мне нужно архивировать способ получить все ПРИЧИНЫ от людей, за которыми я не следую, но которые имеют в своем списке сторонников пользователя, которого я придерживаюсь.
Мне еще предстоит найти элегантное решение, хотя я приближаюсь к "грубой силе", и это настолько громоздко и многословно, что лучшая половина моего мозга программиста кричит на меня, как Сьюзан Паутер...
Здесь пример:
let retweetQuery = PFQuery(className: Constants.kParseClassCauses)
retweetQuery.orderByDescending(Constants.kParseFieldCreatedAt)
retweetQuery.whereKey(Constants.kParseFieldFromUser, notEqualTo: PFUser.currentUser()!)
retweetQuery.whereKey(Constants.kParseFieldFromUser, doesNotMatchKey: Constants.kParseFieldToUser, inQuery: getFollowedUsersQuery)
retweetQuery.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in
if let causes = objects {
for cause in causes {
let supporterRelations = cause.relationForKey(Constants.kParseClassSupporters)
let supporterQuery = supporterRelations.query()
supporterQuery.findObjectsInBackgroundWithBlock { (supporters, error) in
if(error == nil && supporters?.count > 0) {
for supporter in supporters! {
let user:PFUser = supporter as! PFUser
getFollowedUsersQuery.whereKey(Constants.kParseFieldToUser, equalTo: user)
getFollowedUsersQuery.whereKey(Constants.kParseFieldFromUser, equalTo: PFUser.currentUser()!)
getFollowedUsersQuery.findObjectsInBackgroundWithBlock({ (results, error) -> Void in
if(error == nil && results?.count > 0) {
for result in results! {
// do stuff
}
}
})
}
}
}
}
}
})
Теперь это чистое безумие и невероятно расточительное (особенно учитывая, как Parse вычисляет свободный уровень), я считаю, что это может действительно сильно повлиять на мой лимит API, если оно будет перенесено на производство).
Уже выполнив два запроса, я полностью переделаю их, затем выполним другой запрос для каждой причины в отношениях SUPPORTER, затем выполните другой запрос для каждого пользователя в этом отношении, чтобы увидеть, следую ли я им... и как только я мне нужно пройти через поддерживаемые пользователем причины (из-за асинхронного возвращения запросов Parse я не чувствую, что могу просто вернуться обратно в родительские петли), которые я еще не реализовал, потому что я собираюсь бросить полотенце - должен быть лучший способ!
Я надеюсь, что здесь отсутствует стратегия...