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

时间:2015-01-14 17:46:45

标签: ios multithreading swift asynchronous singleton

对不起,如果我说的话完全错了,但我是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()
}

现在是DataManager:

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()
    }
}

我显然已经留下了一些不必要的代码。

我将非常感谢任何帮助。提前谢谢

1 个答案:

答案 0 :(得分:4)

因此,基本上不是试图获取集合视图并刷新它,而是希望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()
}

你完成了。然后删除与单身人士有关的所有事情!!!