I am getting this warning while submitting app to the Apps store through organizer.
The app references non-public selectors in Payload/.app/: decoder
i know we get this warning if we use any Third Party API in our application. I have used SOCKETIO-ObjC library for chat functionality in application. Also used facebook iOS sdk for fb implementation.So i am not getting exactly what causes this warning.! Please find attached ScreenShot for better understanding
You may get this warning just for using a selector in your own code or third party code that has the same name as some selector that is marked as non-public. Happens to me all the time. Never got rejected for it.
By "same name" i mean just something as simple as you having an object with this selector:
-(id) XYZKMyClass doSomethingFancy:(id) toThis
...and there being a selector like this for an internal Apple functionality
-(id) ApplesClass doSomethingFancy:(id) toSomething
So: What it seems they are looking for is the signature -(id) doSomethingFancy:(id). You can see how it's very easy to accidentally bump up against this.
Presumably they perform a deeper check at the App Store Police HQ, and determine that the flagged selector is in your code, and hence OK.
This can help you:
Before:
#import "SocketIOJSONSerialization.h"
extern NSString * const SocketIOException;
// covers the methods in SBJson and JSONKit
#interface NSObject (SocketIOJSONSerialization)
// used by both JSONKit and SBJson
- (id) objectWithData:(NSData *)data;
// Use by JSONKit serialization
- (NSString *) JSONString;
**- (id) decoder;**
// Used by SBJsonWriter
- (NSString *) stringWithObject:(id)object;
#end
After:
#import "SocketIOJSONSerialization.h"
extern NSString * const SocketIOException;
// covers the methods in SBJson and JSONKit
#interface NSObject (SocketIOJSONSerialization)
// used by both JSONKit and SBJson
- (id) objectWithData:(NSData *)data;
// Use by JSONKit serialization
- (NSString *) JSONString;
**- (id) jsonDecoder;**
// Used by SBJsonWriter
- (NSString *) stringWithObject:(id)object;
#end
I get in this link: http://blog.csdn.net/erica_sadun/article/details/12188083
Check your Target Membership for all classes used in project. In some cases when you create or copy your target the warning may appears without link error.
Related
I have an iOS app that is ported to MacOS. The app uses Firebase for Crashlytics. So far I managed to configure everything just fine, by creating a separate Mac target and separate Firebase project for that target. The problem is that the crashes I see in the console for the MacOS project are all under "AppKit". Example:
AppKit | -[NSApplication _crashOnException:] + 106
Not very informative, is it... Now, I can still get the crashing exception if I inspect the crashes and then go to 'Keys':
crash_info_entry_0 | Crashing on exception: *** -[__NSCFCalendar rangeOfUnit:startDate:interval:forDate:]: date cannot be nil
But with that all the different crashes are grouped together under that AppKit crash and so it is not very helpful.
I realise that this issue is due to the default behaviour of AppKit catching all exceptions on MacOS by default. Is there perhaps a better way to setup Crashlytics for MacOS, in order to get more granular reports, like on iOS and other platforms?
After a lot of research I found that there is no perfect solution to this. I tried overriding NSApplication and setting it as NSPrincipalClass, and even implemented Sentry instead - no success. But I found a way to bypass AppKit using method swizzling and FIRExceptionModel.
Note: Before anything, for Firebase Crashlytics to work on MacOS, you need the following in your AppDelegate's didFinishLaunchingWithOptions:
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults registerDefaults:#{#"NSApplicationCrashOnExceptions" : #"YES"}];
Then you need to create a category of NSApplication and swizzle the method _crashOnException:
#import <objc/runtime.h>
#import "NSApplication+CrashReport.h"
#import <FIRCrashlytics.h>
#implementation NSApplication (CrashReport)
+(void)load {
static dispatch_once_t once_token;
dispatch_once(&once_token, ^{
SEL crashOnExceptionSelector = #selector(_crashOnException:); // Ignore 'Undeclared selector' warning.
SEL crashOnExceptionReporterSelector = #selector(reported__crashOnException:);
Method originalMethod = class_getInstanceMethod(self, crashOnExceptionSelector);
Method extendedMethod = class_getInstanceMethod(self, crashOnExceptionReporterSelector);
method_exchangeImplementations(originalMethod, extendedMethod);
});
}
- (void)reported__crashOnException:(NSException*)exception {
NSArray<NSString*> *stacktrace = [exception callStackSymbols];
[[FIRCrashlytics crashlytics]setCustomValue:stacktrace forKey:#"mac_os_stacktrace"];
FIRExceptionModel *errorModel = [FIRExceptionModel exceptionModelWithName:exception.name reason:exception.reason];
// The below stacktrace is hardcoded as an example, in an actual solution you should parse the stacktrace array entries.
errorModel.stackTrace = #[
[FIRStackFrame stackFrameWithSymbol:#"This stacktrace is fabricated as a proof of concept" file:#"Hello from Serge" line:2021],
[FIRStackFrame stackFrameWithSymbol:#"__exceptionPreprocess" file:#"CoreFoundation" line:250],
[FIRStackFrame stackFrameWithSymbol:#"objc_exception_throw" file:#"libobjc.A.dylib" line:48],
[FIRStackFrame stackFrameWithSymbol:#"-[__NSCFCalendar rangeOfUnit:startDate:interval:forDate:]" file:#"CoreFoundation" line:453]
];
// Note: ExceptionModel will always be reported as a non-fatal.
[[FIRCrashlytics crashlytics] recordExceptionModel:errorModel];
[self reported__crashOnException:exception];
}
#end
This code as a gist: https://gist.github.com/sc941737/c0c4542401ce203142c93ddc9b05eb1f
This means however that the exceptions won't be reported as crashes, but as non-fatals. So I would recommend setting an extra custom key to filter crashes from non-fatals more easily. See Firebase docs for details: https://firebase.google.com/docs/crashlytics/customize-crash-reports?platform=ios
NOTE: Swizzling private methods of Apple's APIs is a no-no for apps targeting the app store. It wasn't an issue in my case, because it was an app used internally.
I just started porting an Android app to iOS, and am hitting a major roadblock that I can't figure out despite scouring many similar questions.
I am attempting to follow the pattern implemented in the CastVideos sample where the GoogleCast API is encapsulated in a singleton class which I've called CastManager. To use my singleton class, I #import "CastManager.h" in AppDelegate.m. Then in CastManager.h, I #import <GoogleCast/GoogleCast.h> so that I can use classes and protocols from it as part of CastManager's public interface. However, because I'm importing CastManager.h in both CastManager.m and AppDelegate.m, the linker is finding duplicate symbols from the GoogleCast framework.
This is my CastManager.h:
#import <GoogleCast/GoogleCast.h>
#import <Foundation/Foundation.h>
#interface CastManager : NSObject
#property(nonatomic, strong) GCKDeviceScanner *deviceScanner;
+ (instancetype)sharedCastManager;
#end
And corresponding CastManager.m:
#import "CastManager.h"
#implementation CastManager
+ (instancetype)sharedCastManager {
NSLog(#"sharedCastManager");
static CastManager *singleton = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
singleton = [[self alloc] init];
});
return singleton;
}
- (instancetype)init {
NSLog(#"init()");
if (self = [super init]) {
self.deviceScanner = [[GCKDeviceScanner alloc] init];
}
return self;
}
#end
And this is the main part of my AppDelegate.m:
#import "AppDelegate.h"
#import "CastManager.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
CastManager *castManager = [CastManager sharedCastManager];
return YES;
}
However, this results in the following error from the linker when attempting to build the project:
duplicate symbol _kGCKDeviceCapabilityVideoOut in:
/Users/nate/Library/Developer/Xcode/DerivedData/MyCastApp-ezrgxdnlvywpanerezulnarzknno/Build/Intermediates/MyCastApp.build/Debug-iphonesimulator/MyCastApp.build/Objects-normal/x86_64/AppDelegate.o
/Users/nate/Library/Developer/Xcode/DerivedData/MyCastApp-ezrgxdnlvywpanerezulnarzknno/Build/Intermediates/MyCastApp.build/Debug-iphonesimulator/MyCastApp.build/Objects-normal/x86_64/CastManager.o
... many similar errors ommitted for brevity ...
duplicate symbol _kGCKDeviceCapabilityAudioIn in:
/Users/nate/Library/Developer/Xcode/DerivedData/MyCastApp-ezrgxdnlvywpanerezulnarzknno/Build/Intermediates/MyCastApp.build/Debug-iphonesimulator/MyCastApp.build/Objects-normal/x86_64/AppDelegate.o
/Users/nate/Projects/MyCastApp/GoogleCast.framework/GoogleCast(GCKDevice.o)
ld: 8 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
As far as I can tell, this exactly copies the pattern as defined in the CastVideos sample, but the sample compiles fine, and mine doesn't, and I've scoured through both projects trying to find what is different, but I just don't see it. Further, I don't see anything really wrong with doing this, and would expect it to work fine. I can't think of any other way to do it, really.
Here are the relevant files from the CastVideos sample for comparison:
ChromecastDeviceController.h
ChromecastDeviceController.m
AppDelegate.m
Other questions point to solutions that don't apply or don't fix it:
I'm not importing a .m file on accident.
I don't have duplicate references to any files in the project.
The "Compile Sources" section of the "Build Phases" project setting doesn't include any duplicates.
I've added the '-ObjC' linker flag as described by the GoogleCast API docs, though it has the same error with or without it.
I've tried deleting the delegate data and doing a clean before building.
This is with Xcode 6.3.1 running on OS X Yosemite 10.10.3 and the GoogleCastSDK-2.6.0 package from the SDK documentation page
I have checked in my sample project with the problem at https://github.com/nshafer/MyCastApp
Any help is greatly appreciated!
Edit: the duplicate is somewhat related, it's definitely about the same symbols, but the answers there didn't help, as I'm not using Object-C++, but rather just Objective-C. I don't have a .mm file, just a .m file.
For me it helped to switch the "No Common Blocks" compiler setting to NO:
It pretty much seems to make sense, the setting is explained here: What is GCC_NO_COMMON_BLOCKS used for?
The linker tells you that you have a variable named kGCKDeviceCapabilityVideoOut in two files, AppDelegate.m and CastManager.m. Since it's not in your source code, it's most likely in the GoogleCast code that you are including.
Either change the GoogleCast.h file, or make sure it is only included in one .m file. Including it from CastManager.h means it is indirectly included in every file that includes CastManager.h, so I would avoid that and only include it from CastManager.m. You'll probably have to add
#class GCKDeviceScanner;
in your CastManager.h file.
I found another fix, which is to edit GCKDevice.h in the GoogleCast.framework/Headers folder. Change the 4 constants from GCK_EXPORT to GCK_EXTERN near the top of the file.
/** Device capability flag for video out. */
GCK_EXTERN const NSInteger kGCKDeviceCapabilityVideoOut;
/** Device capability flag for video in. */
GCK_EXTERN const NSInteger kGCKDeviceCapabilityVideoIn;
/** Device capability flag for audio out. */
GCK_EXTERN const NSInteger kGCKDeviceCapabilityAudioOut;
/** Device capability flag for audio in. */
GCK_EXTERN const NSInteger kGCKDeviceCapabilityAudioIn;
I detailed this in a bug report I filed with Google's issue tracker, but it was marked as a duplicate of another somewhat related issue. Either way, it will perhaps get fixed in the next version. Until then, I would suggest going with changing the "No Common Blocks" setting as detailed in Joobik'com's answer, as that doesn't involve changing the 3rd party code.
I'm building a static library in iOS. after importing that library in my project, I added -ObjC in Other linker flags. But when I call the class methods(currently 3 available), 2 of them are being called and executed properly, but the last one is getting this error: "+[RankConferenceLib joinConferenceWithName:]: unrecognized selector sent to class 0x5044dc".
This is my Header file of library
#interface RankConferenceLib : NSObject
+(void)initEnvironment;
+(void)orientationChange;
+(void)joinConferenceWithName:(NSString *)name;
#end
in .m file of library
+ (void)joinConferenceWithName:(NSString *)name
{
//....codes
}
and in my project I'm calling them
- (IBAction)join:(UIButton *)sender {
[RankConferenceLib joinConferenceWithName:#"User"];
}
Please tell me what I'm missing here. This is my first static library. I've searched but could not find any help which is similar as my situation here. Please mention what else you need to know.
Thank you.
I have checked this and for me it's working fine without any linker flags added.
The only one error possibility is something happened inside the + (void)joinConferenceWithName:(NSString *)name
Write a log inside the joinConferenceWithName to printout the parameter name and make sure this is calling and the problem is occurring inside that method.
+ (void)joinConferenceWithName:(NSString *)name
{
NSLog(#"the name is: %#", name);
}
Finally, make sure that you added the latest modified static library into your project.
You can download the working sample from here
Try Running using the -all_load linker flag
Apple Documentation
Stack Overflow Answer
I'm working on a custom Jailbreak solution on iOS. I'm trying to be able to add new triggers in Activator. Specifically I'm trying to define a tap-release-tap-and-hold behavior for the home button although this could theoretically work for any device input.
Now I'm well-versed in MobileSubstrate which lets you do method swizzling against existing classes at run-time (see here for more info: http://iphonedevwiki.net/index.php/MobileSubstrate) as well as providing other features and benefits. However, I'm not sure how to get that plugged into Activator since I don't have access to the code, and while I could use ClassDump to export the headers for Activator and sift through them, Activator is an extremely complex application which is why rather than spending a week looking through it all, I'm hoping someone else knows the rough 'injection point' (for lack of a better term) that could get me heading in the right direction.
Note, while I could simply listen for my action at the system level, doing so would short-circuit Activator which defeats the purpose of what I'm trying to accomplish, which is to add a new action that can be used with activator: an Activator extension if you will.
So does anyone have any information on, or a good jumping-off point for achieving this? I'm hoping for a little direction so I don't have to tear through the entire header class-dump of the code.
It seems that you'd like to make something like LAEvent.
Here are some information may help you start:
Implement LAEventDataSource protocol
#protocol LAEventDataSource <NSObject>
#required
- (NSString *)localizedTitleForEventName:(NSString *)eventName;
- (NSString *)localizedGroupForEventName:(NSString *)eventName;
- (NSString *)localizedDescriptionForEventName:(NSString *)eventName;
#optional
- (BOOL)eventWithNameIsHidden:(NSString *)eventName;
- (BOOL)eventWithName:(NSString *)eventName isCompatibleWithMode:(NSString *)eventMode;
#end
Register event data source
#interface LAActivator : NSObject
- (void)registerEventDataSource:(id<LAEventDataSource>)dataSource forEventName:(NSString *)eventName;
#end
Now your event is available in availableEventNames property of LAActivator
#property (nonatomic, readonly) NSArray *availableEventNames;
Send event
#interface LAEvent : NSObject<NSCoding>
+ (id)eventWithName:(NSString *)name;
+ (id)eventWithName:(NSString *)name mode:(NSString *)mode;
- (id)initWithName:(NSString *)name;
- (id)initWithName:(NSString *)name mode:(NSString *)mode;
#end
#interface LAActivator : NSObject
- (void)sendEventToListener:(LAEvent *)event;
#end
I have an issue where I'm getting bad access exceptions but only when running a testing build (calling the same methods in a debug build doesn't cause the problem to come up). The project has ARC enabled and I'm running this on the iPad 5.1 simulator using Xcode 4.3:
Here's where the problem crops up:
- (void)testChangeFoodNotification {
Player* p = [[Player alloc] init];
[p addObserver:self forKeyPath:#"food" options:0 context:0]; // <-EXC_BAD_ACCESS (code=2)
p.food += 1;
STAssertTrue(_wasNotifiedOfFoodChange, nil);
}
At the point when the addObserver: method is called it doesn't seem like any of the objects involved should have been released so what could be causing the exception?
EDIT:
Apologies if it wasn't clear but the code above is being executed as part of a test case (using the standard Xcode OCUnit). Also in case it clarifies anything here's the relevant code from the player class (there's other ivars and methods but they don't have any connection to the property or methods being tested):
// Public interface
#interface Player : NSObject
#property (nonatomic, assign) NSInteger food;
#end
// Private interface
#interface Player() {
NSInteger _food;
}
#end
#implementation Player
#synthesize food = _food;
#pragma mark - Getters/Setters
- (void)setFood:(NSInteger)food {
[self willChangeValueForKey:#"food"];
_food = food;
[self didChangeValueForKey:#"food"];
}
If your class is indeed key-value compliant, ensure that the implementation for the class exhibiting the issue is not included in your test product. This means that the Target Membership panel of the Identity inspector for your .m file should only have your app checked (not YourAppTests).
I experienced the same issue in Xcode 4.3.1 when an implementation was included in both products and I registered observers in both production and test code. The following logs tipped me off:
Class YourClass is implemented in both /Users/yourUser/Library/Application Support/iPhone Simulator/5.1/Applications//YourApp.app/YourApp and /Users/yourUser/Library/Developer/Xcode/DerivedData/YourApp-/Build/Products/Debug-iphonesimulator/YourAppTests.octest/YourAppTests. One of the two will be used. Which one is undefined.
As per the Key-Value Observing Programming Guide, is your Player key-value-compliant? You want to make sure you are Ensuring KVC Compliance. I also assume that you have also implemented your observeValueForKeyPath:ofObject:change:context:? If you think you've done all of this and it's still not working, then perhaps you can share your code.
Also, minor thing, but I assume this is a code snippet to highlight the issue. I only mention it because ARC is going to be releasing your p object at the end of your testChangeFoodNotification and I would have thought that you'd want to remove your observer first.