MagicalRecord doesn't want to use CocoaLumberjack logging #598

Closed
Zyphrax opened this Issue Oct 15, 2012 · 28 comments

Projects

None yet

9 participants

@Zyphrax
Zyphrax commented Oct 15, 2012

I posted this issue at MagicalRecord (magicalpanda/MagicalRecord#277) but I'm starting to think this is a CocoaPods issue.

When I combine the MagicalRecord pod with the CocoaLumberjack pod, MagicalRecord should start using CocoaLumberjack for logging. However this doesn't seem to work, and MagicalRecord will fall back to using NSLog.

MagicalRecord is detecting CocoaLumberjack in MagicalRecord.h:

#if MR_ENABLE_ACTIVE_RECORD_LOGGING != 0
      // First, check if we can use Cocoalumberjack for logging
    #ifdef LOG_VERBOSE
        extern int ddLogLevel;
        #define MRLog(...)  DDLogVerbose(__VA_ARGS__)
    #else
        #define MRLog(...) NSLog(@"a %s(%p) %@", __PRETTY_FUNCTION__, self, [NSString stringWithFormat:__VA_ARGS__])
    #endif
#else
    #define MRLog(...) ((void)0)
#endif

However the MagicalRecord podspec causes this to be added to Pods-prefix.ch:

#ifdef __OBJC__
#define MR_SHORTHAND
#import "CoreData+MagicalRecord.h"
#endif

The Pods-prefix.ch doesn't have an include for DDLog.h, so LOG_VERBOSE isn't defined and MagicalRecord will default back to NSLog.

My AppName-Prefix.ch looks like this:

// Pod: Lumberjack logging
#import <CocoaLumberjack/DDLog.h>

// Pod: Magical Record
#define MR_ENABLE_ACTIVE_RECORD_LOGGING 1
#define MR_SHORTHAND 1
#import <MagicalRecord/CoreData+MagicalRecord.h>

How do the Pods-prefix.ch and AppName-Prefix.ch influence each other?
How can we get MagicalRecord and CocoaLumberjack to work together?

My workaround for now is to manually add import "DDLog.h" above the MagicalRecord include in Pods-prefix.ch. Of course I prefer not to edit the Pods project :)

@fabiopelosin
Member

@Zyphrax please join the discussion in #539.

@jogu
jogu commented Feb 10, 2013

I've run into this same issue too - #539 seems to be closed now, is just that the MagicalRecord pod now needs to be updated as per the comments on #539?

@Zyphrax
Zyphrax commented Mar 28, 2013

I've created a post_install script for now (for CocoaPods 0.17):

# Modify Pods-prefix.pch, so that MagicalRecord will use CocoaLumberjack
post_install do | installer |
    file = File.open("#{installer.sandbox_root}/Pods-prefix.pch", "r+")
    lines = file.readlines
    file.rewind
    lines.each do | line |
        if line.include? "CoreData+MagicalRecord.h"
            file.puts "#import \"DDLog.h\""
        end
        file.puts line
    end
end

I don't have a lot of experience with Ruby, suggestions for doing this more efficiently are welcome :)
Perhaps it would be better if the MagicalRecord pod could somehow detect the CocoaLumberjack pod.

@Zyphrax
Zyphrax commented Apr 8, 2013

@alloy / @irrationalfab
Do you guys know a better way to solve this?

Basically when you use the MagicalRecord pod and CocoaLumberjack together, CocoaLumberjack (DDLog.h) should be included above MagicalRecord in the PCH.

@fabiopelosin
Member

@Zyphrax a first step in that direction is discussed in issue #833. That would be still a manual approach though. There is also an experimental feature currently shipping in CocoaPods which would allow automatic integration. If you open a installation generated with CocoaPods > 0.17. You'll notice that in the Pods project there is a file called Pods-header.h. The contents of this file should be similar to:

// WARNING: This feature of CocoaPods is present for discussion purposes and might be discontinued or changed in future
#define __COCOA_PODS

#define __POD_MagicalRecord
#define __POD_CocoaLumberjack

As this file is being imported in the prefix header a Pod like magical record could do something like the following in its source:

#ifdef __POD_CocoaLumberjack
  #import "DDLog.h"
#end

And the automatic integration would kick in. However this feature is experimental mostly because I haven't received enough feedback about it and I don't know if this is the best approach.

@Zyphrax
Zyphrax commented Apr 9, 2013

