Я работаю над медицинским приложением, которое объясняет некоторые медицинские термины и его детали. Мне приходится обрабатывать несколько операций по загрузке изображений и некоторых аудиофайлов. У меня есть два класса для обработки сетевых операций и операций кеша для загрузки изображений и загрузки аудио соответственно. Я использовал AFNetworking для обработки всех операций, и я использую Swift. Сценарий запускается при запуске приложения, я вызываю func класса изображения для загрузки всех изображений и на соответствующем диспетчере просмотра для просмотра подробностей термина, у меня есть возможность воспроизвести аудиофайл, если он доступен. Однако, если я нажимаю кнопку воспроизведения, звук загружается только после загрузки всех изображений (например, 20 изображений), которые были обработаны из делегата приложения.Задержка при использовании операций в разных точках
import UIKit
let ImageFileDirectory : String = "Image-cache"
typealias ImageDownloadCallBackSuccess = (String , UIImage) -> Void
class ImageManager: NSObject {
override init() {
super.init()
}
func downloadImageFile (imageData : Dictionary<String,AnyObject>, callback: ImageDownloadCallBackSuccess) -> Void {
let imageUrl : NSString = (imageData as NSDictionary).objectForKey("url") as! NSString
let imageId : Int = (imageData as NSDictionary).objectForKey("id") as! Int
let imageIDString : String = String(imageId)
let filemanager = NSFileManager.defaultManager()
if !filemanager.fileExistsAtPath(filePath(imageIDString)) {
var opManager : AFHTTPRequestOperationManager = AFHTTPRequestOperationManager()
opManager.responseSerializer = AFImageResponseSerializer()
opManager.requestSerializer.timeoutInterval = 180.0
let newOperation = opManager.HTTPRequestOperationWithRequest(NSURLRequest(URL: NSURL(string: imageUrl)!), success: { (operation: AFHTTPRequestOperation!,responseObject: AnyObject!) -> Void in
println("File Saved to ImageCacheDirectory")
let imageData : NSData = UIImageJPEGRepresentation(responseObject as! UIImage, 1.0)
imageData.writeToFile(self.filePath(imageIDString), atomically: true)
callback(imageIDString, responseObject as! UIImage)
}, failure: { (operation: AFHTTPRequestOperation!,error: NSError!) -> Void in
println("Couldn't save the file to ImageCacheDirectory")
})
newOperation.start()
}
else {
println("file exist for path")
}
}
class func filePathForImage (imageID: String) -> (String!) {
let documentsPath : String = NSSearchPathForDirectoriesInDomains(.DocumentDirectory,.UserDomainMask,true)[0] as! String
let fileExtensionString = String(format:"/%@/", ImageFileDirectory)
let folderPath = documentsPath.stringByAppendingPathComponent("\(fileExtensionString)")
let filemanager = NSFileManager.defaultManager()
var err: NSErrorPointer = nil
if !filemanager.fileExistsAtPath(folderPath) {
filemanager.createDirectoryAtPath(folderPath, withIntermediateDirectories: true, attributes: nil, error: err)
}
var filePath = "\(folderPath)"
filePath += "/"
filePath += "\(imageID)"
filePath += "."
filePath += "jpg"
return filePath
}
func imageRootDirectory() -> String {
let documentsPath : String = NSSearchPathForDirectoriesInDomains(.DocumentDirectory,.UserDomainMask,true)[0] as! String
let imageDirectory = String(format:"/%@/", ImageFileDirectory)
return documentsPath.stringByAppendingPathComponent("\(imageDirectory)")
}
func filePath (imageID :String) -> String {
let folderPath = imageRootDirectory()
var filePath = "\(folderPath)"
filePath += "/"
filePath += "\(imageID)"
filePath += "."
filePath += "jpg"
return filePath
}
func downloadAllImage() {
for imageObject in DataManager.sharedInstance.allImages {
downloadImageFile(imageObject, callback: { (imageString, imageData) -> Void in
})
}
}
}
typealias AudioDownloadHandler = (Double) -> Void
let AudioFileDirectory : String = "Audio-cache"
import UIKit
import AVFoundation
class AudioManager: NSObject ,AVAudioPlayerDelegate {
var audioID : Int?
var audioUrl : String?
var audioPlayer : AVAudioPlayer! // will be Optional, must supply initializer
override init() {
super.init()
}
init (audioId : Int , audioUrl: String) {
self.audioUrl = audioUrl
self.audioID = audioId
super.init()
}
func cacheAudioFile(callback:AudioDownloadHandler) -> Void {
let request: NSURLRequest = NSURLRequest(URL: NSURL(string: self.audioUrl!)!)
let audioDownloadOperation: AFHTTPRequestOperation = AFHTTPRequestOperation(request: request)
audioDownloadOperation.outputStream = NSOutputStream(toFileAtPath: filePathForAudio()!, append: false)
audioDownloadOperation.setDownloadProgressBlock({(bytesRead, totalBytesRead, totalBytesExpectedToRead) -> Void in
var total: CGFloat = CGFloat(totalBytesRead)/CGFloat(totalBytesExpectedToRead)
callback(Double(total))
})
audioDownloadOperation.start()
}
func filePathForAudio() -> (String!) {
let documentsPath : String = NSSearchPathForDirectoriesInDomains(.DocumentDirectory,.UserDomainMask,true)[0] as! String
let fileExtensionString = String(format:"/%@/", AudioFileDirectory)
let folderPath = documentsPath.stringByAppendingPathComponent("\(fileExtensionString)")
let filemanager = NSFileManager.defaultManager()
var err: NSErrorPointer = nil
if !filemanager.fileExistsAtPath(folderPath) {
filemanager.createDirectoryAtPath(folderPath, withIntermediateDirectories: true, attributes: nil, error: err)
}
var filePath = "\(folderPath)"
filePath += "/"
filePath += "\(self.audioID!)"
filePath += "."
filePath += "\(self.audioUrl!.pathExtension)"
return filePath
}
func playAudioFile() {
var filePathUrl : NSURL = NSURL.fileURLWithPath(filePathForAudio())!
var error: NSError!
self.audioPlayer = AVAudioPlayer(contentsOfURL: filePathUrl, error: nil)
self.audioPlayer.delegate = self
if let player : AVAudioPlayer = self.audioPlayer as AVAudioPlayer?{
self.audioPlayer.prepareToPlay()
player.play()
}
}
func audioPlayerDidFinishPlaying(player: AVAudioPlayer!, successfully flag: Bool) {
NSNotificationCenter.defaultCenter().postNotificationName("AudioFinishedPlaying", object: nil)
}
}
let imageManager = ImageManager()
imageManager.downloadAllImage()
Итак, в чем ваш вопрос? –
@DuncanC Есть ли проблемы с управлением операциями с моим кодом. – Nassif
Несвязанный, но я бы не советовал использовать 'AFImageResponseSerializer', а затем использовать' UIImageJPEGRepresentation' для повторного создания 'NSData', который (а), вероятно, делает его больше; и (б), возможно, теряет метаданные в этом процессе. Вы можете получить оригинальную 'NSData', посмотрев на свойство' responseData' операции. Или используйте стандартный 'AFHTTPResponseSerializer', а затем конвертируйте его в' UIImage' самостоятельно. В любом случае сохраните исходные данные ответа, а не повторно извлеките его из изображения. – Rob