Getting AppDelegate reference while creating framework swift - ios

I am creating a custom framework. I need a reference to the AppDelegate to perform operations e.g get window or some other delegates.
example code:
static var safeArea: UIEdgeInsets {
var padding: UIEdgeInsets = UIEdgeInsets.zero
if #available(iOS 11.0, *) {
if let b = appDel.window?.safeAreaInsets {
padding = b
}
}
return padding
}
The main issue I have is that I need the AppDelegate reference on multiple levels.
Any help regarding this should be appreciated.

Sample Source for comments below :). Create a sampleManager inside framework. Import the framework into appdelegate and set SampleManager.shared.delegate to self as weak reference.
public class SampleManager {
public static let shared = SampleManager()
public weak var delegate: UIApplicationDelegate?
func doWhateverYouWant() {
}
}
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
private let dependencyManager = DependencyManager()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
SampleManager.shared.delegate = self
startAppCoordinator()
return true
}
}

Related

iOS - Restore app state by coordinators after terminate

Navigation system in my app contains coordinator pattern. when my application starts for the first time, everything works well. But when the app recedes into the background and phone system terminate it and I'm trying to get back to it, app starts for the first time again. So I need to restore my app state if system terminate app in background.
My AppDelegate class
import UIKit
import Swinject
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
let container = Container()
private var appCoordinator: AppCoordinator!
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
setupDependecies()
return true
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window = UIWindow()
appCoordinator = AppCoordinator(window: window!, container: container)
appCoordinator.start()
window?.makeKeyAndVisible()
return true
}
func application(_ application: UIApplication, shouldSaveSecureApplicationState coder: NSCoder) -> Bool {
return true
}
func application(_ application: UIApplication, shouldRestoreSecureApplicationState coder: NSCoder) -> Bool {
return true
}
}
AppCoordinator class
import Foundation
import UIKit
import Swinject
enum AppChildCoordinator {
case serial
case topic
}
final class AppCoordinator: Coordinator {
private let window: UIWindow
let container: Container
private var childCoordinators = [AppChildCoordinator: Coordinator]()
private let navigationController: UINavigationController
private let plistService: PlistService
init(window: UIWindow, container: Container) {
self.window = window
self.container = container
navigationController = UINavigationController()
self.window.rootViewController = navigationController
plistService = container.resolve(PlistService.self)!
}
func start() {
let isActivated: Bool?
isActivated = plistService.readPlist(namePlist: "Preferences", key: Constans.isActivated) as! Bool?
if isActivated != nil && isActivated! {
showTopic()
} else {
showSerial()
}
}
private func showSerial() {
let serialCoordinator = SerialCoordinator(container: container, navigationController: navigationController)
childCoordinators[.serial] = serialCoordinator
serialCoordinator.delegate = self
serialCoordinator.start()
}
private func showTopic() {
let topicCoordinator = TopicCoordinator(container: container, navigationController: navigationController)
childCoordinators[.topic] = topicCoordinator
topicCoordinator.delegate = self
topicCoordinator.start()
}
}
extension AppCoordinator: SerialCoordinatorDeligate {
func serialCoordinatorDidFinish() {
childCoordinators[.serial] = nil
showTopic()
}
}
extension AppCoordinator: TopicCoordinatorDeligate {
func topicCoordinatorDidFinish() {
childCoordinators[.topic] = nil
}
}
I understand that when my app starts it run Serial or Topic coordinator without restore logic. For example if user go to Topic coordinator, then to Auth coordinator (child of Topic coordinator), then to Home coordinator (child of Auth coordinator), how can I restore Home coordinator after start terminated by system app?

How to assign boolean value to appdelegate method from view controller

I am new to IOS and swift. Does anyone know how to assign value to boolean appdelegate method? I want to set shouldAllowExtensionPointIdentifier in viewcontroller but i didn't find any solution. Thank you
//
// AppDelegate.swift
// TestKeyboard
//
// Created by Mol Monyneath on 11/1/17.
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
public var Alow : Bool?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch
return true
}
func application(_ application: UIApplication, shouldAllowExtensionPointIdentifier extensionPointIdentifier: UIApplicationExtensionPointIdentifier) -> Bool {
print("\(extensionPointIdentifier.rawValue) allow = \(Alow)")
return Alow!
}
}
Here is Main view controller:
I couldn't block that app . please help
import UIKit
class ViewController: UIViewController,UITextFieldDelegate {
#IBOutlet weak var normaltextView: UITextField!
#IBOutlet weak var txtView: UITextField!
var appDelegate = UIApplication.shared.delegate as! AppDelegate
override func viewDidLoad() {
super.viewDidLoad()
normaltextView.delegate = self
txtView.delegate = self
}
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
if textField.keyboardType == UIKeyboardType.numberPad{
// textField.inputView = nil
txtView.inputView = nil
appDelegate.Alow = false
txtView.reloadInputViews()
print("false")
}else{
print("should Press")
print("True")
// textField.inputView = nil
appDelegate.Alow = true
txtView.reloadInputViews()
normaltextView.reloadInputViews()
}
return true
}
}
thank

Apple TVJS showsPlaybackControls