@irrationalfab the Pods-header.h would give a lot of flexibility in putting together your own Pods-Prefix.pch.

In this case it would be unfortunate that everyone who combines MagicalRecord and CocoaLumberjack will have to change their Pods-header.h to make this work. I think it should be the responsibility of the MagicalRecord pod to detect the CocoaLumberjack pod.

Perhaps another way to solve this would be to do the following:

  • Pod PCH directives (prefix_header_contents) are added to Pods-Prefix.pch in the order that pods are defined in the Podfile
  • Next to prefix_header_contents there will be an extra directive "prefix_header_contents2" (we have to figure out a proper name for this). The contents of this directive will be added to the Pods-Prefix.pch after all the Pods are processed

So for example:

  • Pod B - prefix_header_contents: "B", prefix_headers_contents2: "Y"
  • Pod A - prefix_header_contents: "A", prefix_headers_contents2: "X"
  • Pod C - prefix_header_contents: "C"

Would result in:

  • B
  • A
  • C
  • Y
  • X

This way MagicalRecord could set up the logging in prefix_headers_contents2 and properly detect CocoaLumberjack.

@fabiopelosin
Member

In this case it would be unfortunate that everyone who combines MagicalRecord and CocoaLumberjack will have to change their Pods-header.h to make this work. I think it should be the responsibility of the MagicalRecord pod to detect the CocoaLumberjack pod.

To be clear, the Pods header is generated automatically and the above example is intended to be included in the source code of MagicalRecord. Therefore, I'm not following your point that everyone will have to change their Pods-header.h.

Perhaps another way to solve this would be to do the following:
This way MagicalRecord could set up the logging in prefix_headers_contents2 and properly detect CocoaLumberjack.

In my opinion, Pods should not use the prefix header for more than the strictly necessary. I don't see why the contents of the prefix_headers_contents2 can't go in the MagicalRecord source.

Regarding the order aware logic, you are not the first one to propose it. Personally, I don't like the idea. I think that keeping into account the order of declaration of the Pods, is brittle, unexpected to the users, could lead to difficulties in a hierarchy of target definitions and would be complex to maintain. Currently the order of declaration can influence the resolution process but this is a band-aid because our resolver is still naive.

@Zyphrax
Zyphrax commented Apr 9, 2013

@irrationalfab Ah sorry, I completely misunderstood the purpose of Pods-header.h. The Pods-header would work fine if it is always included at the top of the Pods-Prefix.pch and MagicalRecord would indeed change MagicalRecord.h. I do wonder if MagicalRecord and other libraries are willing to add lines like these to their code (which is completely irrelevant for people who don't use CocoaPods).

I think we need some kind of way to define the order of the imports in de Pods-Prefix.pch. The order of the pods in de PodFile might not be the best way, I support your argument on that. Perhaps some kind of template file, where you can say: these are my imports, import CocoaLumberjack here, import MagicalRecord there. Basically what I thought Pods-header.h was for :)

@fabiopelosin
Member

I do wonder if MagicalRecord and other libraries are willing to add lines like these to their code (which is completely irrelevant for people who don't use CocoaPods).

This would be up to the library maintainer, akin to the inclusion of the podspec in t the root of the repo. If they want to provide automatic auto detection they can. Also the nature of the macro makes the code harmless for non CP environments and generally would provide useful functionality which the lib can expose with another macro.

Perhaps some kind of template file, where you can say: these are my imports, import CocoaLumberjack here, import MagicalRecord there. Basically what I thought Pods-header.h was for :)

If I understand you correctly this is #833 is about. CocoaPods would create a header for each target and not overwrite it during install. This file would be imported in the prefix. In this way the user has still a chance to manually affect the build environment. Same for the Xcconfigs.

@fabiopelosin
Member

