Firebaseからデータを注文しようとしているので、最新の投稿が一番上に表示されます(Instagramなど)が、正しく機能させることができません。サーバーのタイムスタンプを使用する必要がありますか? 「createdAt」フィールドはありますか?
func getPosts() {
POST_REF.observeEventType(.Value, withBlock: { snapshot in
guard let posts = snapshot.value as? [String : [String : String]] else {
print("No Posts Found")
return
}
Post.feed?.removeAll()
for (postID, post) in posts {
let newPost = Post.initWithPostID(postID, postDict: post)!
Post.feed?.append(newPost)
}
Post.feed? = (Post.feed?.reverse())!
self.tableView.reloadData()
}, withCancelBlock: { error in
print(error.localizedDescription)
})
}
配列にreverse()のみを使用するだけでは、すべてを網羅するのに十分な方法ではありません。あなたが考える必要があるさまざまなことがあります:
データの取得中に制限し、append()を使用してからreverse()を使用します時間を節約するために。毎回すべてのアレイを削除する必要はありません。
スクロールトリガーまたはwillDisplayセルメソッド読み込み
はじめましょう。投稿の子を作成できますtimestampまたはdate/timeグローバル。 Instagram秒、週のように提供するには、UTC時間を使用することをお勧めします。だから私はこれを呼びます:(timeUTC)
すべての投稿を並べ替えるには、since1970タイムスタンプを使用します。したがって、これを(timestamp)と呼び、別のノードを(reversedTimestamp)として保持して、タイムスタンプに-プレフィックスを追加することもできます。したがって、このノードに対してqueryOrderedを使用する場合。 yourQuery.queryLimited(toFirst: 5)
を使用して最新の5件の投稿を処理できます。
1.timeUTCノードのUTC日付/時刻をSwift 3:で取得します
let date = Date()
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
formatter.timeZone = TimeZone(abbreviation: "UTC")
let utcTimeZoneStr = formatter.string(from: date)
+0000は世界時を意味します。 http://time.is/tr/UTC を見てください。
2。1970年以降のタイムスタンプを取得して、投稿をSwift 3:
let timestamp = (Date().timeIntervalSince1970 as NSString).doubleValue
let reversedTimestamp = -1.0 * timestamp
これで、このようにFirebaseの投稿に保存できます。
"posts" : {
"-KHLOy5mOSq0SeB7GBXv" : {
"timestamp": "1475858019.2306"
"timeUTC" : "2012-02-04 12:11:56 +0000"
},
"-KHLrapS0wbjqPP5ZSUY" : {
"timestamp": "1475858010.1245"
"timeUTC" : "2014-02-04 12:11:56 +0000"
},
5 x 5の投稿を取得するので、viewDidLoad
でqueryLimited(toFirst:5)を実行しています。
let yourQuery = ...queryOrdered(byChild: "reverseTimestamp")
.queryEnding(atValue: "\(self.pageOnTimestamp)", childKey: "reverseTimestamp")
yourQuery.observeSingleEvent(of: .value, with: { (snapshot) in
if snapshot.value is NSNull {
print("There is no post.")
}
else {
yourQuery.queryLimited(toFirst: 5).observeSingleEvent(of: .value, with: { (snapshot) in
self.posts.removeAll(keepingCapacity: true)
for (i, snap) in snapshot.children.enumerated() {
if let postAllDict = snapshot.value as? [String: AnyObject] {
if let postDict = postAllDict[(snap as AnyObject).key as String] as? [String: AnyObject] {
let post = Post(key: (snap as AnyObject).key as String, postDict: postDict)
self.posts.append(post)
}
}
}
completion(true)
})
}
})
ユーザーが最新の投稿に到達した場合は、以下のようにwillDisplay
メソッドで処理でき、loadMore関数を呼び出すことができます。
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if self.posts.count - 1 == indexPath.row {
// call loadMore function.
}
}
LoadMore()関数では、最新の投稿のタイムスタンプを処理し、それと同じようにクエリを開始および終了できるため、配列の前に追加しながら、次の最初の5つの投稿を簡単に続行できます。
Swift 3をニース形式で変換するには、こちらをご覧ください: Swift 3-UTCから時間前のラベル、12時間/ 24時間のデバイス時間を考えて変更
@tobeiosdevの回答に基づいて、データ構造を次のように定義します。
"posts" : {
"-KcOa8GXBl08V-WXeX8P" : {
"author" : "@giovanny.piñeros",
"hashtags" : [ "Hello", "World" ],
"text" : "Hola Mundo!!!!!",
"timestamp" : 5.08180914309278E8,
"title" : "Hello World",
"userid" : "hmIWbmQhfgh93"
}
タイムスタンプ属性を追加したことがわかるように、子が追加されたイベントを使用してデータをクエリすると、そのデータが投稿オブジェクトに渡され、テーブルビューがフィードする投稿の配列にそのオブジェクトが追加されます。
self.posts.append(post)
self.posts.sort(by: {$0.timestamp! > $1.timestamp!})
self.tableViewFeed.reloadData()
並べ替え方法を使用して、最新から古いものへと、投稿の希望順にデータを並べ替えることができました。このアプローチが誰にでも役立つことを願っています:)。