首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在NSURLSession委托方法之前启动UICollectionView w/completion?

如何在NSURLSession委托方法之前启动UICollectionView w/completion?
EN

Stack Overflow用户
提问于 2014-10-06 19:55:49
回答 1查看 292关注 0票数 1

以下目标-C代码在UICollectionView的委托之前处理NSURLSession代码(通过viewDidLoad()) (这正是我想要的):

代码语言:javascript
复制
--- Session ---
--- Session ---
--- {CellForItemAtIndexPath} ---
--- {CellForItemAtIndexPath} ---
--- {CellForItemAtIndexPath} ---
--- {CellForItemAtIndexPath} ---
--- {CellForItemAtIndexPath} ---
--- {CellForItemAtIndexPath} ---
--- {CellForItemAtIndexPath} ---
--- {CellForItemAtIndexPath} ---
--- {CellForItemAtIndexPath} ---
--- {CellForItemAtIndexPath} ---
--- {CellForItemAtIndexPath} ---
--- {CellForItemAtIndexPath} ---
--- {CellForItemAtIndexPath} ---
--- {CellForItemAtIndexPath} ---
--- {CellForItemAtIndexPath} ---

注意:上面的调试消息是在它们各自的中断属性中生成的。

简略的目标-C代码:

代码语言:javascript
复制
@interface MainViewController () <UICollectionViewDataSource, UICollectionViewDelegate>
@property (weak, nonatomic) IBOutlet UICollectionView *collectionView;
@property (nonatomic, strong) NSMutableArray *downloaders;
@property (nonatomic, strong) NSArray *photoInfos;
@end

@implementation MainViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self fetchFlickrPhotoWithSearchString:@"Ric"];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    if (_currentImageDownloader) {
        [_downloaders replaceObjectAtIndex:_selectedItemIndex withObject:_currentImageDownloader];
    }
}

// -----------------------------------------------------------------------------------------------------------------------
#pragma mark -

- (void)fetchFlickrPhotoWithSearchString:(NSString *)searchString {

    SimpleFlickrAPI *flickr = [SimpleFlickrAPI new];


    [[[NSURLSession sharedSession] dataTaskWithURL:[flickr getURLForString:@"Ric"]
                                 completionHandler:^(NSData *data,
                                                     NSURLResponse *response,
                                                     NSError *error) {
                                     if (!error) {
                                         NSString *string = [flickr stringByRemovingFlickrJavaScript:data];
                                         NSData *jsonData = [string dataUsingEncoding:NSUTF8StringEncoding];
                                         NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData
                                                                                                  options:NSJSONReadingAllowFragments
                                                                                                    error:&error];

                                         self.photoInfos = [[jsonDict objectForKey:@"photos"] objectForKey:@"photo"];

                                         NSMutableArray *downloaders = [[NSMutableArray alloc] initWithCapacity:[_photoInfos count]];
                                         for (NSInteger index = 0; index < [_photoInfos count]; index++) {
                                             ImageDownloader *downloader = [[ImageDownloader alloc] initWithDict:_photoInfos[index]];
                                             [downloaders addObject:downloader];
                                         }
                                         self.downloaders = downloaders; // ...link local array with instance array 'downloaders' (Note: same object!).

                                         dispatch_async(dispatch_get_main_queue(), ^{
                                             [self.collectionView reloadData];
                                         });
                                     } else {
                                         NSLog(@"*** {SessionDataError}: %@",error);
                                         // ...Handle Error.
                                     }
                                 }] resume];

}

// -----------------------------------------------------------------------------------------------------------------------
#pragma mark - UICollectionViewDelegate methods
// ...to be implemented later.

// -----------------------------------------------------------------------------------------------------------------------
#pragma mark - UICollectionViewDataSource methods

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return [self.photoInfos count];
}

// -----------------------------------------------------------------------------------------------------------------------

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"PhotoCell" forIndexPath:indexPath];
    ...
    ...
    return cell;
}    

...
@end

然而..。斯威夫特的处理模式不同。UIControllerView的数据源委托方法是在NSURLSession之前处理的:

代码语言:javascript
复制
--- {UICollectionView numberOfItems...} ---
--- {cellForItemAtIndexPath} ---
--- {cellForItemAtIndexPath} ---
--- {cellForItemAtIndexPath} ---
--- {cellForItemAtIndexPath} ---
--- {cellForItemAtIndexPath} ---
--- {session} ---
--- {session} ---

以下是Swift的“等效”代码:

代码语言:javascript
复制
import UIKit

var gPhotoData:Array<Dictionary<String,AnyObject>>?
var gDownloaders:NSMutableArray = NSMutableArray()
var currentImageDownloader:ImageDownloader?
var gSelectedItemIndex:Int?


class ViewController: UIViewController {

    @IBOutlet weak var collectionView: UICollectionView!

    override func viewDidLoad() {
        super.viewDidLoad()
        fetchFlickrPhotoWithSearchString("Ric");
    }

    // -----------------------------------------------------------------------------------------------------
    // MARK: -


    func fetchFlickrPhotoWithSearchString(searchString:String) {

        let url = getURLForString("Ric")

        let task = NSURLSession.sharedSession().dataTaskWithURL(url) {(data, response, error) in
            if let httpRes = response as? NSHTTPURLResponse {
                if httpRes.statusCode == 200 {
                    let string = stringByRemovingFlickrJavaScriptFromData(data)
                    let data = string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
                    let JSON: AnyObject? = NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments, error: nil)

                    let rawDataDict = JSON as Dictionary<String,AnyObject>!
                    let photos: AnyObject? = rawDataDict["photos"]
                    gPhotoData = (photos!["photo"] as Array<Dictionary<String,AnyObject>>)

                    let myCount = (gPhotoData!.count - 1)

                    for index in 0...myCount {
                        let smirf = gPhotoData![index]
                        let downloader:ImageDownloader = ImageDownloader(dict: smirf)
                        gDownloaders.addObject(downloader)
                    }

                    dispatch_async(dispatch_get_main_queue(), {
                        // ...do something.
                    })

                }
            }
        }

        task.resume()

    } // ...end class ViewController().

    // =======================================================================================================================
    // MARK: - Action Methods

    @IBAction func exitAction(sender: AnyObject) {
        exit(0)
    }

}

// =======================================================================================================================

extension ViewController: UICollectionViewDataSource {

    // -----------------------------------------------------------------------------------------------------

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if let anyData = gPhotoData {
            return gPhotoData!.count
        }
        return 5  //...arbitrary number to avoid crashing.
    }

    // -----------------------------------------------------------------------------------------------------

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell: AnyObject = collectionView.dequeueReusableCellWithReuseIdentifier("photoCell", forIndexPath:indexPath)
        let photoImageView = cell.viewWithTag!(1) as UIImageView

...
...

        return cell as UICollectionViewCell


    }

}

注意:上面的调试消息是在它们各自的中断属性中生成的。

问题:如何启动NSURLSession/Swift,并在UIViewController的委托方法开火之前完成(正如在Objective版本中所做的那样)?

EN

回答 1

Stack Overflow用户

发布于 2014-10-07 10:30:55

如果您的目标是在通过会话检索数据之后在collectionView中显示数据,那么为什么不直接在dispatch_main_queue中调用collectionView.reloadData()呢?

为了避免numberOfRows中的崩溃,不要强制取消数组的包装,而是对可选的:return anyData.count执行操作。只有当anyData不是零时,它才会调用该代码,并且在可选的展开包装之后返回0应该是可以的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26223871

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档