Detect URL Change in ContentView.swift iOS app Swift - swift

Trying to detect change event of the URL being navigated to somewhere else when the user changes the currently viewed webpage. Here is my code.
struct WebView: UIViewRepresentable {
var view = WKWebView()
init() {
print("initialized")
}
func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if let newValue = change?[.newKey] as? Int, let oldValue = change?[.oldKey] as? Int, newValue != oldValue {
//Value Changed
print(change?[.newKey])
}else{
//Value not Changed
print(change?[.oldKey])
}
}
func makeUIView(context: UIViewRepresentableContext<WebView>) -> WKWebView {
while(!authenticated) {
}
DispatchQueue.main.async {
var url = URL(string:"https://www.runixcoin.com/")!
if (faceIdSuccess) {
url = URL(string:"https://www.runixcoin.com/dashboard/auth-login-basic.php?face_id=true")!
}
else {
url = URL(string:"https://www.runixcoin.com/dashboard/auth-login-basic.php?return_url=https://www.runixcoin.com/dashboard/dashboard-4.php")!
}
let request = URLRequest(url: url)
view.load(request)
view.addObserver(view, forKeyPath: "URL", options: .new, context: nil)
}
return view
}
func updateUIView(_ uiView: WKWebView, context: UIViewRepresentableContext<WebView>) {
}
typealias UIViewType = WKWebView
}
The observeValue function is getting called and printing the results I want when the user navigates away from the current page, however the app is crashing... I want to stop the app from crashing. I even tried using the removeObserver code and it either prevented the function from being called or would still crash... What do I need to do?
2022-04-04 18:21:55.489370-0400 Runixcoin[6797:1762100] [error] warning: View context accessed for persistent container runixcoin with no stores loaded
CoreData: warning: View context accessed for persistent container runixcoin with no stores loaded
initialized
Logged in with FaceID
2022-04-04 18:21:58.914721-0400 Runixcoin[6797:1762100] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '<WKWebView: 0x106025e00; frame = (0 0; 428 796); layer = <CALayer: 0x283bb1b80>>: An -observeValueForKeyPath:ofObject:change:context: message was received but not handled.
Key path: URL
Observed object: <WKWebView: 0x106025e00; frame = (0 0; 428 796); layer = <CALayer: 0x283bb1b80>>
Change: {
kind = 1;
new = "https://www.runixcoin.com/dashboard/auth-password-basic.php";
}
Context: 0x0'
*** First throw call stack:
(0x1811e50fc 0x199a35d64 0x182ad0adc 0x1829a30cc 0x18298ed90 0x1829c8508 0x18fd95468 0x18fd951c0 0x18fe1b82c 0x18fe1b380 0x1901932c0 0x18fa41114 0x18fe69850 0x18fa1ebe4 0x18fa1e1f4 0x18d2d6e44 0x18d2d7fb4 0x1812070d0 0x181217d90 0x181152098 0x1811578a4 0x18116b468 0x19cd0f38c 0x183b0e5d0 0x18388cf74 0x188e2a314 0x188d59508 0x188d3acb8 0x104f080d4 0x104f0818c 0x10510daa4)
libc++abi: terminating with uncaught exception of type NSException
dyld4 config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/Developer/usr/lib/libBacktraceRecording.dylib:/Developer/usr/lib/libMainThreadChecker.dylib:/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '<WKWebView: 0x106025e00; frame = (0 0; 428 796); layer = <CALayer: 0x283bb1b80>>: An -observeValueForKeyPath:ofObject:change:context: message was received but not handled.
Key path: URL
Observed object: <WKWebView: 0x106025e00; frame = (0 0; 428 796); layer = <CALayer: 0x283bb1b80>>
Change: {
kind = 1;
new = "https://www.runixcoin.com/dashboard/auth-password-basic.php";
}
Context: 0x0'
terminating with uncaught exception of type NSException
(lldb)

Related

Tableview crashes when I try to get images from firebase

