2014-11-13 1 views
1
// 
// ViewController.swift 
// Fashun 
// 
// Created by Alex Macleod on 20/10/14. 
// Copyright (c) 2014 Alex Macleod. All rights reserved. 
// 

import UIKit 

class ViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource { 

var collectionView: UICollectionView? 

var instanceOfCustomObject: CustomObject = CustomObject() 
var accessToken: NSString! 
var userDefaults: NSUserDefaults! 
let colorWheel = ColorWheel() 
var photoCount: Int! = 0 
let photos = NSMutableArray() 

override func viewDidLoad() { 
    super.viewDidLoad() 

    userDefaults = NSUserDefaults.standardUserDefaults() 
    self.accessToken = userDefaults!.objectForKey("accessToken") as NSString 
    println(self.accessToken) 

//  instanceOfCustomObject.someProperty = "Hello World" 
//  var accessToken : NSString? = NSString(instanceOfCustomObject.accessToken) 
//  println(accessToken) 
//  instanceOfCustomObject.authorize() 

// Do any additional setup after loading the view, typically from a nib. 
    let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() 
//  layout.sectionInset = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 0) 
    layout.itemSize = CGSize(width: 124, height: 124) 
    layout.minimumInteritemSpacing = 1.0 
    layout.minimumLineSpacing = 1.0 
    collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout) 
    collectionView!.dataSource = self 
    collectionView!.delegate = self 
    collectionView!.registerClass(Cell.self, forCellWithReuseIdentifier: "Cell") 
    collectionView!.backgroundColor = UIColor.whiteColor() 
    self.view.addSubview(collectionView!) 

    getData() 
} 

    func getData() -> Void { 
     let baseUrl = NSURL(string:"https://api.instagram.com/v1/users/7522782/media/recent/?access_token=\(self.accessToken)") 

//  let forcastUrl = NSURL(string: "37.8267,-122.423", relativeToURL: baseUrl) 

     //  let data = NSData(contentsOfURL: forcastUrl) 
     //  println(data) 
     let sharedSession = NSURLSession.sharedSession() 
     let downloadTask: NSURLSessionDownloadTask = sharedSession.downloadTaskWithURL(baseUrl!, completionHandler: { (location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in 


      //   var urlContents = NSString.stringWithContentsOfURL(location, encoding: NSUTF8StringEncoding, error: nil) 
      //   println(urlContents) 

      let dataObject = NSData(contentsOfURL: baseUrl!) 

      if (error == nil) { 
       let responseDictionary: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataObject!, options: nil, error: nil) as NSDictionary 
//    println(responseDictionary) 

       var currentResponse = responseDictionary.valueForKeyPath("data.images.standard_resolution.url") as NSArray 



       dispatch_async(dispatch_get_main_queue(), {() -> Void in 

//     for url in currentResponse { 
//      var urlStrings: NSString = url as NSString 
//       
//      var images = UIImage(data: NSData(contentsOfURL: NSURL(string:urlStrings)!)!) 
// 
//     } 
        for url in currentResponse { 
         var urls: NSString = url as NSString 
         //      println(images) 
         var photoUrls = NSURL(string: urls) 

         var err: NSError? 
         var imageData :NSData = NSData(contentsOfURL: photoUrls!,options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &err)! 
         self.photos.addObject(UIImage(data:imageData)!) 
         println(self.photos) 
        } 

        self.photoCount = currentResponse.count as Int 

        self.collectionView?.reloadData() 

       }) 

      } else { 

       let networkIssueController = UIAlertController(title: "Error", message: "Something went wrong get a better phone you pleb!", preferredStyle: .ActionSheet) 
       let okButton = UIAlertAction(title: "OK", style: .Default, handler: nil) 
       networkIssueController.addAction(okButton) 
       let cancelButton = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil) 
       networkIssueController.addAction(cancelButton) 

       self.presentViewController(networkIssueController, animated: true, completion: nil) 

       dispatch_async(dispatch_get_main_queue(), {() -> Void in 
        //Stop refresh animation 


       }) 
      } 
     }) 

     downloadTask.resume() 

    } 


override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
    return photoCount 

} 

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as Cell 
//    println(photos) 
//   cell.textLabel.text = "Text" 
    cell.imageView.image = photos.objectAtIndex(indexPath.row) as? UIImage 
// cell.photo = self.photos[indexPath.row] as? NSDictionary 
    cell.imageView.backgroundColor = colorWheel.randomColor() 

    return cell 
} 
} 

Как вы можете видеть, у меня есть сеанс NSURLDownload, который загружает информацию от instagram от пользователя «7522782». Я анализирую данные и подсчитываю массив currentResponse, чтобы получить количество ячеек, которые мне нужны в моем представлении коллекции. Затем я анализирую информацию об обращении URL-адресов к UIimages и помещаю их в ячейки.Как запустить несколько NSURLSessionDownloadTask, чтобы я мог загружать несколько потоков пользовательских фотографий из Instagram?

Как это сделать для более одного пользователя. Я хочу показывать фотографии от 20 + пользователей.
Имейте в виду, что мне нужно будет подытожить общее количество фотографий от всех пользователей, чтобы сообщить моей коллекции, сколько ячеек сделать.

Заранее благодарен.

+0