@casademora, @tonyarnold It would be great if you could share your opinion about this feature. In detail it would be helpful to know:

  • Whether you would implement such a functionality in MagicalRecord.
  • Whether you think that the implementation can be improved (even if you wouldn't implement it).
  • Any alternative implementation which you would suggest for an automatic of optional components like CocoaLumberjack (the less specific to CocoaPods the better).
@fabiopelosin
Member

The gist is described in this comment.

@casademora

Cocoa lumberjack has been supported by magical record for quite some time.
To enable logging, you need to set the enable_active_record_logging to 1.

Sent from my iPad

On Apr 9, 2013, at 7:42 AM, Fabio Pelosin notifications@github.com wrote:

@casademora https://github.com/casademora,
@tonyarnoldhttps://github.com/tonyarnoldIt would be great if you
could share your opinion about this feature. In
detail helpful to know:

  • Whether you would implement such a functionality in MagicalRecord.
  • Whether you think that the implementation can be improved (even if you
    wouldn't implement it).
  • Any alternative implementation which you would suggest for an
    automatic of optional components like CocoaLumberjack (the less specific to
    CocoaPods the better).


Reply to this email directly or view it on
GitHubhttps://github.com/CocoaPods/CocoaPods/issues/598#issuecomment-16113034
.

@alloy
Member
alloy commented Apr 9, 2013

@casademora Yeah, but the point is that with CP the source is not imported into the user’s project, so unless you hack the source, you can’t set that before compilation. This ticket is about changing the way MR detects the default. So instead of:

#if MR_ENABLE_ACTIVE_RECORD_LOGGING != 0
      // First, check if we can use Cocoalumberjack for logging
    #ifdef LOG_VERBOSE
        extern int ddLogLevel;
        #define MRLog(...)  DDLogVerbose(__VA_ARGS__)
    #else
        // [SNIP]
    #endif
#endif

It would be:

#if MR_ENABLE_ACTIVE_RECORD_LOGGING != 0
      // First, check if we can use Cocoalumberjack for logging
    #ifdef LOG_VERBOSE || __POD_CocoaLumberjack
        #import "DDLog.h"
        extern int ddLogLevel;
        #define MRLog(...)  DDLogVerbose(__VA_ARGS__)
    #else
        // [SNIP]
    #endif
#endif
@casademora

That seems like a reasonable thing to add.

Sent from my iPad

On Apr 9, 2013, at 7:52 AM, "Eloy Durán" notifications@github.com wrote:

@casademora https://github.com/casademora Yeah, but the point is that
with CP the source is not imported into the user’s project, so unless you
hack the source, you can’t set that before compilation. This ticket is
about changing the way MR detects the default. So instead of:

#if MR_ENABLE_ACTIVE_RECORD_LOGGING != 0
// First, check if we can use Cocoalumberjack for logging
#ifdef LOG_VERBOSE
extern int ddLogLevel;
#define MRLog(...) DDLogVerbose(VA_ARGS)
#else
// [SNIP]
#endif#endif

It would be:

#if MR_ENABLE_ACTIVE_RECORD_LOGGING != 0
// First, check if we can use Cocoalumberjack for logging
#ifdef LOG_VERBOSE || POD_CocoaLumberjack
#import "DDLog.h"
extern int ddLogLevel;
#define MRLog(...) DDLogVerbose(__VA_ARGS
)
#else
// [SNIP]
#endif#endif


Reply to this email directly or view it on
GitHubhttps://github.com/CocoaPods/CocoaPods/issues/598#issuecomment-16113525
.

@alloy
Member
alloy commented Apr 9, 2013

@casademora Awesome. This was untested code btw, so maybe it’s best if we create a PR for MR that we have verified to work as intended.

@fabiopelosin
Member

@casademora Thanks!
@Zyphrax Given that you already have a good test project could you fork MR and apply @alloy's patch and test that it actually works as expected? The support from the CP side is already there. We just need to graduate the feature.

@alloy
Member
alloy commented Apr 9, 2013

And then there’s the pod version issue, which, after much discussion, we settled on solving like this: https://gist.github.com/alloy/5346435.

Basically, if you follow semver, we will define version macros, otherwise we don’t.

@fabiopelosin fabiopelosin referenced this issue in AFNetworking/AFNetworking Apr 9, 2013
Closed

Add support for COCOAPODS macro #905

@Zyphrax
Zyphrax commented Apr 10, 2013

Great!

@irrationalfab Sure I'll try this out later this week

@casademora or @tonyarnold Could you accept my existing MR pull request (magicalpanda/MagicalRecord#432)? MR currently has a method that performs two fetches instead of one, because its calling the wrong method. After that I can create a fresh fork of MR.

@Zyphrax
Zyphrax commented Apr 24, 2013

Sorry about the delay.
I've tried @alloy 's patch but it had a small syntax issue. I got it working with the following code:

#if MR_ENABLE_ACTIVE_RECORD_LOGGING != 0
      // First, check if we can use Cocoalumberjack for logging
    #if defined(LOG_VERBOSE) || defined(__POD_CocoaLumberjack)
        #import "DDLog.h"
        extern int ddLogLevel;
        #define MRLog(...)  DDLogVerbose(__VA_ARGS__)
    #else
        // [SNIP]
#endif

That works great. I'll submit the change to the development branch of MagicalRecord.
@casademora @irrationalfab fyi

@Zyphrax Zyphrax referenced this issue in magicalpanda/MagicalRecord Apr 24, 2013
Closed

Added CocoaLumberjack detection through CocoaPods macro #463

@blackgold9

I'm working on merging it into MR but i can't get it working locally. Where should __POD_CocoaLumberjack be defined?

@Zyphrax
Zyphrax commented Jun 3, 2013

They've changed the definition format in the latest version of CocoaPods. The updated code is:

#if MR_ENABLE_ACTIVE_RECORD_LOGGING != 0
    // First, check if we can use Cocoalumberjack for logging
    #if defined(LOG_VERBOSE) || defined(COCOAPODS_POD_AVAILABLE_CocoaLumberjack)
        #import "DDLog.h"
        extern int ddLogLevel;
        #define MRLog(...)  DDLogVerbose(__VA_ARGS__)
    #else
        // [SNIP]
#endif

So compared to the original MR code, the following has changed:

  • ifdef LOG_VERBOSE became if defined LOGVERBOSE || COCOAPODS_POD_AVAILABLE etc.
  • DDLog.h is imported above the ddLogLevel line

CocoaPods pod definitions are listed in Pods-environment.h in the Pods project.

@blackgold9

Ok. I'm almost there. I have it compiling, and I use Lumberjack all over this project I'm testing it with (and have various ddLogLevels set), however MRLog still isn't working. Still digging.

@bachand
bachand commented Aug 29, 2013

As of the time of writing, it looks like this is still not fixed in the latest MagicalRecord release (2.2), although the change does appear to be in master.

For an example of what I believe is an improved solution over what is in MagicalRecord master, check out this commit on our MagicalRecord fork, which causes MagicalRecord to integrate with CocoaLumberjack and also adds log levels.

@casademora

I like the commit and the way you've added log levels, etc. But this will only work with cocoa pods. I don't use cocoa pods myself, so there needs to be an alternative way to detect when cocoa lumberjack is added to a project old skool like with git submodules.

On Aug 29, 2013, at 4:36 PM, Michael Bachand notifications@github.com wrote:

As of the time of writing, it looks like this is still not fixed in the latest MagicalRecord release (2.2), although the change does appear to be in master.

For an example of what I believe is an improved solution over what is in MagicalRecord master, check out this commit on our MagicalRecord fork, which causes MagicalRecord to integrate with CocoaLumberjack and also adds log levels.


Reply to this email directly or view it on GitHub.

@casademora

I've recently created a 3.0 version branch of magical record that should have better support for logging in general. If you're up for it, give it a try and let me known how the logging works for you. It should be a bit more automatic depending on if you have a debug build or not. There are now 5 log levels, verbose, info, warn, error and fatal. You can see the levels and the method to enable them in the MagicalRecord+Settings.h file.

@krzyzanowskim

I know it's closed but I found this issue when trying to figure out how to add #define to all my Pods, and this is what I came with: https://gist.github.com/krzak/7690635

Modyfying Pods-environment.h did the trick. I'm not sure if this is the best, but works for me.

post_install do | installer |
  open("#{installer.sandbox_root}/Pods-environment.h","a") do |file|
    file.puts <<EOF
// Disable logs
#ifndef DEBUG
  #define NSLog(...)
#endif
EOF
  end
end
@fabiopelosin
Member

@krzak Interesting technique, note that this could break in the future if we implement #1396.

@raphaelschaad raphaelschaad referenced this issue in Flipboard/FLAnimatedImage May 30, 2014
Closed

Log using CocoaLumberjack, if available #1

@Blackjacx

For the development branch (version 2.3.0 and higher) of Magical Record logging seems to still not work correctly. When imported like this:
pod 'MagicalRecord', :git => 'https://github.com/magicalpanda/MagicalRecord', :branch => 'develop'

I have no logging output on my Xcode console. But I altered the post_install script of the Cocoapod. The following should enable logging:
https://gist.github.com/Blackjacx/e5f3d62d611ce435775e

With that buildsetting included in GCC_PREPROCESSOR_DEFINITIONS logging of Magical Record can be controllen in 2.3.0++ by using [MagicalRecord setLoggingLevel:]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment