Swift 4+Alamofire视频下载及UIActivityViewController多平台分享求助
Hey there! Let's walk through how to download a video with Alamofire and share it via UIActivityViewController in Swift 4. I'll break this down into clear steps with code examples you can adapt for your project.
First, make sure Alamofire is integrated into your project. If you're using CocoaPods, add this to your Podfile:
pod 'Alamofire', '~> 4.9' # Swift 4 compatible version
Run pod install in your terminal, then open the .xcworkspace file to continue development.
We'll use Alamofire's download API to fetch the video and save it to a subfolder in the app's Documents directory. This keeps the file organized and accessible for sharing.
Here's the download function:
import Alamofire func downloadVideo(from urlString: String, completion: @escaping (URL?, Error?) -> Void) { guard let videoURL = URL(string: urlString) else { completion(nil, NSError(domain: "InvalidURL", code: -1, userInfo: [NSLocalizedDescriptionKey: "The video URL is invalid"])) return } // Create a dedicated folder for downloaded videos in Documents let documentsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] let videosFolder = documentsDir.appendingPathComponent("DownloadedVideos") do { try FileManager.default.createDirectory(at: videosFolder, withIntermediateDirectories: true, attributes: nil) } catch { completion(nil, error) return } // Define where to save the downloaded file let destination: DownloadRequest.Destination = { _, response in // Use the suggested filename or generate a unique one let fileName = response.suggestedFilename ?? "video_\(Date().timeIntervalSince1970).mp4" let fileURL = videosFolder.appendingPathComponent(fileName) return (fileURL, [.removePreviousFile, .createIntermediateDirectories]) } // Start the download Alamofire.download(videoURL, to: destination) .downloadProgress { progress in print("Download progress: \(String(format: "%.2f%%", progress.fractionCompleted * 100))") // Update UI here if you want to show a progress bar } .response { response in switch response.result { case .success(let savedFileURL): completion(savedFileURL, nil) case .failure(let error): completion(nil, error) } } }
Quick Explanation:
- We create a
DownloadedVideosfolder in the Documents directory to keep our videos organized. - The destination closure tells Alamofire where to save the file, and ensures we overwrite any existing file with the same name.
- We track download progress in case you want to add a progress indicator for users.
Once the video is downloaded, we'll use UIActivityViewController to let users share it to Facebook, Messages, Twitter, and other supported platforms.
Here's the sharing function:
func shareDownloadedVideo(at fileURL: URL, from presentingVC: UIViewController) { let activityItems = [fileURL] let activityVC = UIActivityViewController(activityItems: activityItems, applicationActivities: nil) // Optional: Exclude any activities you don't want to show activityVC.excludedActivityTypes = [ .postToWeibo, .print, .assignToContact, .saveToCameraRoll // Remove this if you want users to save to photos ] // Handle iPad popover presentation (required for iPad) if let popoverController = activityVC.popoverPresentationController { popoverController.sourceView = presentingVC.view popoverController.sourceRect = CGRect(x: presentingVC.view.bounds.midX, y: presentingVC.view.bounds.midY, width: 0, height: 0) popoverController.permittedArrowDirections = [] } presentingVC.present(activityVC, animated: true, completion: nil) }
Key Notes for Sharing:
- Pass the local file URL directly to
UIActivityViewController—iOS handles the rest for supported platforms. - For iPad, you must set the
popoverPresentationControllerproperties to avoid crashes. - Adjust
excludedActivityTypesto hide any sharing options you don't need.
Now let's put it all together with a sample usage in a ViewController:
class VideoViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Example call to download and share a video let targetVideoURL = "https://your-video-url-here.mp4" startDownloadAndShare(videoURL: targetVideoURL) } func startDownloadAndShare(videoURL: String) { downloadVideo(from: videoURL) { [weak self] fileURL, error in guard let self = self else { return } if let error = error { // Show error alert to user let alert = UIAlertController(title: "Download Failed", message: error.localizedDescription, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default)) self.present(alert, animated: true) return } guard let savedFileURL = fileURL else { print("No file URL returned after download") return } // Share the video once downloaded self.shareDownloadedVideo(at: savedFileURL, from: self) } } }
- Permissions: If you want to let users save videos to their photo library, add the
NSPhotoLibraryAddUsageDescriptionkey to yourInfo.plistwith a description of why you need access (e.g., "Save downloaded videos to your photo library"). - File Cleanup: Remember to periodically delete old downloaded videos to prevent your app from taking up too much storage. You can check the size of the
DownloadedVideosfolder and prompt users to clean up if needed. - Error Handling: The example includes basic error handling, but you can expand it to handle specific cases like network timeouts, invalid file types, or insufficient storage.
内容的提问来源于stack exchange,提问作者Ankit Kumar Gupta