Вы близко, и у вас есть код, используйте NSData с циклом из того, сколько всего снимков вы хотите загрузить, сохраните эти изображения в массиве с вызовом Async в Global Dispatch (фоновый поток), а затем получите callback выполняет вызов метода, который обновит ваш пользовательский интерфейс с загруженными изображениями с главной очередью отправки. –

+0

Я, такой нуб, не могли бы вы объяснить, что мне снова в условиях мирян? Я ищу для загрузки контента из API-интерфейсов Instagram от нескольких пользователей, так что у них плохое 20+ URL-адресов для вызова и разбора. Мне просто нужно знать, как делать NSurlsession с двумя URL-адресами, тогда я могу сделать это с помощью всего, как мне нравится ... скажите эти два NSURL (строка: «https://api.instagram.com/v1/users /7522782/media/recent/?access_token=\(self.accessToken) ") NSURL (строка:" https://api.instagram.com/v1/users/14454619/media/recent/?access_token=\(self .accessToken) ") shareSession.downloadTaskWithURL может принимать только один URL-адрес за раз! – alemac852

+0

Я использовал NSUrlSession в очень ограниченной ситуации, когда мне приходилось загружать изображения для отображения списка, однако я им управлял по 20 за раз, поэтому одновременно вы можете это сделать. Именно так вы его реализуете, как я уже говорил, но я бы сделал еще один подход. Позвольте мне написать его для вас, и вы скажете мне, работает ли оно на вас. Но вместо NSUrlSession я предлагаю вам использовать NSData, поскольку он выполняет аналогичные задачи, если вам не нужна NSUrlSession специально для чего-то другого. –

ответ

0

Это один способ, которым я думал, прямо сейчас ...

первую очередь исправить то, как вы используете отправку ... A Good Answer about Dispatch Queues

//Might run into an issue that if you insert more heavy logic here your UI will get stuck until processing ends. 
dispatch_async(dispatch_get_main_queue(), {() -> Void in } 

Поэтому использовать dispatch_get_global_queue вместо фоновой резьбе, а затем вызвать dispatch_get_main_queue, когда вы хотите запустить код, который будет обновлять ваш пользовательский интерфейс внутри закрытия фона (блок).

//Correct way to use it to do Background work. 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), { 

    //async code the callings to the NSUrlSession any other logic 

     dispatch_async(dispatch_get_main_queue(), {() -> Void in 
      //Do UI Updates Code. 
     } 

} 

Теперь для вашей конкретной ситуации. Вы правильно обрабатываете пользователя, который получает все URL-адреса для фотографий для этого пользователя, поэтому теперь добавьте что-то подобное, чтобы обрабатывать несколько пользователей для одного и того же экрана. Проблема заключается в том, что для загрузки более 20 фотографий пользователей потребуется много времени, но поскольку вы делаете это, асинхронный экран не застрянет.

Сделайте матрицу, массив массивов, фотографий; каждый массив внутри основного массива представляет собой набор фотографий для пользователя.

var photoUserMatrix = [NSMutableArray]() //using Swift array and NSMutableArray 

Или использовать это, так как вы более склонны к NSMutableArrays

var photoUserMatrix = NSMutableArray() 
photoUserMatrix.addObject(NSMutableArray())//Each Photo Set per user is a new array. 

Проблема с Матрицей, что найти что-то O (N^2) в исполнении Time.

В любом случае теперь у вас может быть X-число пользователей, и ваш код обработает его. используя этот кусок кода.

//Use this pseudo code to start downloading the multiple pictures for the users. 
for i in 0...countOfUsers{ 

    //Create the array of Photos for this user. 
    var newPhotoSet = NSMutableArray() 

    //Now use your code that downloads the photos with 
    //the Urls given for that users photos. with another loop on the Count of Urls/Photos 
    for pos in 0...countOfUrls{ 

     //Download the Image with NSUrlSession 

     //and add the photo to the new Array in the CompletionHandler 
     newPhotoSet.AddObject(newImageDownloaded); 
    } 

    photoUserMatrix.addObject(newPhotoSet) 


} 

Код для отображения CollectionViewCells.

for photoSet in photoUserMatrix as (NSMutableArray) { 

    var count:Int = photoSet.count 
    for i in 0...count{ 
     //use algorithm to display downloaded pictures in CollectionView. 
     //If any image is nil do not display that image. 
     //Same Code can be used to do the sum of all photos in each array. 
    } 


} 

Имейте в виду, что это не самое оптимальное решение. Кроме того, дизайн приложения не помогает, делая загрузку. Изображения для более 20 пользователей на одном экране - это проблема, которую вы будете запускать там, если изображения действительно очень маленькие.

Также я предлагаю вам добавить этот рабочий логический код в метод, который вызовет Dispatch_get_global_queue для каждого пользователя, который требует загрузки изображений, что делает его более параллельным.

PS: если вы нажмете на какие-либо вопросы, скажите, что я с удовольствием помогу.

+0

Я не знаю, будете ли вы получать уведомление, но я задал еще один вопрос ниже в качестве ответа. – alemac852

+0

[link] (https://www.dropbox.com/s/t82qcgw7lcde7tx/Fashun.zip?dl=0) это ссылка для загрузки моего проекта, если вы смеете смотреть на мой отвратительный код. – alemac852

+0

глядя на него ... и да, он не сообщает мне, когда отправлен ответ. –

 Смежные вопросы

  • Нет связанных вопросов^_^