I need to loop a video in an Apple TV app, and I really would prefer to use TVJS so that we can update easily server side. However, when I loop the video, it shows the playback controls every time, and this is not ideal.
I see that AVPlayerViewController has a showsPlaybackControls bool that can be set to false, and is true by default, but the TVJS Player Class does not seem to have the same available to it.
What I am curious about is if there is a way that from the AppDelegate I can change that default from true to false so that the playbackControls never ever show? I have included my AppDelegate as well below. Thanks in advance!
import UIKit
import TVMLKit
import AVFoundation
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, TVApplicationControllerDelegate {
var window: UIWindow?
var appController: TVApplicationController?
static let TVBaseURL = "http://localhost:3000/"
static let TVBootURL = "\(AppDelegate.TVBaseURL)assets/tv.js"
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window = UIWindow(frame: UIScreen.mainScreen().bounds)
let appControllerContext = TVApplicationControllerContext()
guard let javaScriptURL = NSURL(string: AppDelegate.TVBootURL) else {
fatalError("unable to create NSURL")
}
appControllerContext.javaScriptApplicationURL = javaScriptURL
appControllerContext.launchOptions["BASEURL"] = AppDelegate.TVBaseURL
appController = TVApplicationController(context: appControllerContext, window: window, delegate: self)
return true
}
}

Swift - App Delegate not passing data

I'm developing an App that it's data is from a URL, here's a sample code that I'm using
AppDelegate.swift
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var fromUrl: String!
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject)-> Bool {
print("Host: \(url.host!)")
self.fromUrl = url.host!
return true
}
ViewController.swift
import UIKit
class ViewController: UIViewController {
let appDelegate = AppDelegate()
override func viewDidLoad() {
super.viewDidLoad()
print(appDelegate.fromUrl)
}
It's is logging the url.host from app delegate. But when i try to log the value of fromUrl from the ViewController.swift it's returning nil. What do you think seems to be the problem? Thanks!
When you declare let appDelegate = AppDelegate() in ViewController you are actually instantiating another instance of AppDelegate. That is not the same instance that you are using as you actual ApplicationDelegate. Try getting that reference by using:
if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate {
print(appDelegate.fromUrl)
}

Ignoring the dynamic type in iOS: Accessibility

Is there a way to completely ignore dynamic type/font size settings in iOS apps?
I mean is there a way like a plist entry so that I can disable it completely. I understand there is a notification we can observe and re-configure the font whenever there is change in the settings. I am looking for a simpler solution. I am using iOS8.
Thanks.
There's no need to swizzle UIApplication. Just subclass UIApplication and provide your own implementation of preferredContentSizeCategory:
Swift:
class MyApplication: UIApplication {
override var preferredContentSizeCategory: UIContentSizeCategory {
get { return UIContentSizeCategory.large }
}
}
UIApplicationMain(
CommandLine.argc,
CommandLine.unsafeArgv,
NSStringFromClass(MyApplication.self),
NSStringFromClass(AppDelegate.self)
)
Objective-C:
#interface MyApplication : UIApplication
#end
#implementation MyApplication
- (UIContentSizeCategory) preferredContentSizeCategory
{
return UIContentSizeCategoryLarge;
}
#end
int main(int argc, char * argv[]) {
#autoreleasepool {
return UIApplicationMain(argc, argv, NSStringFromClass([MyApplication class]), NSStringFromClass([AppDelegate class]));
}
}
In your AppDelegate add:
#import <objc/runtime.h>
#implementation AppDelegate
NSString* swizzled_preferredContentSizeCategory(id self, SEL _cmd)
{
return UIContentSizeCategoryLarge; // Set category you prefer, Large being iOS' default.
}
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
Method method = class_getInstanceMethod([UIApplication class], #selector(preferredContentSizeCategory));
method_setImplementation(method, (IMP)swizzled_preferredContentSizeCategory);
...
}
Just provide Swift 4 fix to #gebirgsbärbel answer.
"preferredContentSizeCategory" in Objective-C is a method, but in Swift it is a read-only variable. So in your AppDelegate is like this:
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
// MARK: - UIApplicationDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
UIApplication.classInit
self.window = UIWindow(frame: UIScreen.main.bounds)
...
self.window?.makeKeyAndVisible()
return true
}
}
// MARK: - Fix Dynamic Type
extension UIApplication {
static let classInit: Void = {
method_exchangeImplementations(
class_getInstanceMethod(UIApplication.self, #selector(getter: fixedPreferredContentSizeCategory))!,
class_getInstanceMethod(UIApplication.self, #selector(getter: preferredContentSizeCategory))!
)
}()
#objc
var fixedPreferredContentSizeCategory: UIContentSizeCategory {
return .large
}
}
The swift equivalent to the answer of #meaning-matters looks as follows:
In your AppDelegate:
#objc func swizzled_preferredContentSizeCategory() -> UIContentSizeCategory {
return UIContentSizeCategory.small
}
open func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let originalMethod = class_getInstanceMethod(UIApplication.self, #selector(preferredContentSizeCategory))
let swizzledMethod = class_getInstanceMethod(UIApplication.self, #selector(swizzled_preferredContentSizeCategory))
method_exchangeImplementations(originalMethod, swizzled_preferredContentSizeCategory)
}

Resources