XCode: Find which event was fired without a breakpoint - ios

I'm sorry if this post is in the wrong area, please advise me on where to move it if needs be.
I've just been passed a project from a previous developer and to be honest the repository is horrendous, the previous developer used awful naming conventions, the code is completely serial, no XCAssets, XIB's or Storyboards were used and I'm finding the whole project very hard to navigate - oh and no comments! What sort of developer leaves no comments...
So far it has taken me 4 hours to fix problems that would normally take a matter of minutes due to having to scour through 200 different source files.
I was wondering if there is a way to tell the debugger to stop each time a function is called on a click events - basically on the UI there is a button which is displaying the wrong dialog, due to awful naming conventions I am finding it near impossible to locate the place in the source for me to make changes.
Any advice would be appreciated (I have told the team I am planning to rebuild the whole app, but we are due to launch next week).

Welcome to the world of programming. You are able to add a custom forwarding delegate to the AppDelegate on the Main start up that will intercept events such as the ones you described above via
int retVal = UIApplicationMain(argc, argv, #"MyListenerHere", nil)

Related

SwiftUI / iOS 14: How to restore last active document (state?) with document-based (DocumentGroup) app

I am working with Xcode's provided SwiftUI multi-platform, document-based app template.
Everything so far has been "smooth sailing", if you will, however I have no been able to figure out something I though was "built in":
If, for some OS management reason the app gets "killed" (or if intentionally, by stopping it in Xcode), when relaunched, the app "forgets" the document the user was working on, and starts up showing the document browser instead.
I looked on the documentation, and found an article titled "Restoring your app's state with SwiftUI" - this article offers sample code for a non-document-based app, but for the life of me I cannot even begin to understand what it is I am supposed to do to adapt it to a doc-based (DocumentGroup) scenario.
I "understand" the concept of SceneStorage, I was even able to persist some random text declared as a SceneStorage property of the example ContentView, but I cannot understand how am I supposed to use this to, when relaunching the app, have the last open document, well, back open.
I sort of tried to do this at the #main code declaration, but could not make it work.
Also, Google has NOT been my friend in this case - have not been able to find a single example of this particular scenario anywhere.
I know I might pass as a "noob" (I am...) and that this is fairly new, so I should expect lack of "stuff" around, and that this should not be so hard, so please forgive my "noob-iness" in advance.
If anyone has any idea about how to achieve this, or can point me to a WORKING sample with a document-based/DocumentGroup app, I will be eternally grateful.

(iOS) Way of viewing log messages directly on an iOS device?

As nice as debuggers have gotten these days, sometimes the best way of finding out what is going on in an app is still ye olde NSLog. Doing this is easy when you're tethered to your computer; Xcode helpfully pops up the Log Viewer panel and there you go. Not so easy to do when you're away from your desk, as you sometimes have to be when testing an app (for example, when you are testing CoreLocation functionality). Sure you can pop open Xcode and check the Console section of the Device Organizer as soon as you get back from a testing run, but then you have to wait, and by the time you can get back to view the logs you forgot what was going wrong with your app; also odds are that by the time you are able to do this, the log messages you are looking for have scrolled off into oblivion.
Is there any way of checking the console logs on the device itself? I'm guessing the answer is "no, unless you jailbreak" (IIRC there are at least one or two terminal apps in jailbreak-land that I could use to do this sort of thing). Unfortunately jailbreaking is not an option for me.
Alternatively, is there some sort of Objective-C framework or library or whatnot that handles log collection and on-device displaying? Ideally this would come in the form of a drop-in replacement for NSLog, whereby I could simply do a search-and-replace and change all occurrences of NSLog to SomeFancyPantsLoggingTool or whatever and be done with it.
A good example of the kind of functionality I am looking for can be found in the podcast client Downcast. If you tap the "More" tab, then tap on the version number string at the bottom of the screen, a new view slides up that contains a scrollable view of accumulated log messages. It even has an easy way of mailing said logs to a support e-mail address.
Take a look at LibComponentLogging which you can configure to output logging at different levels and to different destinations.
There is a file for the SysLog. You can simply open it and read from it. The file is at /var/log/syslog. If the file does not exist there are instructions on how to set it up here.

Adding pin on mapView is not working on appstore version

I have submitted my app and been accepted couple of weeks ago. However, I have an issue that one of my critical functionality which is adding pin is not working but it works in building version. Adding pin requires URL connection. Could you please look at the answer that I get from apple developer and guide me please?
It shouldn't be causing your problem (at least not directly), but in general
having networking code like this live inside your UI code is very problematic
for a number of reasons:
-On general architecture grounds, it's a large violation of the MVC (model
view controller) architecture. The pin annotation is obviously heavily tied
to your UI (the view), while networking is clearly part of your backend (the
model).
-Because iOS REQUIRES the main thread to remain responsive, attaching code
that does IO or computation to the main thread is inherently risky. It can be
done and work well, but doing it incorrectly will inevitably lead to crashes.
NSURLConnection works in background and interactions with UI should go on main thread.
So, if you add your pin at the connectionDidFinish method for example, you should do like this:
[mapView performSelectorOnMainThread:#selector(addAnnotation:) withObject:yourAnnotation waitUntilDone:[[NSThread currentThread] isMainThread]];
Hope that helps you. I wrote from windows but the line should work.
I'm not exactly sure about what you are trying to achieve. Are App folks complaining because you are fetching URL directly in the Main thread ? Could you just send a code snippet showing how you fetch urls ?
One option would be to drop the pin (not tied to URL connection at all) and once the pin drops, load your data for the callout or annotation (which is what I'm assuming you are doing). You can always put a loading indicator or progressHUD up to tell the user they need to wait for something. It isn't exactly ideal, but in instances where you need to wait for data, what are you going to do?
Apple really doesn't care about blocking the UI so long as the user is aware you are blocking it. Like a progress bar or progress HUD. The user can see the app is still working and doing something. Not showing anything and having the UI just freeze while it waits for the main thread/main loop to return isn't going to work. It is just bad design and Apple will likely ding you for it.

What are good strategies to debug iOS apps with 'dangling UIViews'?

I recently inherited maintenance of a relatively small iOS application. The app was created by external contractors with very little guidance and oversight. Needless to say it needs "a little" cleaning - I am evaluating whether to redo the entire thing or not.
One thing that got me stumped is a crash in the app whereby the debugger shows "Applications are expected to have a root view controller at the end of application launch". In the module where this occurs, I researched all UIViews to make sure they are created with a parent (addSubView sets the root view controller, right?) - this seems all prim and proper.
Being rather new to XCode, I am not familiar with facilities that help me figure out what might be going on here. E.g., how can I quickly see/investigate the status of all UIViews created by a module? How can I 'watch' a variable just to be alerted when it changes? And in general, is there a best strategy to use to tackle issues like the one I described above?
Sorry to stay a bit vague but I don't think that publishing a bunch of ugly code helps you to understand the problem better :-)
That particular problem happens when the application's UIWindow doesn't have a value for its rootViewController property by the time it finishes launching. Take a look in your application delegate file - usually, the root view controller is set on the window there.
With regards to your more general questions: there are a variety of ways to inspect the state of your program as it runs. A very basic way to dump some info is to use an NSLog statement - you can print out messages to the console in much the same way as a C printf would. You can also set breakpoints in your application and use the debugger to inspect different variables - take a look at the lldb documentation for more info.
Whether you have "dangling" UIViews or not has not much to do with having a root view controller or not.
Instead, you should make sure that your app's UIWindow has a rootViewController at the end of your app delegates appDidFinishLaunching method.

Delphi, TPopupMenuItems behaving strangely after the application is idle for a long time

I have a problem I cannot solve. Of course here I just expect to have a suggestion that can help me to find a solution.
Basically my application is full of runtime generated TPopupMenuItems (while all the TPopupMenus are hardcoded). In some cases what I do is simply hide/show or enable/disable items, in other cases I create items at runtime.
In some machines only, after leaving the application running for days (2 or more) the popupmenus don't work anymore correctly.
The behaviour is:
all the TPopupmenu items look are the same, and execute the same action.
The action is the one performed by the first TPopupMenuItem of the application (the first generated at runtime when the application starts, this is the only hint I have).
Imagine in correct scenario I have (in a 3-items-TPopupMenu):
Item23
Item24
Item25
after the problem I see:
Item1
Item1
Item1
(where Item1 is the TPopupMenuItem belonging to another TPopupMenu).
Does this tell you something?
Thanks.
Update:
I tried to look at the code of my popupmenus and I found what could be a common cause, and this explains also why FastMM4 didn't find this:
while mnuItem.Count > 0 do
mnuItem.Delete(0);
Delete (I just read in the documentation) doesn't free the item, I should call free instead. Anyway when closing the application the main popupmenus are freed correctly, and FastMM4 doesn't complain. So this is probably the solution, now I don't know why Delete was used, I didn't write that code.
Further update:
I tried to make a sample application, I couldn't reproduce the problem, but for sure I noticed that using this is much more performant (I tried a loop with 10000 recursions):
while mnuItem.Count > 0 do
mnuItem.Items[0].Free;
I will try for this in my app (but I need to let some days pass to really know if I got the problem, ayway for sure this is a major improvement anyway).
I confirm that the problem was linked to Delete instead of Free. Popupmenu wsa refreshed every minute on the machines that had the problem (so it was not OS or HW specific, just config specific). Then according to user settings the menu could have 10 to 100 items, so leaving it idle for days made it possible to hit the handle limit.
By the way it also makes no sense to refresh the popupmenu in that way, so I found also an optimizaion removed a bug.
Did you check for memory leakage and handles that aren't freed?

Resources