Я пытаюсь поделиться скриншотом или записи экрана моего приложения, я реализовал также Instagram, который работает нормально, но для Facebook он откроет откройте мой скриншот или запись экрана в клетке, затем снова откройте мое приложение, следуйте в инструкциях оттуда оттуда Официальный веб -сайт, но не смог исправить решение < /p>
Импорт Фонд
import uikit
import avfoundation < /p>
class facebooksharingmanager {
static let shared = facebooksharingmanager () < /p>
private let appID: String = "1337677113908275"
/// Shares media (video or screenshot) to Facebook Stories
func shareToFacebookStories(videoURL: URL? = nil, screenshot: UIImage? = nil) {
if let videoURL = videoURL {
shareBackgroundVideo(videoURL: videoURL, appID: appID)
} else if let screenshot = screenshot {
shareImage(screenshot: screenshot, appID: appID)
} else {
print("⚠️ No valid media provided.")
}
}
/// Shares an image to Facebook Stories
private func shareImage(screenshot: UIImage, appID: String) {
let resizedImage = resizeImageToAspectRatio(image: screenshot, targetRatio: 9.0/16.0)
if let imageData = resizedImage.pngData() {
backgroundImage(imageData: imageData, appID: appID)
}
}
private func backgroundImage(imageData: Data, appID: String) {
guard let urlScheme = URL(string: "facebook-stories://share?source_appliation=\(appID)"),
UIApplication.shared.canOpenURL(urlScheme) else {
print("❌ Facebook app is not installed or does not support story sharing.")
return
}
let pasteboardItems: [[String: Any]] = [
["com.facebook.sharedSticker.backgroundImage": imageData,
"com.facebook.sharedSticker.appID": appID]
]
let pasteboardOptions: [UIPasteboard.OptionsKey: Any] = [
.expirationDate: Date().addingTimeInterval(300) // 5 minutes expiration
]
// Assign background image to pasteboard
UIPasteboard.general.setItems(pasteboardItems, options: pasteboardOptions)
// Open Facebook Stories
UIApplication.shared.open(urlScheme, options: [:], completionHandler: nil)
}
func shareBackgroundVideo(videoURL: URL, appID: String) {
// ✅ Process video before sharing
processVideoForFacebook(inputURL: videoURL) { processedURL in
guard let finalURL = processedURL else {
print("❌ Failed to process video.")
return
}
Task {
if await self.isValidVideo(videoURL: finalURL) {
do {
let videoData = try Data(contentsOf: finalURL)
self.backgroundVideo(videoData: videoData, appID: appID)
} catch {
print("❌ Failed to load video data: \(error.localizedDescription)")
}
} else {
print("⚠️ Video still does not meet Facebook's requirements!")
}
}
}
}
func backgroundVideo(videoData: Data, appID: String) {
guard let urlScheme = URL(string: "facebook-stories://share?source_application\(appID)"),
UIApplication.shared.canOpenURL(urlScheme) else {
print("❌ Facebook app is not installed or does not support story sharing.")
return
}
let pasteboardItems: [[String: Any]] = [
["com.facebook.sharedSticker.backgroundVideo": videoData,
"com.facebook.sharedSticker.appID": appID]
]
let pasteboardOptions: [UIPasteboard.OptionsKey: Any] = [
.expirationDate: Date().addingTimeInterval(300) // 5 minutes expiration
]
// Assign background video to pasteboard
UIPasteboard.general.setItems(pasteboardItems, options: pasteboardOptions)
DispatchQueue.main.async {
UIApplication.shared.open(urlScheme, options: [:], completionHandler: nil)
}
}
private func showAlert(title: String, message: String) {
DispatchQueue.main.async {
if let topVC = self.getTopViewController() {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default))
topVC.present(alert, animated: true)
} else {
print("❌ Failed to find top view controller.")
}
}
}
// Helper function to get the top-most view controller
private func getTopViewController() -> UIViewController? {
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let window = windowScene.windows.first,
let rootViewController = window.rootViewController {
var topController: UIViewController? = rootViewController
while let presentedViewController = topController?.presentedViewController {
topController = presentedViewController
}
return topController
}
return nil
}
func resizeImageToAspectRatio(image: UIImage, targetRatio: CGFloat) -> UIImage {
let originalSize = image.size
let originalRatio = originalSize.width / originalSize.height
var newSize: CGSize
if originalRatio > targetRatio {
// Crop width to fit 9:16
newSize = CGSize(width: originalSize.height * targetRatio, height: originalSize.height)
} else {
// Crop height to fit 9:16
newSize = CGSize(width: originalSize.width, height: originalSize.width / targetRatio)
}
let format = UIGraphicsImageRendererFormat()
format.scale = image.scale
let renderer = UIGraphicsImageRenderer(size: newSize, format: format)
return renderer.image { _ in
image.draw(in: CGRect(origin: .zero, size: newSize))
}
}
/// ✅ **Validates if video meets Facebook's requirements**
private func isValidVideo(videoURL: URL) async -> Bool {
let asset = AVURLAsset(url: videoURL)
do {
// Load required properties asynchronously
let duration = try await asset.load(.duration)
let tracks = try await asset.loadTracks(withMediaType: .video)
guard let track = tracks.first else {
print("❌ No video track found.")
return false
}
let size = try await track.load(.naturalSize)
let bitrate = try await track.load(.estimatedDataRate)
let durationSeconds = CMTimeGetSeconds(duration)
print("📹 Video Info: Duration = \(durationSeconds)s, Resolution = \(size.width)x\(size.height), Bitrate = \(bitrate)")
// ✅ Ensure video meets Facebook’s recommended criteria
return durationSeconds = 1080 &&
bitrate Void) {
Task {
let asset = AVURLAsset(url: inputURL)
// ✅ Ensure export session is created outside the Task
guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality) else {
print("❌ Failed to create AVAssetExportSession")
completion(nil)
return
}
do {
// ✅ Load required properties asynchronously
let duration = try await asset.load(.duration)
let tracks = try await asset.loadTracks(withMediaType: .video)
guard let videoTrack = tracks.first else {
print("❌ No video track found.")
completion(nil)
return
}
let preferredTransform = try await videoTrack.load(.preferredTransform)
// ✅ Define output file path
let outputURL = FileManager.default.temporaryDirectory.appendingPathComponent("processedVideo.mp4")
try? FileManager.default.removeItem(at: outputURL)
// ✅ Force video to 1080x1920 resolution
let videoComposition = AVMutableVideoComposition()
videoComposition.renderSize = CGSize(width: 1080, height: 1920)
videoComposition.frameDuration = CMTime(value: 1, timescale: 30) // 30 FPS
let instruction = AVMutableVideoCompositionInstruction()
instruction.timeRange = CMTimeRange(start: .zero, duration: duration)
let transformer = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)
transformer.setTransform(preferredTransform, at: .zero)
instruction.layerInstructions = [transformer]
videoComposition.instructions = [instruction]
exportSession.outputURL = outputURL
exportSession.outputFileType = .mp4
exportSession.shouldOptimizeForNetworkUse = true
exportSession.videoComposition = videoComposition
// ✅ Start exporting asynchronously
exportSession.exportAsynchronously {
DispatchQueue.main.async { // ✅ Ensure completion runs on the main thread
if exportSession.status == .completed {
print("✅ Video processed successfully!")
completion(outputURL)
} else {
print("❌ Video processing failed: \ (exportSession.error?.localizedDescription ?? "Unknown error")")
completion(nil)
}
}
}
} catch {
print("❌ Failed to load video properties: \. (error.localizedDescription)")
completion(nil)
}
Это мой полный код, который я ожидаю откроется Facebook, и мой предоставленный контент должен появиться в клетке, и у меня есть общая опция, чтобы опубликовать это на историях
Я пытаюсь поделиться скриншотом или записи экрана моего приложения, я реализовал также Instagram, который работает нормально, но для Facebook он откроет откройте мой скриншот или запись экрана в клетке, затем снова откройте мое приложение, следуйте в инструкциях оттуда оттуда Официальный веб -сайт, но не смог исправить решение < /p> Импорт Фонд import uikit import avfoundation < /p> class facebooksharingmanager { static let shared = facebooksharingmanager () < /p> [code]private let appID: String = "1337677113908275"
/// Shares media (video or screenshot) to Facebook Stories func shareToFacebookStories(videoURL: URL? = nil, screenshot: UIImage? = nil) {
if let videoURL = videoURL { shareBackgroundVideo(videoURL: videoURL, appID: appID) } else if let screenshot = screenshot { shareImage(screenshot: screenshot, appID: appID) } else { print("⚠️ No valid media provided.") } }
/// Shares an image to Facebook Stories private func shareImage(screenshot: UIImage, appID: String) { let resizedImage = resizeImageToAspectRatio(image: screenshot, targetRatio: 9.0/16.0) if let imageData = resizedImage.pngData() { backgroundImage(imageData: imageData, appID: appID) } }
private func backgroundImage(imageData: Data, appID: String) { guard let urlScheme = URL(string: "facebook-stories://share?source_appliation=\(appID)"), UIApplication.shared.canOpenURL(urlScheme) else { print("❌ Facebook app is not installed or does not support story sharing.") return }
// Open Facebook Stories UIApplication.shared.open(urlScheme, options: [:], completionHandler: nil) }
func shareBackgroundVideo(videoURL: URL, appID: String) { // ✅ Process video before sharing processVideoForFacebook(inputURL: videoURL) { processedURL in guard let finalURL = processedURL else { print("❌ Failed to process video.") return }
Task { if await self.isValidVideo(videoURL: finalURL) { do { let videoData = try Data(contentsOf: finalURL) self.backgroundVideo(videoData: videoData, appID: appID) } catch { print("❌ Failed to load video data: \(error.localizedDescription)") } } else { print("⚠️ Video still does not meet Facebook's requirements!") } } } }
func backgroundVideo(videoData: Data, appID: String) { guard let urlScheme = URL(string: "facebook-stories://share?source_application\(appID)"), UIApplication.shared.canOpenURL(urlScheme) else { print("❌ Facebook app is not installed or does not support story sharing.") return }
// ✅ Start exporting asynchronously exportSession.exportAsynchronously { DispatchQueue.main.async { // ✅ Ensure completion runs on the main thread if exportSession.status == .completed { print("✅ Video processed successfully!") completion(outputURL) } else { print("❌ Video processing failed: \ (exportSession.error?.localizedDescription ?? "Unknown error")") completion(nil) } } } } catch { print("❌ Failed to load video properties: \. (error.localizedDescription)") completion(nil) } [/code] Это мой полный код, который я ожидаю откроется Facebook, и мой предоставленный контент должен появиться в клетке, и у меня есть общая опция, чтобы опубликовать это на историях