mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-09 22:36:01 +05:45
130 lines
4.2 KiB
Swift
130 lines
4.2 KiB
Swift
// Copyright 2023 Google LLC
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
import Foundation
|
|
import Photos
|
|
import UIKit
|
|
|
|
@objc(FIRFADInAppFeedback) open class InAppFeedback: NSObject {
|
|
@objc(
|
|
feedbackViewControllerWithAdditionalFormText:releaseName:image:onDismiss:
|
|
) public static func feedbackViewController(additionalFormText: String,
|
|
releaseName: String,
|
|
image: UIImage?,
|
|
onDismiss: @escaping ()
|
|
-> Void)
|
|
-> UIViewController {
|
|
// TODO: Add the additionalInfoText parameter.
|
|
let frameworkBundle = Bundle(for: self)
|
|
|
|
let resourceBundleURL = frameworkBundle.url(
|
|
forResource: "AppDistributionInternalResources",
|
|
withExtension: "bundle"
|
|
)
|
|
let resourceBundle = Bundle(url: resourceBundleURL!)
|
|
|
|
let storyboard = UIStoryboard(
|
|
name: "AppDistributionInternalStoryboard",
|
|
bundle: resourceBundle
|
|
)
|
|
let vc: FeedbackViewController = storyboard
|
|
.instantiateViewController(withIdentifier: "fir-ad-iaf") as! FeedbackViewController
|
|
|
|
vc.additionalFormText = additionalFormText
|
|
vc.releaseName = releaseName
|
|
vc.image = image
|
|
vc.viewDidDisappearCallback = onDismiss
|
|
|
|
return vc
|
|
}
|
|
|
|
@objc(getManuallyCapturedScreenshotWithCompletion:)
|
|
public static func getManuallyCapturedScreenshot(completion: @escaping (_ screenshot: UIImage?)
|
|
-> Void) {
|
|
getPhotoPermissionIfNecessary(completionHandler: { authorized in
|
|
guard authorized else {
|
|
completion(nil)
|
|
return
|
|
}
|
|
|
|
let manager = PHImageManager.default()
|
|
|
|
let fetchOptions = PHFetchOptions()
|
|
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
|
|
fetchOptions.predicate = NSPredicate(
|
|
format: "(mediaSubtype & %d) != 0",
|
|
PHAssetMediaSubtype.photoScreenshot.rawValue
|
|
)
|
|
|
|
let requestOptions = PHImageRequestOptions()
|
|
requestOptions.isSynchronous = true
|
|
|
|
let fetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions)
|
|
|
|
manager.requestImage(
|
|
for: fetchResult.object(at: 0),
|
|
// TODO: Identify the correct size.
|
|
targetSize: CGSize(width: 358, height: 442),
|
|
contentMode: .aspectFill,
|
|
options: requestOptions
|
|
) { image, err in
|
|
// TODO: Add logic to respond correctly if there's an error.
|
|
completion(image)
|
|
}
|
|
})
|
|
}
|
|
|
|
static func getPhotoPermissionIfNecessary(completionHandler: @escaping (_ authorized: Bool)
|
|
-> Void) {
|
|
if #available(iOS 14, *) {
|
|
// The iOS 14 API is used to prompt users for permission if they previously provided limited
|
|
// access, but have now taken an additional screenshot.
|
|
guard PHPhotoLibrary.authorizationStatus(for: .readWrite) != .authorized else {
|
|
completionHandler(true)
|
|
return
|
|
}
|
|
|
|
PHPhotoLibrary.requestAuthorization(for: .readWrite) { status in
|
|
completionHandler(status != .denied)
|
|
}
|
|
} else {
|
|
guard PHPhotoLibrary.authorizationStatus() != .authorized else {
|
|
completionHandler(true)
|
|
return
|
|
}
|
|
|
|
PHPhotoLibrary.requestAuthorization { status in
|
|
completionHandler(status != .denied)
|
|
}
|
|
}
|
|
}
|
|
|
|
@objc(captureProgrammaticScreenshot)
|
|
public static func captureProgrammaticScreenshot() -> UIImage? {
|
|
// TODO: Explore options besides keyWindow as keyWindow is deprecated.
|
|
let layer = UIApplication.shared.keyWindow?.layer
|
|
|
|
if let layer {
|
|
let renderer = UIGraphicsImageRenderer(size: layer.bounds.size)
|
|
let image = renderer.image { ctx in
|
|
layer.render(in: ctx.cgContext)
|
|
}
|
|
|
|
return image
|
|
}
|
|
|
|
return nil
|
|
}
|
|
}
|