I get this error.Ive also provided a screenshot with a more detailed look at the error I've never seen this before
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread.'
//MARK: EXPLANATION (your passing item in down below because this allows you to call whatever is in the item class)
func generateCellForITEMS(item : Item){
nameLabel.text = item.name
descriptionLabel.text = item.description
priceLabel.text = convertCurrency(item.price )
priceLabel.adjustsFontSizeToFitWidth = true // this will adjust the font of the label sizse to helpt it fit even with a large price
if item.imageLinks != nil && item.imageLinks.count > 0 {
downLoadImages(imageUrls: [item.imageLinks.first!]) { (images) in
self.ItemImageView.image = images.first as? UIImage
}
}
}
You need to update the UI from the main thread as the error suggests:
downLoadImages(imageUrls: [item.imageLinks.first!]) { (images) in
DispatchQueue.main.async {
self.ItemImageView.image = images.first as? UIImage
}
}

Snapshotting a `UIView` crashes the app with `NSInvalidArgumentException` "[_UIReplicantView _isSymbolImage]: unrecognized selector sent to instance"

Hi guys i have just updated XCode to version 11.4 from the app store and when i try to snapshot a UIView on iOS 13.4 like this:
extension UIView {
func snapshot(at scale: CGFloat) -> UIImage? {
let renderer = UIGraphicsImageRenderer(size: bounds.size)
let image = renderer.image { [weak self] context in
self?.drawHierarchy(in: self?.bounds ?? .zero, afterScreenUpdates: true)
}
return image
}
}
or like that:
extension UIView {
func snapshotOld(at scale: CGFloat) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(bounds.size, false, scale)
guard let currentContext = UIGraphicsGetCurrentContext() else { return nil }
layer.render(in: currentContext)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
and set the resulting image to UIImageView like that:
class ViewController: UIViewController {
#IBOutlet private weak var imageView: UIImageView!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let image = view.snapshot
imageView.image = image
}
}
extension UIView {
#objc var snapshot: UIImage? {
snapshot(at: 3.0)
// snapshotOld(at: 3.0)
}
}
i get:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_UIReplicantView _isSymbolImage]: unrecognized selector sent to instance 0x115907c00'
*** First throw call stack:
(0x1ad52c164 0x1ad240c1c 0x1ad42a7e0 0x1b16a5b6c 0x1ad53085c 0x1ad532b60 0x1b1af6cdc 0x1b1af714c 0x1b1af0b30 0x1025061a8 0x102506270 0x1b1010880 0x1b10112cc 0x1b0f25658 0x1b167fc10 0x1b166f13c 0x1b16a088c 0x1ad4a6c54 0x1ad4a18e4 0x1ad4a1d84 0x1ad4a1660 0x1b78b2604 0x1b167615c 0x102507f78 0x1ad31d1ec)
libc++abi.dylib: terminating with uncaught exception of type NSException
I get this both in simulator and on a real device.
Do you guys have any idea why is this happening? I suspect it is a XCode 11.4 bug because this code worked nicely on the older versions 🤔
Here is a sample project if you would like to try it out on your machine
You're not calling the method you think you are. You have two choices:
Change snapshot to snapshott everywhere (or some other nonambiguous alternative).
Or else, remove the #objc designation.
Do either of those things, and all will be well.

Why a change in my firebase database makes my app crash

I am building an application with WebView and Firebase as database. The url used to load the vewView comes from the database.
I have implemented both WebView and Firebase correctly but the problem is that when I change an url in the database, my app crashes. It basically saying that the url is nil...which is not in reality since the new url is completely valid.
Even when I rebuild my app, the error still continues....
class ViewController: UIViewController {
var dbRef: DatabaseReference!
var nextUrl = "https://www.google.co.uk/"
func retrieveUrl () {
dbRef = Database.database().reference().child("EXAMPLE")
dbRef.observe(.value) {
(snapshot) in
let value = snapshot.value as! NSDictionary
let url = value["url"]!
self.nextUrl = (url as! String)
print (nextUrl)
print ("webview is about to load")
let request = URLRequest (url: URL(string: nextUrl)!)
self.webView.load(request)
self.webView.addObserver(self, forKeyPath: #keyPath(WKWebView.isLoading), options: .new, context: nil)
}
print ("function observe is called")
}
override func viewDidLoad () {
super.viewDidLoad()
retrieveUrl()
}
Here is the fatal error:
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

Error calling on managedobject with EXC_BAD_ACCESS

I searched a lot for this error and was not able to find a solution.
I have my managedObject:
lazy var managedObjectContext: NSManagedObjectContext = {
let coordinator = self.persistentStoreCoordinator
var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
and I have a Singleton class
lazy var managedObjectContext : NSManagedObjectContext? = {
if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate {
return appDelegate.managedObjectContext
}
return nil
}()
I have a method which is called lot of time whenever I update / delete / load data from database
class func LoadDatabase(tableName: String, predicateString: String, predicateIntValue: Int) -> [AnyObject]? {
do {
let managedObjectContext = Singleton.sharedInstance.managedObjectContext
if managedObjectContext == nil {
return nil
}
let fReq: NSFetchRequest = NSFetchRequest(entityName: tableName)
if predicateString != "" {
fReq.predicate = NSPredicate(format: predicateString, predicateIntValue)
}
var result: [AnyObject]
do {
if managedObjectContext == nil {
return nil
}
result = try managedObjectContext!.executeFetchRequest(fReq)
} catch {
return nil
}
// update exist event
if
result.count != 0 {
return result
}
} catch let error1 as NSError {
print("No values to load for table: \(error1)")
}
return nil
}
I think I have problem on concurrence access. When the app starts it stars asynchronous requests to update the database. But I also call the method LoadDatabase from varius controller. Once the asynchronous call done with updating the datable, it call another method to delete datas which are not more in remote database.
This is what I get. This does not happens always.
I tried to change to MainQueueConcurrency but now I am getting also this error:
2016-03-20 21:27:01.371 Tamil League[1070:245784] CoreData: error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. -[__NSCFSet addObject:]: attempt to insert nil with userInfo (null)
2016-03-20 21:27:01.371 Tamil League[1070:245784] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFSet addObject:]: attempt to insert nil'
*** First throw call stack:
(0x24a9e2eb 0x2426adff 0x24a9e231 0x249e7fe5 0x261eb683 0x261ea063 0x261e2dfb 0x24a60b21 0x24a5ee17 0x24a5f255 0x249b1bb9 0x249b19ad 0x25c2baf9 0x28c9dfb5 0xa6d5c 0x24664873)
libc++abi.dylib: terminating with uncaught exception of type NSException
Does anyone know how to solve this?

Parse NSInternalInconsistencyException raises with PFImageView

I'm experiencing an odd behaviour of Parse right now.
My App worked fine for weeks of development and never raised a 'NSInternalInconsistencyException' since project setup.
But I just implemented a PFImageView in my ProfileViewController (second VC in UITabBarController, therefore only showing when user is logged in) and my App keeps crashing with this error:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'You have to call setApplicationId:clientKey: on Parse to configure Parse.'
Of course I checked my Parse setup in func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool:
Parse.setApplicationId("myApplicationID", clientKey: "myClientKey")
Parse.enableLocalDatastore()
// This is where I used to activate Parse, but SO and Parse forums kept
// saying you should try to do this at the very beginning
ParseCrashReporting.enable()
PFAnalytics.trackAppOpenedWithLaunchOptionsInBackground(launchOptions, block: nil)
In my ProfileViewController this is where I load my image from Parse:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
userImageView.file = user["profilePicture"] as PFFile
userImageView.loadInBackground { (image, error) -> Void in
if error != nil {
JSSAlertView().danger(self, title: "Loading Image Failed", text: "Please check your connection")
} else {
self.userImageView.image = image
}
}
}
Setting the instance variable of image:
var image: UIImage? {
// If User picked a new image, automatically update imageView
didSet {
userImageView.image = image
// Convert image to PNG and save in in Parse-Cloud
let imageData = UIImagePNGRepresentation(image)
let imageFile = PFFile(name: "profilePicture.png", data: imageData)
// Attach this file to our user
user["profilePicture"] = imageFile
user.saveInBackgroundWithBlock { (success, error) -> Void in
if error != nil {
JSSAlertView().danger(self, title: "Failed To Save Image", text: "Please try again saving your image!")
}
}
userImageView.file = user["profilePicture"] as PFFile
}
}
I have no clue what kind of connection could be between these things, but I didn't change anything else in the whole project.
Regards,
Ok, finally after hours of trial and error I found the solution for this problem.
You should never ever execute parse calls in the header of view controllers, as these calls could be executed before the API registration.
For example:
class ViewController: UIViewController {
// this will crash the app as above!
var user: PFUser! = PFUser.currentUser()
override func viewDidLoad() {
super.viewDidLoad()
// initialize the user here. This will work just fine
user = PFUser.currentUser()
}
}
Hope this saves you from having the same errors!