我尝试实现的共享扩展有一个非常奇怪的行为。我的应用程序应该将用户选择的图像发送到服务器进行分析。用户选择一张照片并按下post
按钮发送。
以下是我的奇怪行为:
我第一次使用共享扩展时,它并没有超出
attachment.loadItem
通话范围。它甚至不打印Before error
。然后,如果我重复相同的工作流程,它工作正常。如果我使用 XCode 调试器,我永远无法进入
attachment.loadItem
部分。无论我使用扩展名的次数。我可以重复测试几次,我的图像永远不会发布到服务器上,也不会Before error
打印There is no error
出来There is an error
。而且,attachment.loadItem
被调用了两次。
didSelectPost
我在函数中有以下代码
override func didSelectPost() {
self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
// Make sure we have a valid extension item
if let content = extensionContext!.inputItems[0] as? NSExtensionItem {
let contentType = kUTTypeImage as String
// Verify the provider is valid
if let contents = content.attachments as? [NSItemProvider] {
// Look for images
for attachment in contents {
print ("There is \(contents.count) attachments")
if attachment.hasItemConformingToTypeIdentifier(contentType) {
print ("I'm in the hasItemConforming part")
attachment.loadItem(forTypeIdentifier: contentType, options: nil) { data, error in
print ("Before error")
if error == nil {
print ("There is no error")
let url = data as! URL
self.sendToServer(localUrl: url)
} else {
print ("There is an error")
}
}
}
}
}
}
}
如果有人可以帮助我,我将不胜感激。非常感谢您的阅读和帮助。
编辑:工作代码。
@IBAction func didSelectButton(_ sender: Any) {
// This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments.
// Inform the host that we're done, so it un-blocks its UI. Note: Alternatively you could call super's -didSelectPost, which will similarly complete the extension context.
if let inputItem = extensionContext!.inputItems.first as? NSExtensionItem {
if let itemProvider = inputItem.attachments?.first as? NSItemProvider {
if self.isInternetAvailable(){
if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeImage as String) {
progressHUD = MBProgressHUD.showAdded(to: self.view, animated: true)
progressHUD.mode = MBProgressHUDMode.determinate
progressHUD.detailsLabel.text = message
let tap = UITapGestureRecognizer(target: self, action: #selector(cancelButton))
progressHUD.addGestureRecognizer(tap)
var imageExt = String()
let imageName = generateRandomStringWithLength(length: 12)
if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeJPEG as String) {
imageExt = ".jpeg"
print ("le type est \(imageExt)")
}
if itemProvider.hasItemConformingToTypeIdentifier(kUTTypePNG as String) {
imageExt = ".png"
print ("le type est \(imageExt)")
}
if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeGIF as String) {
imageExt = ".gif"
print ("le type est \(imageExt)")
}
if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeTIFF as String) {
imageExt = ".tiff"
print ("le type est \(imageExt)")
}
var myData: Data? = nil
itemProvider.loadItem(forTypeIdentifier: kUTTypeImage as String){ [unowned self] (data, error) in
//let myImage: UIImage?
switch data {
case let image as UIImage:
//myImage = image
myData = UIImagePNGRepresentation(image)
imageExt = ".png"
case let data as Data:
//myImage = UIImage(data: data)
myData = data
case let url as URL:
//let imageData = NSData(contentsOf: url.absoluteURL)
//myImage = UIImage(data: imageData! as Data)
//let sourcePath = Bundle.main.path(forResource: url.absoluteString, ofType: "gif")
//print ("Le source path est \(type(of: sourcePath))")
do{
try myData = Data(contentsOf: url)
}catch let error{
print ("Error \(error)")
}
default:
//There may be other cases...
print("Unexpected data:", type(of: data))
//myImage = nil
}
//imageName is set depending on the extension
let myImageName = imageName.appending(imageExt)
print ("final name is \(myImageName)")
self.sendToServer(imageData: myData!, imageName: myImageName)
}
} else if itemProvider.hasItemConformingToTypeIdentifier("public.movie") {
let pre = NSLocale.preferredLanguages[0]
var message = String()
if pre.hasPrefix("fr-") {
message = "Annuler"
}
else{
message = "Tap to cancel"
}
progressHUD = MBProgressHUD.showAdded(to: self.view, animated: true)
progressHUD.mode = MBProgressHUDMode.determinate
progressHUD.detailsLabel.text = message
let tap = UITapGestureRecognizer(target: self, action: #selector(self.cancelButton))
progressHUD.addGestureRecognizer(tap)
itemProvider.loadItem(forTypeIdentifier: "public.movie", options: nil, completionHandler: { (url, error) in
//////TOUT ÇA EST À CORRIGER, ce n'est pas propre ///////////////
var urlString = url.debugDescription as! String
var urlString2 : String?
urlString2 = urlString.replacingOccurrences(of: "Optional(file://", with: "")
urlString2 = urlString2?.replacingOccurrences(of: ")", with: "")
//////TOUT ÇA EST À CORRIGER ///////////////
print("Video Selected")
let appGroupDirectory = self.appGroupContainerURL()
let frameCount = 64
let delayTime = Float(0.2)
let loopCount = 0 // 0 means loop forever
let fnameTmp = self.generateRandomStringWithLength(length: 8)
let fname = fnameTmp+".jpg"
let fnameGif = appGroupDirectory?.appendingPathComponent(fnameTmp+".gif")
Regift.createGIFFromSource(url as! URL, destinationFileURL : fnameGif, frameCount: frameCount, delayTime: delayTime, loopCount: loopCount) { (result) in
print("Gif saved to \(result)")
}
let snapshot = self.videoSnapshot(filePathLocal: urlString2! as NSString)
let jpgImageData = UIImageJPEGRepresentation(snapshot!, 0.4)!
let newFname = fnameTmp+".gif"
let mimetype = "image/gif"
//dataToSend = regift
var dataToSend = Data()
do {
dataToSend = try NSData(contentsOf: fnameGif!) as Data
} catch {
print(error)
return
}
let fileManager = FileManager.default
do {
if fileManager.fileExists(atPath: (fnameGif?.path)!) {
try fileManager.removeItem(atPath: (fnameGif?.path)!)
}
} catch let error as NSError {
print(error.debugDescription)
}
let filePath = appGroupDirectory?.appendingPathComponent(fname)
do{
try jpgImageData.write(to: (filePath)!)
}catch let error{
print ("Error \(error)")
}
self.sendToServer(imageData: dataToSend, imageName: newFname)
})
}
}
else{
DispatchQueue.main.async(execute: {
let noInternetHud = MBProgressHUD.showAdded(to: self.view, animated: true)
noInternetHud.mode = MBProgressHUDMode.text
noInternetHud.label.text = "No Internet Available"
noInternetHud.hide(animated: true, afterDelay: 2)
})
}
}
}
}