Advertise here




Advertise here

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Free Utility For Adding Logs

BrianSlickBrianSlick Treadmill Desk NinjaPosts: 10,676Tutorial Authors, Registered Users @ @ @ @ @ @ @ @
edited May 2014 in iOS SDK Development
NOTE: I've made a new version. Scroll down to find the post. The original here still works, though.

Offered with very little support is this:

TrackingLogsService.zip
See GitHub instead: BTITrackingLogs

Edit: The zip file is obsolete, and I'm no longer providing the full package, just the Xcode project on GitHub. So some of the instructions below no longer apply; you'll have to build the whole thing from scratch.

Edit 2: See this thread for some complementary services.

Contents:

- An Xcode project that builds an Automator action
- A pre-made instance of said action
- A sample Automator Workflow using said action

How to make it:

I don't actually know that much about Automator, so I don't know if you can just drop in what I've included, or if you will need to make stuff for yourself.

- Build the app and then reveal the product in the Finder, just like you would for an iPhone app.
- The .action needs to wind up in ~/Library/Automator
- The Workflow needs to be in ~/Library/Services

If drag-n-drop doesn't work, create a new Automator Workflow using the Service template. Name it whatever you want. Use these settings at the top:
Service receives selected -text- in -any application-
-checkmark ON- Replaces selected text

Then find the action and drag it into your workflow. It will probably be found in your "Recently Added" smart folder. Save.

This should appear in your Services menu any time you have text selected. If you want to assign a key command, System Preferences -> Keyboard -> Keyboard Shortcuts tab -> Select Services on the left -> Find the name you gave the Automator action, assign whatever key combo you want. I'm currently using Cmd-Shift-1.

What it does:

I use lots and lots and lots of NSLogs. For the most part, I have these tracking logs built in to my class templates. However, I routinely encounter methods that don't have them, either newly created ones of my own, classes I don't have custom templates for, client projects, etc. I still want my logs. Up until now, this has been a copy-paste operation for me, and it can get old. Inspired by Accessorizer (highly, highly recommended), I set out to make my own utility.

So, you have a typical method:
- (void)someMethod
{       // <---- Double-click the {
    [anObject doSomething];
}       // <---- Or double-click the }

Double-clicking either brace will select the entire method except for the name.

Perform the service, and you wind up with this:
- (void)someMethod
{
   NSLog(@>>> Entering %s <<<, __PRETTY_FUNCTION__);

   [anObject doSomething];

   NSLog(@<<< Leaving %s >>>, __PRETTY_FUNCTION__);
}

Fun fact: I just used that service here in Safari, too.

Characteristics I wanted that this service does:

- If the selected text does NOT begin with a { AND end with a }, then the selected text is not modified.
- If the method has a return value, the 'leaving' log is placed before the return line. This is based strictly on the presence of "return", it is not doing anything to inspect the method name.
- If the logs are already there, they will not be duplicated.

The Future:

I'm mostly just throwing this out there in case anyone else would find it useful. Although I'm happy to entertain good ideas, I don't really envision changing this very much. The only other thing I might add is a scan for multiple 'return' lines in the selection. The code is made available so you can tailor it to your liking. Feel free to point out bugs.

Enjoy.

Lion

