UIPrinterPickerController not showing on iOS 13 - ios

I've been trying to get a UIPrinterPicker to show up but for some reason it just never does. The completion handler gets called immediately. The UIPrintInteractionController shows up just fine but this one refuses to show for some reason. This is the code I am using currently
let picker = UIPrinterPickerController(initiallySelectedPrinter: nil)
picker.present(animated: true) { (controller, complete, error) in
print("done")
}

Implement UIPrinterPickerControllerDelegate so it works for iOS 13
https://developer.apple.com/documentation/uikit/uiprinterpickercontroller/1620514-present
class ViewController: UIViewController {
#IBAction func btnTapped(_ sender: Any) {
let picker = UIPrinterPickerController(initiallySelectedPrinter: nil)
picker.delegate = self
picker.present(animated: true) { (controller, complete, error) in
print("done")
}
}
}
// MARK:- UIPrinterPickerControllerDelegate
extension ViewController: UIPrinterPickerControllerDelegate {
func printerPickerControllerParentViewController(_ printerPickerController: UIPrinterPickerController) -> UIViewController? {
return self
}
}

Related

Protocol-Delegate pattern not notifying View Controller

My Model saves data to Firestore. Once that data is saved, I'd like it to alert my ViewController so that a function can be called. However, nothing is being passed to my ViewController.
This is my Model:
protocol ProtocolModel {
func wasDataSavedSuccessfully(dataSavedSuccessfully:Bool)
}
class Model {
var delegate:ProtocolModel?
func createUserAddedRecipe(
docId:String,
completion: #escaping (Recipe?) -> Void) {
let db = Firestore.firestore()
do {
try db.collection("userFavourites").document(currentUserId).collection("userRecipes").document(docId).setData(from: recipe) { (error) in
print("Data Saved Successfully") // THIS OUTPUTS TO THE CONSOLE
// Notify delegate that data was saved to Firestore
self.delegate?.wasDataSavedSuccessfully(dataSavedSuccessfully: true)
}
}
catch {
print("Error \(error)")
}
}
}
The print("Data Saved Successfully") outputs to the console, but the delegate method right below it doesn't get called.
And this is my ViewController:
class ViewController: UIViewController {
private var model = Model()
override func viewDidLoad() {
super.viewDidLoad()
model.delegate = self
}
}
extension ViewController: ProtocolModel {
func wasDataSavedSuccessfully(dataSavedSuccessfully: Bool) {
if dataSavedSuccessfully == true {
print("Result is true.")
}
else {
print("Result is false.")
}
print("Protocol-Delegate Pattern Works")
}
}
Is there something I'm missing from this pattern? I haven't been able to notice anything different in the articles I've reviewed.
So I test your code and simulate something like that
import UIKit
protocol ProtocolModel {
func wasDataSavedSuccessfully(dataSavedSuccessfully:Bool)
}
class Model {
var delegate:ProtocolModel?
// I use this timer for simulate that firebase store data every 3 seconds for example
var timer: Timer?
func createUserAddedRecipe(
docId:String) {
timer = Timer.scheduledTimer(withTimeInterval: 3, repeats: true, block: { _ in
self.delegate?.wasDataSavedSuccessfully(dataSavedSuccessfully: true)
})
}
}
class NavigationController: UINavigationController {
var model = Model()
override func viewDidLoad() {
super.viewDidLoad()
model.delegate = self
// Call this method to register for network notification
model.createUserAddedRecipe(docId: "exampleId")
}
}
extension NavigationController: ProtocolModel {
func wasDataSavedSuccessfully(dataSavedSuccessfully: Bool) {
print(#function)
}
}
so you can see the result as image below, my delegate update controller that conform to that protocol.

How to create a Cancel button on the screen that selects the file on Swift5?

I am using UIDocumentBrowser to retrieve files. But I am not able to place a back or cancel button in the navigation bar.
I want to make a cancellation button for this but I can't make a cancellation button. How can I solve this problem?
current code
import Foundation
import UIKit
#available(iOS 11.0, *)
class DocumentBrowserViewController : UIDocumentBrowserViewController, UIDocumentBrowserViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
delegate = self
browserUserInterfaceStyle = .dark
view.tintColor = .white
}
func documentBrowser(_ controller: UIDocumentBrowserViewController, didRequestDocumentCreationWithHandler importHandler: #escaping (URL?, UIDocumentBrowserViewController.ImportMode) -> Void) {
let newDocumentURL: URL? = nil
// Set the URL for the new document here. Optionally, you can present a template chooser before calling the importHandler.
// Make sure the importHandler is always called, even if the user cancels the creation request.
if newDocumentURL != nil {
importHandler(newDocumentURL, .move)
} else {
importHandler(nil, .none)
}
}
func documentBrowser(_ controller: UIDocumentBrowserViewController, didPickDocumentURLs documentURLs: [URL]) {
guard let sourceURL = documentURLs.first else { return }
do{
try presentDocument(at: sourceURL)
} catch {
Log.Debug("\(error)")
}
}
func documentBrowser(_ controller: UIDocumentBrowserViewController, didImportDocumentAt sourceURL: URL, toDestinationURL destinationURL: URL) {
// Present the Document View Controller for the new newly created document
do{
try presentDocument(at: sourceURL)
} catch {
Log.Debug("\(error)")
}
}
func documentBrowser(_ controller: UIDocumentBrowserViewController, failedToImportDocumentAt documentURL: URL, error: Error?) {
// Make sure to handle the failed import appropriately, e.g., by presenting an error message to the user.
}
func presentDocument(at documentURL: URL) throws {
guard documentURL.startAccessingSecurityScopedResource() else {
throw IXError.fileAcessFailed
}
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
let documentViewController = storyBoard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
documentViewController.document = Document(fileURL: documentURL)
}
}
picture of cancellation button that I want
Help me a lot
Thanks in advance.
Do I understand correctly that you want to push a viewController (documentViewController) on the navigation stack and have a back button on the navigationBar that leads you back to your main viewController (DocumentBrowserViewController)? If so first you need to push documentViewController on the current navigation stack.
First of all, does the documentViewController appears?
What I see is that you instantiate a documentViewController, set it's document to Document(...) and end of story. I don't use storyboard but does instantiate presents the viewController?
If you provide more details I will update the answer. But general conclusion is in your presentDocument(...), you need:
self.navigationController?.pushViewController(documentViewController, animated: true)
I learned about the UIDocumentBrowserViewController class and succeeded in adding buttons. But the position of the button is not where I want it to be.
But this has solved my fundamental problem, so I'll end the question.
override func viewDidLoad() {
super.viewDidLoad()
delegate = self
allowsDocumentCreation = false
allowsPickingMultipleItems = false
browserUserInterfaceStyle = .dark
view.tintColor = .white
let cancelbutton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelButton(sender:)))
additionalTrailingNavigationBarButtonItems = [cancelbutton]
}
#objc func cancelButton(sender: UIBarButtonItem) {
dismiss(animated: true, completion: nil)
}

