2016-08-23 4 views
0

Ich bin neu in iOS-Entwicklung, so dass jede Hilfe geschätzt werden würde.Wie lade ich eine Textdatei asynchron aus einer URL, lade asynchrone Bilder von URLs in der Textdatei? (in swift)

Das Projekt: Ich entwickle eine Emoji-Tastatur für iOS. Wenn die Tastatur zum ersten Mal geladen wird, wird eine .txt-Datei aus dem Internet mit Bild-URLs heruntergeladen (auf diese Weise kann ich die Bilder einfach durch Aktualisieren dieser .txt-Datei hinzufügen/löschen/neu anordnen). Die Bild-URLs werden in ein Array eingegeben. Anschließend wird das Array der Bild-URLs zum Auffüllen einer Sammlungsansicht verwendet.

Der Code, den ich geschrieben habe, funktioniert, aber wenn ich auf meine Tastatur umschalte, wartet das System, bis alles geladen ist (normalerweise 2-3 Sekunden), bevor die Tastatur auftaucht. Was ich will ist, dass die Tastatur sofort ohne Bilder auftaucht, dann laden Sie die Bilder, sobald sie verfügbar sind - auf diese Weise kann der Benutzer sehen, wie die Tastatur funktioniert.

Wie kann ich die Tastatur sofort laden, dann die Textdatei herunterladen, gefolgt von den Bildern? Ich finde viele Informationen über asynchronen Download für Bilder, aber mein Problem ist ein wenig komplexer mit dem Hinzufügen des Textdownloads und ich kann es nicht ganz herausfinden.

weitere Informationen:

Ich SDWebImage unter Verwendung der Bilder zu laden, so dass sie schön sind das Caching und sollte asynchron werden geladen, aber die Art und Weise habe ich es eingewickelt die Tastatur wartet, bis alles heruntergeladen Anzeige.

Ich habe versucht, die "do {} catch {}" Teil des Codes unten innen - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { //do-catch code }) - wenn ich dies tun, die Tastatur erscheint sofort wie ich will, aber statt 2-3 Sekunden, um die Bilder zu laden, Es dauert 8-10 Sekunden und es wartet immer noch auf alle Bilder, bevor Bilder angezeigt werden.

Unten ist mein Code. Ich habe den Code vereinfacht, indem ich Tasten und anderen funktionierenden Code entfernt habe. Es gibt zwei .xib Dateien mit diesem Code verbunden: KeyboardView und ImageCollectionViewCell

import UIKit 
import MobileCoreServices 
import SDWebImage 


class ImageCollectionViewCell:UICollectionViewCell { 
    @IBOutlet var imgView:UIImageView! 
} 

class KeyboardViewController: UIInputViewController, UICollectionViewDataSource, UICollectionViewDelegate { 

    @IBOutlet var collectionView: UICollectionView! 

    let blueMojiUrl = NSURL(string: "http://example.com/list/BlueMojiList.txt") 
    var blueMojiArray = NSMutableArray() 

    func isOpenAccessGranted() -> Bool { 
     // Function to test if Open Access is granted 
     return UIPasteboard.generalPasteboard().isKindOfClass(UIPasteboard) 
    } 


    override func viewDidLoad() { 
     super.viewDidLoad() 

     let nib = UINib(nibName: "KeyboardView", bundle: nil) 
     let objects = nib.instantiateWithOwner(self, options: nil) 
     self.view = objects[0] as! UIView; 

     self.collectionView.registerNib(UINib(nibName: "ImageCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "ImageCollectionViewCell") 


     if (isOpenAccessGranted()) == false { 
      // Open Access is NOT granted - display error instructions 

     } else { 
      // Open Access IS granted 

       do { 

       self.blueMojiArray = NSMutableArray(array: try NSString(contentsOfURL: self.blueMojiUrl!, usedEncoding: nil).componentsSeparatedByString("\n")); 

       self.collectionView.reloadData() 

      } catch { 
       // Error connecting to server - display error instructions 
      } 

     } 

    } // End ViewDidLoad 


    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return self.blueMojiArray.count 
    } 


    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 

     let iCell = collectionView.dequeueReusableCellWithReuseIdentifier("ImageCollectionViewCell", forIndexPath: indexPath) as! ImageCollectionViewCell 
     let url = NSURL(string: self.blueMojiArray.objectAtIndex(indexPath.row) as! String) 

     iCell.imgView.sd_setImageWithURL(url, placeholderImage: UIImage(named: "loading")) 

     iCell.layer.cornerRadius = 10.0 

     return iCell 
    } 

} 

UPDATE: Danke für die Antworten. Ich konnte mein Problem mit Alamofire beheben. Ich habe den Alamofire-Pod zu meinem Projekt installiert. Der spezifische Code, den ich verwendet, um mein Problem zu beheben: Zuerst habe ich import Alamofire an der Spitze, dann entfernte ich das do {} catch {} Code oben und ersetzt mit

Alamofire.request(.GET, blueMojiUrl!) 
       .validate() 
       .responseString { response in 

        switch response.result { 

        case .Success: 
         let contents = try? NSString(contentsOfURL: self.blueMojiUrl!, usedEncoding: nil) 
         self.blueMojiArray = NSMutableArray(array: contents!.componentsSeparatedByString("\n")) 

        self.collectionView.reloadData() 


        case .Failure: 
         // Error connecting to server - display error instructions 
        } 
      } 

Nun ist die Tastatur lädt sofort, gefolgt von der Bilder laden innerhalb von 2-3 Sekunden. Die

Antwort

0

Ich würde so etwas tun:

Auf cellForItemAtIndexPath Call-Methode zum Download Bild für aktuelle Zelle mit Abschlussbehandler. Bei Download-Abschluss das Bild der Zelle auf das heruntergeladene Bild setzen und die Methode reloadItemsAtIndexPaths für diese Zelle aufrufen.

Beispielcode:

func downloadPlaceholderImage(url: String, completionHandler: (image: UIImage) ->()) { 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { 
     /// download logic 
      completionHandler(image: downloadedImage) 
     })    
    } 
} 

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 
    /// 
    downloadPlaceHolderImage("url", completionHandler: { image in 
    cell.image = image 
    self.collectionView.reloadItemsAtIndexPaths([indexPath]) 
    }) 
    /// 
} 
+0

Danke! In meinem Fall verursachte die Verwendung von reloadItemsAtIndexPaths Probleme, weil ich mehrere Sammlungen habe, so dass sie übereinander gestapelt wurden :) Ich konnte es richtig mit Alamofire arbeiten lassen, und ich aktualisierte meine Frage mit meinen Ergebnissen. Danke für die Antwort, ich danke Ihnen, dass Sie sich die Zeit genommen haben, zu helfen. –

Verwandte Themen