I just did a clean install of Lion, so I had to manually replace this. Download the linked zip file above. It contains 2 documents, and a folder containing the Xcode project. You can double-click on each document (separately, I assume; didn't try both), and you will be prompted to install them. This will place them into the file locations mentioned above. After that, assign your key combo, and you're good to go. It still works as far as I can tell.
Post edited by BrianSlick on
Professional iOS App Development. Available for hire.
BriTer Ideas LLC - WWW | Facebook | Twitter | LinkedIn

BTIKit | BTICoreDataKit | SlickShopper 2 | Leave a PayPal donation

Replies

  • scgregscgreg Posts: 9New Users
    edited July 2010
    Loving it - cheers Brian!
  • musicwind95musicwind95 Posts: 365Registered Users
    edited August 2010
    In my files, I do a

    #define dNSLog NSLog

    statement in the beginning or header file. Then I just call dNSLog (@NSLog called); It is easier than typing #ifdef every single time, and when it comes time to release, just change the define to // (it'll comment out all the dNSLogs).

    Great utility though. Thanks!
    If I have helped you, <a href="http://bit.ly/mw95donate"; target="_blank">please consider donating</a>. I use PayPal. It would mean a lot to me!<br />
    <br />
    <a href="http://cupsofcocoa.wordpress.com/"; target="_blank">20100829-
  • musicwind95musicwind95 Posts: 365Registered Users
    edited August 2010
    Also, for someone with more experience in Automator...it would be nice if the service could automatically parse through the files (maybe by looking for matching curly braces)? On that note, it would also be nice to add this into an if() or for() statement, for the same purposes as the utility was originally designed for.
    If I have helped you, <a href="http://bit.ly/mw95donate"; target="_blank">please consider donating</a>. I use PayPal. It would mean a lot to me!<br />
    <br />
    <a href="http://cupsofcocoa.wordpress.com/"; target="_blank">20100829-
  • BrianSlickBrianSlick Treadmill Desk Ninja Posts: 10,676Tutorial Authors, Registered Users @ @ @ @ @ @ @ @
    edited August 2010
    The algorithm is in Cocoa, so you could modify it. I thought about going after any curly brace in the selection, but I generally don't add logs to interior ones, so it was overkill for my purposes. It wouldn't take much to change the code to do that, however. But you can double-click any curly brace and this utility will work. It's not limited to methods. The text selection just has to begin with { and end with }.

    Parsing through all files is a bigger deal that I don't know how to do. For the most part, I already have my template class files pre-filled with these logs, so case-by-case is fine for me. I would only need to carpet-bomb when someone hands me a new project, and when that happens I'm usually rearranging stuff anyway and need to get a look at what is there.
    Professional iOS App Development. Available for hire.
    BriTer Ideas LLC - WWW | Facebook | Twitter | LinkedIn

    BTIKit | BTICoreDataKit | SlickShopper 2 | Leave a PayPal donation
  • musicwind95musicwind95 Posts: 365Registered Users
    edited August 2010
    BrianSlick wrote: »
    The algorithm is in Cocoa, so you could modify it. I thought about going after any curly brace in the selection, but I generally don't add logs to interior ones, so it was overkill for my purposes. It wouldn't take much to change the code to do that, however. But you can double-click any curly brace and this utility will work. It's not limited to methods. The text selection just has to begin with { and end with }.

    Parsing through all files is a bigger deal that I don't know how to do. For the most part, I already have my template class files pre-filled with these logs, so case-by-case is fine for me. I would only need to carpet-bomb when someone hands me a new project, and when that happens I'm usually rearranging stuff anyway and need to get a look at what is there.

    I was actually looking at the code, and I was trying to change the lines that added the NSLogs to add dNSLogs, as per my code. The resulting .action file in the ProjectFolder/build/debug file was 25KB, versus the included 61KB...not sure what's going on there. It doesn't work, either...I'm probably not looking in the right place.
    If I have helped you, <a href="http://bit.ly/mw95donate"; target="_blank">please consider donating</a>. I use PayPal. It would mean a lot to me!<br />
    <br />
    <a href="http://cupsofcocoa.wordpress.com/"; target="_blank">20100829-
  • johnw188johnw188 Posts: 1New Users
    edited September 2010
    In my files, I do a

    #define dNSLog NSLog

    statement in the beginning or header file. Then I just call dNSLog (@NSLog called); It is easier than typing #ifdef every single time, and when it comes time to release, just change the define to // (it'll comment out all the dNSLogs).

    Great utility though. Thanks!

    Better way of achieving this same effect:

    In your app_prefix.pch, add the following line to get rid of all your log statements -

    #define NSLog(x,...)

    app_prefix.pch gets prepended to every single file you write in a project. The line above defines a preprocessor macro that converts all your NSLog function calls to nothing. If you want your logs to print again, comment out the line in app_prefix.pch, giving

    //#define NSLog(x,...)
  • Duncan CDuncan C Posts: 9,112Tutorial Authors, Registered Users @ @ @ @ @ @ @
    edited September 2010
    BrianSlick wrote: »
    Offered with very little support is this:

    TrackingLogsService.zip

    Contents:

    - An Xcode project that builds an Automator action
    - A pre-made instance of said action
    - A sample Automator Workflow using said action

    How to make it:

    I don't actually know that much about Automator, so I don't know if you can just drop in what I've included, or if you will need to make stuff for yourself.

    - Build the app and then reveal the product in the Finder, just like you would for an iPhone app.
    - The .action needs to wind up in ~/Library/Automator
    - The Workflow needs to be in ~/Library/Services

    If drag-n-drop doesn't work, create a new Automator Workflow using the Service template. Name it whatever you want. Use these settings at the top:
    Service receives select <text> in <any application>
    <checkmark on> Replaces selected text

    Then find the action and drag it into your workflow. It will probably be found in your "Recently Added" smart folder. Save.

    This should appear in your Services menu any time you have text selected. If you want to assign a key command, System Preferences -> Keyboard -> Keyboard Shortcuts tab -> Select Services on the left -> Find the name you gave the Automator action, assign whatever key combo you want. I'm currently using Cmd-Shift-1.

    What it does:

    I use lots and lots and lots of NSLogs. For the most part, I have these tracking logs built in to my class templates. However, I routinely encounter methods that don't have them, either newly created ones of my own, classes I don't have custom templates for, client projects, etc. I still want my logs. Up until now, this has been a copy-paste operation for me, and it can get old. Inspired by Accessorizer (highly, highly recommended), I set out to make my own utility.

    So, you have a typical method:
    - (void)someMethod
    {       [COLOR="Red"]// <---- Double-click the {[/COLOR]
        [anObject doSomething];
    }       [COLOR="red"]// <---- Or double-click the }[/COLOR]
    

    Double-clicking either brace will select the entire method except for the name.

    Perform the service, and you wind up with this:
    - (void)someMethod
    {
       NSLog(@>>> Entering %s <<<, __PRETTY_FUNCTION__);
    
       [anObject doSomething];
    
       NSLog(@<<< Leaving %s >>>, __PRETTY_FUNCTION__);
    }
    

    Fun fact: I just used that service here in Safari, too.

    Characteristics I wanted that this service does:

    - If the selected text does NOT begin with a { AND end with a }, then the selected text is not modified.
    - If the method has a return value, the 'leaving' log is placed before the return line. This is based strictly on the presence of "return", it is not doing anything to inspect the method name.
    - If the logs are already there, they will not be duplicated.

    The Future:

    I'm mostly just throwing this out there in case anyone else would find it useful. Although I'm happy to entertain good ideas, I don't really envision changing this very much. The only other thing I might add is a scan for multiple 'return' lines in the selection. The code is made available so you can tailor it to your liking. Feel free to point out bugs.

    Enjoy.

    Brian,

    Thanks for posting that. I'll have to give it a try.

    Where did you find that __PRETTY_FUNCTION__ macro, anyway?
    Regards,
    Duncan C
    WareTo

    widehead.gif
    Animated GIF created with Face Dancer, available for free in the app store.

    I'm available for one-on-one help at CodeMentor
  • BrianSlickBrianSlick Treadmill Desk Ninja Posts: 10,676Tutorial Authors, Registered Users @ @ @ @ @ @ @ @
    edited September 2010
  • musicwind95musicwind95 Posts: 365Registered Users
    edited September 2010
    johnw188 wrote: »
    Better way of achieving this same effect:

    In your app_prefix.pch, add the following line to get rid of all your log statements -

    #define NSLog(x,...)

    app_prefix.pch gets prepended to every single file you write in a project. The line above defines a preprocessor macro that converts all your NSLog function calls to nothing. If you want your logs to print again, comment out the line in app_prefix.pch, giving

    //#define NSLog(x,...)

    Thanks! I'll be sure to try that out.
    If I have helped you, <a href="http://bit.ly/mw95donate"; target="_blank">please consider donating</a>. I use PayPal. It would mean a lot to me!<br />
    <br />
    <a href="http://cupsofcocoa.wordpress.com/"; target="_blank">20100829-
  • musicwind95musicwind95 Posts: 365Registered Users
    edited September 2010
    BrianSlick wrote: »

    The link says that it's a GCC extension...but it seems to be working under LLVM as well.
    If I have helped you, <a href="http://bit.ly/mw95donate"; target="_blank">please consider donating</a>. I use PayPal. It would mean a lot to me!<br />
    <br />
    <a href="http://cupsofcocoa.wordpress.com/"; target="_blank">20100829-
  • BrianSlickBrianSlick Treadmill Desk Ninja Posts: 10,676Tutorial Authors, Registered Users @ @ @ @ @ @ @ @
    edited July 2011
    Updated with some quick Lion info. The service still works.
    Professional iOS App Development. Available for hire.
    BriTer Ideas LLC - WWW | Facebook | Twitter | LinkedIn

    BTIKit | BTICoreDataKit | SlickShopper 2 | Leave a PayPal donation
  • NareilleNareille Posts: 2New Users
    edited July 2011
    This sounds quite appealing, as I also make a log for every method, but i can't call it from within Xcode (4) (I never used automator before, so maybe it's just pebkac..)

    So I put the .action in ~/Library/Automator (tried both, fur the user and the one you access over the harddrive symbol..) and the .workflow inside System/Library/Services (The only services folder i found)

    Relaunching Xcode, I don't know how to run the service after double-clicking on the curled brackets, as ctrl-click doesn't show an automator-entry..

    Am I missing something?

    Thanks!

    //Edit:
    *facepalm* okay, sorry, i was looking for something writing "service", and oversee the "Add Logging..".. Never mind ^^

    Thank you! This will save me hours of copy and paste :)
  • BrianSlickBrianSlick Treadmill Desk Ninja Posts: 10,676Tutorial Authors, Registered Users @ @ @ @ @ @ @ @
    edited July 2011
    Try reading the entire post. Carefully.
    Professional iOS App Development. Available for hire.
    BriTer Ideas LLC - WWW | Facebook | Twitter | LinkedIn

    BTIKit | BTICoreDataKit | SlickShopper 2 | Leave a PayPal donation
  • BrianSlickBrianSlick Treadmill Desk Ninja Posts: 10,676Tutorial Authors, Registered Users @ @ @ @ @ @ @ @
    edited April 2013
    Well, I have been using this action/service for a good long time, and over time I've identified some areas where I'd like improvement. And I've made a couple of changes to how I want the log to look.

    Old:
    NSLog(@">>> Entering %s <<<", __PRETTY_FUNCTION__);

    NSLog(@"<<< Leaving %s >>>", __PRETTY_FUNCTION__);
    New:
    NSLog(@">>> Entering <%p> %s <<<", self, __PRETTY_FUNCTION__);

    NSLog(@"<<< Leaving <%p> %s >>>", self, __PRETTY_FUNCTION__);
    The %p token will print the object ID, so this looks more like Apple's generic descriptions. I've encountered enough situations with multiple objects of a given type, I've found it to be useful to know which object instance is which.

    Additionally, I've started using a NSLog macro for these logs, so that I can turn them off independent of regular logs (see BTIConcepts for implementation details). Looks like this:
    BTITrackingLog(@">>> Entering <%p> %s <<<", self, __PRETTY_FUNCTION__);

    BTITrackingLog(@"<<< Leaving <%p> %s >>>", self, __PRETTY_FUNCTION__);
    Either way, the old service needed to be updated. And since I was messing with it anyway, I decided to address another situation I encounter a lot, which is early/optional return points from a method. For example:
    - (void)aMethod
    {
    BTITrackingLog(@">>> Entering <%p> %s <<<", self, __PRETTY_FUNCTION__);

    if (someCondition)
    {
    BTITrackingLog(@"<<< Leaving <%p> %s >>> EARLY - Triggered the important condition", self, __PRETTY_FUNCTION__);
    return;
    }

    // Now do the real work

    BTITrackingLog(@"<<< Leaving <%p> %s >>>", self, __PRETTY_FUNCTION__);
    }
    With the old service, I only ever reached the final log if the method successfully executed all of the way through. If the logic flow made it leave through any of the early return points, then I never saw the "leaving" log. Easy enough, just look for any return lines and add the log.

    Unfortunately, "return" is not used exclusively to exit a method. It is also used to skip to the next loop in a block-based enumeration. Where you would use "break" in a fast-enumeration loop, you use "return" in a block loop. So need to weed out those cases.

    And hey, if I already have the OLD logs there, maybe it would be nice if they were updated to become NEW logs.

    I decided to split this up into 2 separate actions, 1 for the NSLog version, and 1 for the BTITrackingLog version. I was hoping to use a single project for this, and just change a variable, but Automator was really being cranky about recognizing the two distinct actions. So I got tired of fighting with it and just made another project with copy-pasted code. Sorry. It was only worth so much effort trying to figure out.

    So the new version(s) do all of the following:
    - Upgrade logs of the older format to the newer format.
    - Add "Leaving" logs to all return lines, except within blocks.
    - For any "Leaving" logs other than the final one, there is additional boilerplate text to explain the reason for leaving there (you'll have to provide your own text).
    - The BTITrackingLog version will convert any NSLog tracking logs to BTITrackingLog.
    - The NSLog version will convert any BTITrackingLogs to NSLog.

    In other words, if any tracking logs are already there, they will be upgraded/converted to use the style matching whichever service you run.

    They look pretty good in my tests so far, but I haven't used them in anger very much yet, so there may be bugs. Installation and usage instructions are the same as the first post. Enjoy:

    NSLogTrackingService.zip
    BTITrackingLogsService.zip
    See GitHub instead: BTITrackingLogs
    Post edited by BrianSlick on
    Professional iOS App Development. Available for hire.
    BriTer Ideas LLC - WWW | Facebook | Twitter | LinkedIn

    BTIKit | BTICoreDataKit | SlickShopper 2 | Leave a PayPal donation
  • BrianSlickBrianSlick Treadmill Desk Ninja Posts: 10,676Tutorial Authors, Registered Users @ @ @ @ @ @ @ @
    edited April 2013
    Well, I'm quite embarrassed. I decided to clean these up a bit, put them in one project, post to GitHub. Along the way, I added unit tests. And while testing, I discovered... well, let's just say that what I posted before wasn't fully baked.

    So, I have removed the previous links. Just go to GitHub instead. If you downloaded the newer project that I posted, you'll probably want to grab the GitHub version, as the previous stuff was quite buggy.
    Professional iOS App Development. Available for hire.
    BriTer Ideas LLC - WWW | Facebook | Twitter | LinkedIn

    BTIKit | BTICoreDataKit | SlickShopper 2 | Leave a PayPal donation
Sign In or Register to comment.