CocoaLumberjack - change log file name by subclassing the LogFileManager - objective-c

I am trying to change the logfile name. What i've found so far is this.
My subclass of DDLogFileManagerDefault looks like this:
LogFileManager.h
#import CocoaLumberjack;
// this import would work as well
// #import <CocoaLumberjack/CocoaLumberjack.h>
// but none of these
//#import "DDLog.h"
//#import "DDTTYLogger.h"
//#import "DDASLLogger.h"
//#import "DDFileLogger.h"
#interface LogFileManager : DDLogFileManagerDefault
#end
LogFileManager.m
#import "LogFileManager.h"
#implementation LogFileManager
- (NSString *)newLogFileName {
NSBundle *bundle = [NSBundle mainBundle];
NSDictionary *info = [bundle infoDictionary];
NSString *appName = [info objectForKey:#"CFBundleExecutable"];
NSString *timeStamp = [self getTimestamp];
return [NSString stringWithFormat:#"%#%#.log", appName, timeStamp];
}
- (BOOL)isLogFile:(NSString *)fileName {
return NO;
}
- (NSString *)getTimestamp {
static dispatch_once_t onceToken;
static NSDateFormatter *dateFormatter;
dispatch_once(&onceToken, ^{
dateFormatter = [NSDateFormatter new];
[dateFormatter setDateFormat:#"YYYY.MM.dd-HH.mm.ss"];
});
return [dateFormatter stringFromDate:NSDate.date];
}
#end
This is how I use it:
DDLogFileManagerDefault *documentsFileManager = [[LogFileManager alloc] init];
DDFileLogger *fileLogger = [[DDFileLogger alloc] initWithLogFileManager:documentsFileManager];
When I replace LogFileManager with DDLogFileManagerDefault it works fine. Otherwise I get:
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_LogFileManager", referenced from:
objc-class-ref in Logger.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code
1 (use -v to see invocation)
What exactly am I missing here?
CocoaLumberjack is added via Carthage 3.2.0 for Xcode 8.
I've added the CocoaLumberjack.framework to the Build Phases like all the other frameworks in the project with /usr/local/bin/carthage copy-frameworks

Okay, I solved it. That error was very confusing but has nothing to do with anything. Sorry for that.
It is a big project with lots of build targets and lots of compile flags that make different things throw a warning and warnings become an error. In this case I added flags to disable the global ones to the mentioned Logger.m class. But I only added those anti-flags to one target and forgot to add them to another. That's why it didn't build.
Still strange, that the compiler didn't simply say: cannot build target A or compile error in file B. Instead I got a missing architecture message that was misleading me totally... So sorry for the trouble. Fixed it.

Related

error: cannot find interface declaration for ‘NSAttributedString’ with GNUStep

I have been messing around with GNUStep, and I have a simple main.m, which compiles fine. I wanted to see if objective-c libraries (meant for ios/mac) work with GNUStep, so i downloaded JSONKit and tried to compile that, but I keep getting this error:
mark#Emperor:~/objc-test2$ make
This is gnustep-make 2.6.2. Type 'make print-gnustep-make-help' for help.
Making all for tool Test...
Compiling file JSONKit.m ...
In file included from JSONKit.m:110:0:
JSONKit.h:63:21: warning: "/*" within comment [-Wcomment]
In file included from /usr/include/GNUstep/Foundation/NSAttributedString.h:143:0,
from /usr/include/GNUstep/Foundation/Foundation.h:42,
from JSONKit.h:72,
from JSONKit.m:110:
/usr/include/GNUstep/GNUstepBase/NSAttributedString+GNUstepBase.h:44:1: error: cannot find interface declaration for ‘NSAttributedString’
make[3]: *** [obj/Test.obj/JSONKit.m.o] Error 1
make[2]: *** [internal-tool-all_] Error 2
make[1]: *** [Test.all.tool.variables] Error 2
make: *** [internal-all] Error 2
mark#Emperor:~/objc-test2$
my main.m is this:
mark#Emperor:~/objc-test2$ cat main.m
#import <stdio.h>
#include <Foundation/Foundation.h>
#import "Fraction.h"
#import "JSONKit.h"
int main( int argc, const char *argv[] ) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// create a new instance
Fraction *frac = [[Fraction alloc] init];
// set the values
[frac setNumerator: 1];
[frac setDenominator: 3];
// print it
NSLog(# "The fraction is: %#", [frac print]);
// free memory
[frac release];
NSMutableArray *testArr = [[NSMutableArray alloc] initWithCapacity:0];
[testArr addObject:[NSNumber numberWithInt:2]];
[testArr addObject:#"Hey"];
NSLog([testArr JSONString]);
[pool drain];
return 0;
}
mark#Emperor:~/objc-test2$
I've googled around and I have made sure that i have the GNUStep env variables set, and i'm using a make file (taken from examples online)
mark#Emperor:~/objc-test2$ cat GNUmakefile
include $(GNUSTEP_MAKEFILES)/common.make
TOOL_NAME = Test
Test_OBJC_FILES = main.m Fraction.m JSONKit.m
Test_CPPFLAGS = $(RUNTIME_DEFINE)
# Include in the rules for making Objective-C programs
include $(GNUSTEP_MAKEFILES)/tool.make
mark#Emperor:~/objc-test2$
I really don't get this as /Foundation/NSAttributedString.h clearly contains the interface declaration for NSAttributedString, and NSAttributedString+GNUStepBase.h imports , so any idea on what is going wrong?

Objective c - DRDevice.h

I'm trying to check my "tray" to see if it open or not, but i can't get it to work, it says:
"_DRDeviceIsTrayOpenKey", referenced from:
´ -[UntitledAppDelegate applicationDidFinishLaunching:] in UntitledAppDelegate.o
ld: symbol(s) not found
the code is:
#import <Foundation/Foundation.h>
#import <DiscRecording/DRCoreDevice.h>
#import <DiscRecording/DRMSF.h>
#import <AvailabilityMacros.h>
extern NSString* const DRDeviceIsTrayOpenKey;
if (!DRDeviceIsTrayOpenKey == NO ) {
[NSApp terminate:nil];
}
info:
DRDeviceIsTrayOpenKey
extern NSString* const DRDeviceIsTrayOpenKey;
Discussion
One of the keys in the dictionary returned by the status method. NSNumber containing a boolean value indicating whether the device's tray is open or not.
Availability
Introduced in Mac OS X v10.2
please help me fix that, i think my code is wrong.
Yes, your code is wrong. That DRDeviceIsTrayOpenKey is a key used to retrieve a value from a NSDictionary.
So if you can get your Disk Recording status, you'd do something like this:
// this code would depend on you passing in a valid DRDevice object
// which I've named myDiscRecordingDevice. A computer can have multiple
// DVD / CD readers attached, so you need to specify which one you care about
NSDictionary * status = [myDiscRecordingDevice status];
NSString* state = [status objectForKey: DRDeviceMediaStateKey];
if ([state isEqualTo: DRDeviceMediaStateNone])
{
if ([[status objectForKey: DRDeviceIsTrayOpenKey] boolValue])
return trayOpen;
return noDisc;
}

Categories in Objective-C aren't working

I'm developing an iOS application that needs to deploy to iOS 3.1.3. I need to extend some of the functionality of the NSData class and am using the following code inside NSData+Base64 (truncated to show the interesting part):
NSData+Base64.h
[...]
#interface NSData (Base64)
+ (NSData *)dataFromBase64String:(NSString *)aString;
- (NSString *)base64EncodedString;
#end
NSData+Base64.m
#implementation NSData (Base64)
[...]
//
// base64EncodedString
//
// Creates an NSString object that contains the base 64 encoding of the
// receiver's data. Lines are broken at 64 characters long.
//
// returns an autoreleased NSString being the base 64 representation of the
// receiver.
//
- (NSString *)base64EncodedString
{
size_t outputLength;
char *outputBuffer =
NewBase64Encode([self bytes], [self length], true, &outputLength);
NSString *result =
[[[NSString alloc]
initWithBytes:outputBuffer
length:outputLength
encoding:NSASCIIStringEncoding]
autorelease];
free(outputBuffer);
return result;
}
#end
However, when I try to message this selector:
NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
NSString *hash = [HMAC base64EncodedString];
I get the following error:
-[NSConcreteData base64EncodedString]: unrecognized selector sent to instance 0x6146e70
2010-11-09 13:44:41.443 SpringboardApplication[21318:40b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSConcreteData base64EncodedString]: unrecognized selector sent to instance 0x6146e70'
I read a lot about iOS 3.1.x having problems with categories. I tried adding the flags -all_load and -ObjC (both separately and together) to no avail. I would really appreciate some direction of how to get this selector to work.
Thanks!
It really seems like your category isn't being compiled or linked into the same target that you're using it from. You should make sure that NSData+Base64.m is marked to be compiled by the same target that it's being used from by getting info on the two files and comparing the targets they're assigned to.
A test you can perform is to add a line with an #error error message to NSData+Base64.m, which will cause the build to fail when it gets to that file. Like this:
#error We're now compiling NSData+Base64.m
Then look and see which target fails to compile.
I had the same issue with ARC project which was linking with non-ARC module having category extension.
Fixed the issue by adding "Other Linker Flags: -all_load" in parent ARC project.
Have you #imported the header file for your category? I know it sounds simple, but I forget nearly every time.
There is a great post on The Carbon Emitter about about handling categories in iOS. It details an easy way to handle importing categories to your project.
Make a file containing all of your category imports, in this example it is Extensions.h:
#import "NSDate+Formatting.h"
#import "UIFonts+MyFonts.h"
#import "UIViewController+Tourbot.h"
Add import your file in AppName-Prefix.pch:
#import <Availability.h>
#ifndef __IPHONE_3_0
#warning "This project uses features only available in iPhone SDK 3.0 and later."
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
#import <CoreText/CoreText.h>
#import "Extensions.h" // Add import here
#endif
In My case when I got this error I simply added the .m file in the Compiled resources, and it get worked. This can be achieved by selecting target project->Build Phases->Compile Sources. Then you click on the + button from its bottom left. In this case you may add 'NSData+Base64.m' file to the compile sources. Then you clean your project and run. I guess this may help.

Link error while accessing NSSpeechSynthesizer

I'm trying to compile a trivial command-line tool with XCode:
#import <Cocoa/Cocoa.h>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
//NSSpeechSynthesizer *speeker = [[NSSpeechSynthesizer alloc] initWithVoice: nil];
NSLog(#"%#", [NSSpeechSynthesizer availableVoices]);
NSLog(#"Hello, World!");
[pool drain];
return 0;
}
and even thought I'm importing Cocoa.h, I'm getting a link error:
Undefined symbols:
"_OBJC_CLASS_$_NSSpeechSynthesizer",
referenced from:
objc-class-ref-to-NSSpeechSynthesizer
in byc.o ld: symbol(s) not found
collect2: ld returned 1 exit status
Anybody knows what's going on???
You imported the header, so compilation worked, but linking failed because you didn't link against a framework that provides NSSpeechSynthesizer. You need to link against either the Application Kit framework (in addition to Foundation) or the Cocoa umbrella framework (instead of Foundation).
Whichever framework you choose, add it to your Linked Frameworks group in your project's group tree (by right-clicking on the group and choosing “Add Existing Framework”), and make sure you also add it to your target.

Symbol not found: _OBJC_CLASS_$_Article

I am working on an extension to Vienna to add the ability for third parties to write Objective-C plugins, but I am getting some runtime linker issues only when running in 64-bit mode (everything appears to work fine in 32-bit mode). My plugin, SynkPlugin, is loaded by the following code in Vienna.app:
NSArray * bundlePaths = [NSBundle pathsForResourcesOfType:#"bundle" inDirectory:[[Preferences standardPreferences] pluginsFolder]];
NSEnumerator * enumerator = [bundlePaths objectEnumerator];
NSString * bundlePath;
NSMutableArray * plugins = [NSMutableArray array];
while ( (bundlePath = [enumerator nextObject]) != nil )
{
NSBundle * pluginBundle = [NSBundle bundleWithPath:bundlePath];
Class principalClass = [pluginBundle principalClass];
id <ViennaPlugin, NSObject> plugin = [[principalClass alloc] init];
[plugins addObject:plugin];
[plugin release];
NSLog(#"Loaded plugin %# [main class: %#]", bundlePath, principalClass);
}
And in the console output, I get the following error message:
2010-07-09 08:55:40.128 Vienna[74065:a0f] Error loading /Users/dcrosta/Library/Application Support/Vienna/PlugIns/SynkPlugin.bundle/Contents/MacOS/SynkPlugin: dlopen(/Users/dcrosta/Library/Application Support/Vienna/PlugIns/SynkPlugin.bundle/Contents/MacOS/SynkPlugin, 265): Symbol not found: _OBJC_CLASS_$_Article
Referenced from: /Users/dcrosta/Library/Application Support/Vienna/PlugIns/SynkPlugin.bundle/Contents/MacOS/SynkPlugin
Expected in: flat namespace
in /Users/dcrosta/Library/Application Support/Vienna/PlugIns/SynkPlugin.bundle/Contents/MacOS/SynkPlugin
This error only happens when running in 64-bit mode, not 32-bit mode. Both Vienna and SynkPlugin are compiled with the "standard 32/64 universal" settings, and SynkPlugin has the additional linker flag "-undefined dynamic_lookup", which, it is my understanding, allows it to link to classes found in Vienna.app without having to compile code for those classes into its own binary.
The other references to this error on Stack Overflow have to do with UIKit differences between iPhone/iPod Touch and iPad -- in those cases, the frameworks are actually missing the classes on iPhone/iPod Touch. In my case, I'm certain that Vienna.app has the Article class within it somewhere, since it is built from identical code to the 32-bit version.
Has anyone seen an error like this before? Have any suggestions on where to look for more information? Thanks.
In the build settings of the Vienna target, under GCC 4.2 - Code Generation uncheck Symbols Hidden by Default (GCC_SYMBOLS_PRIVATE_EXTERN).