Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用swift 3.0和CloudKit创建一个feed,该feed将来自不同其他记录的记录混合在一起,并限制为一个数字?_Swift_Database_Xcode_Cloudkit - Fatal编程技术网

如何使用swift 3.0和CloudKit创建一个feed,该feed将来自不同其他记录的记录混合在一起,并限制为一个数字?

如何使用swift 3.0和CloudKit创建一个feed,该feed将来自不同其他记录的记录混合在一起,并限制为一个数字?,swift,database,xcode,cloudkit,Swift,Database,Xcode,Cloudkit,所以我一直在开发一款应用程序,它的工作原理基本上类似于facebook(简单得多),但更适合学校。它包含提要、带有帖子的类、带有帖子的组、带有帖子的朋友等等。我想要的是能够从我所在的朋友、团体和班级获取帖子,并将它们加载到新闻提要中的tableView中 数据库的结构: Post { (...) user: Reference likes: Reference list //users comments: Reference list //comments } User

所以我一直在开发一款应用程序,它的工作原理基本上类似于facebook(简单得多),但更适合学校。它包含提要、带有帖子的类、带有帖子的组、带有帖子的朋友等等。我想要的是能够从我所在的朋友、团体和班级获取帖子,并将它们加载到新闻提要中的tableView中
数据库的结构:

Post {
   (...)
   user: Reference
   likes: Reference list //users
   comments: Reference list //comments
}

User {
   (...)
   name: String
   surname: String
   friends: Reference list
   posts: Reference list
}

Class {
   (...)
   posts: Reference list 
}
到目前为止,我的新闻提要(相关)代码:

// Class used for controlling CloudKit
class DatabaseController {  
        var publicDatabase = CKContainer.default().publicCloudDatabase

    func reload() {
        publicDatabase = CKContainer.default().publicCloudDatabase
    }

    func networkCheck() -> Bool {
        var networkConnection = true
        doesRecordExist(withRecordName: "test", withFieldName: "test", equalTo: "test") { _, _, error in
            switch CKError(_nsError: error!) {
            case CKError.networkFailure, CKError.networkUnavailable, CKError.serviceUnavailable: networkConnection = false
            default: break
            }
        }
        return networkConnection
    }

    //Q U E R I E S

        func doesRecordExist(withRecordName: String, withFieldName: String, equalTo: String, completionHandler: @escaping (Bool?, CKRecord?, NSError?) -> Void) {
        print(withFieldName,equalTo)
        //this function checks if a record with specified value of a specified field exists.


        //initiating the query
        let predicate = NSPredicate(format: "\(withFieldName) == %@", equalTo)
        let query = CKQuery(recordType: withRecordName, predicate: predicate)
        publicDatabase.perform(query, inZoneWith: nil) {results, error in
            if error != nil {
                //if there is an error
                completionHandler(nil, nil, error as NSError?)
                return
            }
            guard let results = results else {
                //if reults are nil
                completionHandler(nil, nil, error as NSError?)
                print("error 2")
                return
            }

            if results.count == 1 {
                //if found
                completionHandler(true, results[0], nil)
                print(results)
            } else {
                //if not found
                completionHandler(false, nil, nil)
                print("not found")
            }
        }
    }

    func getAllRecords(withRecordType: String, withDesiredKeys: [String], sortForkey: String, ascending: Bool, withResultLimit: Int, operations:Int, completionHandler: @escaping ([CKRecord], NSError?) -> Void) {

        //prepare the variables to create a query for wanted records and retrieve them.
        var records: [CKRecord] = []
        let predicate = NSPredicate(value: true)
        let sort = NSSortDescriptor(key: sortForkey, ascending: ascending)

        let query = CKQuery(recordType: withRecordType, predicate: predicate)
        query.sortDescriptors = [sort]

        //limiting the query using operation
        let operation = CKQueryOperation(query: query)
        operation.desiredKeys = withDesiredKeys
        operation.resultsLimit = withResultLimit

        //completing the query
        operation.recordFetchedBlock = { record in
            records.append(record)
            print(1)
        }

        //executing the operation
        operation.queryCompletionBlock = { [unowned self] (cursor, error) in
            var count = 0

            //checking weather there is a need for more than one operations
            if error != nil && count < operations {
                count += 1
                let newOperation = CKQueryOperation(cursor: cursor!)
                newOperation.queryCompletionBlock = operation.queryCompletionBlock
                self.publicDatabase.add(newOperation)
            } else {
                print(2)
                completionHandler(records, nil)
            }

        }

        publicDatabase.add(operation)
    }
}
//用于控制CloudKit的类
类数据库控制器{
var publicDatabase=CKContainer.default().publicCloudDatabase
func reload(){
publicDatabase=CKContainer.default().publicCloudDatabase
}
func networkCheck()->Bool{
var networkConnection=true
doesRecordExist(记录名为“test”,字段名为“test”,相等于“test”){uu,u,错误在
开关CKError(\n错误:错误!){
案例CKError.networkFailure,CKError.networkUnavailable,CKError.serviceinavailable:networkConnection=false
默认值:中断
}
}
返回网络连接
}
//Q U E R I S
func doesRecordExist(withRecordName:String、withFieldName:String、equalTo:String、completionHandler:@escaping(Bool?、CKRecord?、NSError?)->Void){
打印(带字段名,等号)
//此函数用于检查是否存在具有指定字段的指定值的记录。
//启动查询
let predicate=NSPredicate(格式:“\(带字段名)=%@”,等号)
let query=CKQuery(记录类型:withRecordName,谓词:谓词)
perform(query,inZoneWith:nil){results,错误在
如果错误!=nil{
//如果有错误
completionHandler(nil,nil,错误为NSError?)
返回
}
guard let results=其他结果{
//如果reults为零
completionHandler(nil,nil,错误为NSError?)
打印(“错误2”)
返回
}
如果results.count==1{
//如果找到
completionHandler(true,结果[0],nil)
打印(结果)
}否则{
//如果找不到
completionHandler(false、nil、nil)
打印(“未找到”)
}
}
}
func getAllRecords(withRecordType:String,withDesiredKeys:[String],SortWorkey:String,升序:Bool,withResultLimit:Int,operations:Int,completionHandler:@escaping([CKRecord],NSError?)->Void){
//准备变量以创建所需记录的查询并检索它们。
变量记录:[CKRecord]=[]
let谓词=NSPredicate(值:true)
让sort=NSSortDescriptor(键:SortWorkey,升序:升序)
let query=CKQuery(记录类型:withRecordType,谓词:谓词)
query.sortDescriptors=[sort]
//使用操作限制查询
let operation=CKQueryOperation(查询:query)
operation.desiredKeys=带desiredKeys
operation.resultsLimit=withResultLimit
//完成查询
operation.recordFetchedBlock={中的记录
记录。追加(记录)
印刷品(1)
}
//执行操作
operation.queryCompletionBlock={[unowned self](光标,错误)位于
变量计数=0
//检查天气需要不止一次操作
如果错误!=nil&&count<操作{
计数+=1
让newOperation=CKQueryOperation(游标:游标!)
newOperation.queryCompletionBlock=operation.queryCompletionBlock
self.publicDatabase.add(newOperation)
}否则{
印刷品(2)
completionHandler(记录,无)
}
}
publicDatabase.add(操作)
}
}

类MyFeedTViewController:UITableViewController{
var posts:[CKRecord]!=[]
var database=DatabaseController()
变量定时器:定时器!
重写func viewDidLoad(){
super.viewDidLoad()
timer=timer.scheduledTimer(时间间隔:60.0,目标:self,选择器:#选择器(MyFeedTViewController.refresh),userInfo:nil,repeats:true)
计时器。火()
database.getAllRecords(带RecordType:“Post”,带DesiredKey:[“user”,“text”,“comments”,“Pluses”],SortWorkey:“creationDate”,升序:false,带ResultLimit:5,操作:1){记录,错误
如果错误==nil{
self.posts=记录
DispatchQueue.main.async{
self.tableView.reloadData()
}
}
}
}
func刷新(){
database.getAllRecords(带RecordType:“Post”,带DesiredKey:[“user”,“text”,“comments”,“Pluses”],SortWorkey:“creationDate”,升序:false,带ResultLimit:5,操作:1){记录,错误
如果错误==nil{
如果记录!=self.posts{
self.posts=记录
DispatchQueue.main.async{
self.tableView.reloadData()
self.refreshControl?.endRefreshing()
}
}
}
}
}
//标记:-表视图数据源
重写func numberOfSections(在tableView:UITableView中)->Int{
//#警告未完成执行,返回节数
返回1
}
重写func tableView(tableView:UITableView,numberofrowsinssection:Int)->Int{
打印(posts.count)
返回岗位数
}
重写func tableView(tableView:UITableView,cellForRowAt indexath:indexPath)->UITableViewCell{
设单元格=表v
class MyFeedTViewController: UITableViewController {
        var posts: [CKRecord]! = []
        var database = DatabaseController()
        var timer: Timer!


    override func viewDidLoad() {
        super.viewDidLoad()

        timer = Timer.scheduledTimer(timeInterval: 60.0, target: self, selector: #selector(MyFeedTViewController.refresh), userInfo: nil, repeats: true)
        timer.fire()

        database.getAllRecords(withRecordType: "Post", withDesiredKeys: ["user","text", "comments", "plusses"], sortForkey: "creationDate", ascending: false, withResultLimit: 5, operations: 1) { records, error in

            if error == nil {
                self.posts = records
                DispatchQueue.main.async {
                    self.tableView.reloadData()
                }
            }
        }
    }

    func refresh() {

        database.getAllRecords(withRecordType: "Post", withDesiredKeys: ["user","text", "comments", "plusses"], sortForkey: "creationDate", ascending: false, withResultLimit: 5, operations: 1) { records, error in

            if error == nil {
                if records != self.posts {
                self.posts = records
                    DispatchQueue.main.async {
                        self.tableView.reloadData()
                        self.refreshControl?.endRefreshing()
                    }
                }
            }
        }
    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print(posts.count)
        return posts.count
    }


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Text Post", for: indexPath) as! PostCell


        // Configure the cell...

        let post = posts[indexPath.row]

        cell.commentsNLabel.setTitle(String((post["comments"] as? Array<Any>)?.count ?? 0) + " comments", for: .normal)

        var name: String!
        var surname: String!

        guard let recordReference: CKReference = (post["user"] as? CKReference) else {
            print("error")
            return cell
        }

        database.publicDatabase.fetch(withRecordID: recordReference.recordID ) { record, error in
            if error == nil {
                name = record!.value(forKey: "name") as? String ?? "null"
                surname = record!.value(forKey: "surname") as? String ?? "null"

                cell.usernameLabel.text = name + " " + surname
                countOperations += 1
            }
        }

        cell.whenPostedLabel.text = EdAppKit().returnStringTillNow(from: (post["creationDate"] as? NSDate) ?? NSDate())

        cell.plusesNLabel.text = String((post["plusses"] as? Array<Any>)?.count ?? 0) + " plusses"

        cell.postText.text = String((post["text"] as? String) ?? "null")

        return cell
    }
}