ReplayKit stops screen recording in background mode of the application or outside the app?

I've implemented screen recording with ReplayKit in foreground mode of the application. But when I'm going outside the app with home button app stops background record.
--> There is an app available In App Store which allows background screen record.
--> If I have to use Broadcast upload and UI extension then please provide me some programming guide. I've added both in my app but still it stops recording in background mode.
Below is my code
import UIKit
import ReplayKit
class ViewController: UIViewController {
let recorder = RPScreenRecorder.shared()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func btnStartRecord_Action(_ sender: UIButton) {
if recorder.isAvailable {
if !recorder.isRecording {
recorder.startRecording { (error) in
if let error = error {
print(error)
}
}
}
}
}
#IBAction func btnStopRecord_Action(_ sender: UIButton) {
if recorder.isAvailable {
if recorder.isRecording {
recorder.stopRecording { (previewVC, error) in
if let previewController = previewVC {
previewController.previewControllerDelegate = self
self.present(previewController, animated: true, completion: nil)
}
}
}
}
}
}
extension ViewController: RPPreviewViewControllerDelegate {
func previewControllerDidFinish(_ previewController: RPPreviewViewController) {
previewController.dismiss(animated: true) {
}
}
}

How to make initial view controller present again in iOS?

I have an app that uses a main screen (below) and then a barcode scanner framework to scan in a barcode and then I will code an action to perform. However, the problem I am having is that in the code it takes me back to the scanning screen. I have tried to use present(VC1, animated: true, completion: nil) and it does not know what VC1 is.
I assigned VC1 in Xcode under storyboard id (see below):
Below is my code here for view controller.swift. Now the code takes you back to the scanning screen, but I want to go back to VC1 the main view controller.
import UIKit
import BarcodeScanner
var presentedViewController: UIViewController?
final class ViewController: UIViewController {
#IBOutlet var pushScannerButton: UIButton!
//Present view and handle barcode scanning
#IBAction func handleScannerPush(_ sender: Any, forEvent event: UIEvent) {
let viewController = makeBarcodeScannerViewController()
viewController.title = "Barcode Scanner"
present(viewController, animated: true, completion: nil)
}
private func makeBarcodeScannerViewController() -> BarcodeScannerViewController {
let viewController = BarcodeScannerViewController()
viewController.codeDelegate = self
viewController.errorDelegate = self
viewController.dismissalDelegate = self
return viewController
}
}
// MARK: - BarcodeScannerCodeDelegate
extension ViewController: BarcodeScannerCodeDelegate {
func scanner(_ controller: BarcodeScannerViewController, didCaptureCode code: String, type: String) {
print("Barcode Data: \(code)")
print("Symbology Type: \(type)")
controller.dismiss(animated: true, completion: nil)
// DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
// controller.resetWithError()
// }
}
}
// MARK: - BarcodeScannerErrorDelegate
extension ViewController: BarcodeScannerErrorDelegate {
func scanner(_ controller: BarcodeScannerViewController, didReceiveError error: Error) {
print(error)
}
}
// MARK: - BarcodeScannerDismissalDelegate
extension ViewController: BarcodeScannerDismissalDelegate {
func scannerDidDismiss(_ controller: BarcodeScannerViewController) {
controller.dismiss(animated: true, completion: nil)
}
}

App works in simulator but not on device

My app runs fine on simulator but when I run on device it hangs on the first view. It doesn't call anything in viewDidLoad or viewDidAppear. Running swift 3, iOS 10, device is a 6S updated to iOS 10.
import UIKit
import Firebase
import SwiftKeychainWrapper
class FirstVC: UIViewController {
override func viewDidLoad() {
}
override func viewDidAppear(_ animated: Bool) {
// MARK: Checks if you have an account and never logged out
if let userId = KeychainWrapper.defaultKeychainWrapper().stringForKey(KEY_UID) {
DataService.ds.REF_USERS.child(userId).observeSingleEvent(of: .value, with: { (FIRDataSnapshot) in
guard let dict = FIRDataSnapshot.value as? NSDictionary, let setup = dict["setup"] as? Bool else {
self.performSegue(withIdentifier: "firstToDemo", sender: nil)
return
}
if setup {
self.performSegue(withIdentifier: "firstToPollBar", sender: nil)
} else {
self.performSegue(withIdentifier: "firstToDemo", sender: nil)
}
})
} else {
self.performSegue(withIdentifier: "firstToLogin", sender: nil)
}
}
}

Resources