我如何让数据管理器告诉 View Controller 重新加载集合

How do I have data manager tell View Controller to reload collection

抱歉,如果我说的任何内容完全错误,但我是 swift 的新手。

我有一个包含 uicollectionsview 的 UIViewController。然后我有一个数据管理器,它从 instagram 获取 json 数据,然后解析它。我想知道的是如何让数据管理器告诉 ViewController 重新加载集合视图中的数据。每次我让数据管理器告诉 ViewController 重新加载数据时,它都会给我一个错误,说它是零。我在想这是因为数据管理器正在创建一个全新的视图控制器实例,所以我使用单例设计模式来尝试让它工作。但是,由于某种原因,当我使用 .instance 时它崩溃了。我把那部分注释掉了。

我也试过使用线程来让它工作,但还是不行。

我知道不是没有信息,因为我在视图控制器中有一个按钮,按下时会重新加载集合视图,然后所有数据都会加载到集合视图中。

我也尝试过其他一些方法,但没有任何效果。

下面是 ViewController 的代码:

class InstagramControllerView: UIViewController, MWPhotoBrowserDelegate, UICollectionViewDelegate {
class var sharedInstance : InstagramControllerView {
    struct Static {
        static var onceToken : dispatch_once_t = 0
        static var instance : InstagramControllerView? = nil
    }
    dispatch_once(&Static.onceToken) {
        Static.instance = InstagramControllerView()
    }
    return Static.instance!
}

//OUTLETS
@IBOutlet weak var collectionView: UICollectionView!

//let navigationController = InstagramNavigationController()

/* this will hold all of the information
** pertaining to this instagram account
*/
//let instagramHeader = InstagramHeader()
var nextUrl = ""

var dataManagerDone: Bool = false

let instagramDataManager = InstagramDataManager()

//arrays to hold instagram content
var headerResults: JSON?
var results: [JSON]? = []
var photos: [MWPhoto] = []
var thumbnailArr: [String] = []
var standardResArr: [String] = []
var descriptionArr: [String] = []

override func viewDidLoad() {
    super.viewDidLoad()
//    self.collectionView.reloadData()
//        let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
//        dispatch_async(dispatch_get_global_queue(priority, 0), {
//            self.instagramDataManager.getProfileInfoJson(self.profileUrlPath)
//            let thum = self.instagramDataManager.getImageDataJson(self.photoUrlPath)
//            dispatch_async(dispatch_get_main_queue(), {
//                    println("this is thumb \(thum)")
//                    self.collectionView.reloadData()
//                    println("i made it to view laod")
//            })
//        })
}

@IBAction func refresh(sender: UIButton) {
    self.refreshCollectionView()
}

func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
    var bottomEdge = scrollView.contentOffset.y + scrollView.frame.size.height;
    if (bottomEdge >= scrollView.contentSize.height) {
        instagramDataManager.getNextSetOfImages()
    }
}

func refreshCollectionView(){
    self.collectionView.reloadData()
}

现在是数据管理器:

class InstagramDataManager {

var profilePictureURL: NSURL?
var postCount: String?
var followerCount: String?
var followingCount: String?
var username: String?
var bio: String?
var website: String?

var doneParsingProfile: Bool = false
var doneParsingImage: Bool = false

//arrays to hold instagram content
var results: [JSON]? = []
var thumbnailArr: [String] = []
var standardResArr: [MWPhoto] = []
var descriptionArr: [String] = []

let profileUrlPath = "https://api.instagram.com/v1/users/22755819/?access_token=fdasf"
let photoUrlPath = "https://api.instagram.com/v1/users/22755819/media/recent/?count=65&access_token=jdkfjs"
var nextUrl = ""

init(){
    self.getProfileInfoJson(profileUrlPath)
    self.getImageDataJson(photoUrlPath)
}

//returns true when done
func getProfileInfoJson(urlPath: String) -> Bool {
    Alamofire.request(.GET, urlPath).responseJSON { (request, response, json, error) in
        if json != nil {
            var jsonObj = JSON(object: json!)
            self.parseProfileData(jsonObj)
        }
    }
    return true
}

//returns true when done
func getImageDataJson(urlPath: String){
    Alamofire.request(.GET, urlPath).responseJSON { (request, response, json, error) in
        if json != nil{
            var jsonObj = JSON(object: json!)
            if let data = jsonObj["data"].arrayValue as [JSON]? {
                self.results? += data
                self.parseImageData(data)
            }
            if let paginationUrl = jsonObj["pagination"]["next_url"].stringValue? {
                self.nextUrl = paginationUrl
            }else{
                self.nextUrl = ""
            }
        }
    }
}

private func parseImageData(jsonData: [JSON]){
    for i in 0..<jsonData.count{
        if let thumbnail = jsonData[i]["images"]["thumbnail"]["url"].stringValue? {
            self.thumbnailArr.append(thumbnail)
        }
        if let standardResPhoto = jsonData[i]["images"]["standard_resolution"]["url"].stringValue? {
            self.standardResArr.append(MWPhoto(URL: NSURL(string: standardResPhoto)))
        }
        if let description = jsonData[i]["caption"]["text"].stringValue? {
            self.standardResArr[i].caption = description
        }
    }
    self.doneParsingImage = true
    doneParsing()
}

private func parseProfileData(json: JSON){
    if let photoUrl = json["data"]["profile_picture"].stringValue? {
        self.profilePictureURL = NSURL(string: photoUrl)
    }
    if let postCount = json["data"]["counts"]["media"].stringValue? {
        self.postCount = postCount
    }
    if let follows = json["data"]["counts"]["follows"].stringValue? {
        self.followingCount = follows
    }
    if let followers = json["data"]["counts"]["followed_by"].stringValue? {
        self.followerCount = followers
    }
    if let username = json["data"]["username"].stringValue? {
        self.username = username
    }
    if let bio = json["data"]["bio"].stringValue? {
        self.bio = bio
    }
    if let website = json["data"]["website"].stringValue? {
        self.website = website
    }
    self.doneParsingProfile = true
    doneParsing()
}

//reload collection view once both image and profile have been parsed
private func doneParsing(){
    if self.doneParsingImage && self.doneParsingProfile {
        //InstagramControllerView.sharedInstance.collectionView.reloadData()
    }
}

我显然遗漏了一些不必要的代码。

我将不胜感激任何能得到的帮助。提前致谢

所以基本上不是试图获取集合视图并刷新它,而是希望您的 InstagramVC 为 DataManager 提供一个块以在接收数据时执行。这样任何对象都可以请求 Instagram 数据。 Instagram 管理器不应专门绑定到任何控制器。所以要做到这一点,你首先需要在请求数据时传递一个代码块:

func getImageDataJson(urlPath: String, completion: () -> ()) {
    Alamofire.request(.GET, urlPath).responseJSON { (request, response, json, error) in
        if json != nil {
            var jsonObj = JSON(object: json!)
            if let data = jsonObj["data"].arrayValue as [JSON]? {
                self.results? += data
                self.parseImageData(data)
            }

            // Not sure where you want this but let's just execute the block here
            completion()

            if let paginationUrl = jsonObj["pagination"]["next_url"].stringValue? {
                self.nextUrl = paginationUrl
            } else {
                self.nextUrl = ""
            }
        }
    }
}

然后在请求数据时,只要传入一个你希望在数据返回后执行的片段:

self.instagramDataManager.getProfileInfoJson(self.profileUrlPath) {
    // Upon completion of receiving data refresh my collection view
    self.collectionView.reloadData()
}

大功告成。然后删除所有与单例有关的东西!!!