Обмен на Facebook Stories iosIOS

Программируем под IOS
Ответить
Anonymous
 Обмен на Facebook Stories ios

Сообщение Anonymous »

Я пытаюсь поделиться скриншотом или записи экрана моего приложения, я реализовал также 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, и мой предоставленный контент должен появиться в клетке, и у меня есть общая опция, чтобы опубликовать это на историях

Подробнее здесь: https://stackoverflow.com/questions/794 ... tories-ios
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»