对不起,如果我说的话完全错了,但我是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()
}
}
我显然已经留下了一些不必要的代码。
我将非常感谢任何帮助。提前谢谢
答案 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()
}
你完成了。然后删除与单身人士有关的所有事情!!!