2016-03-23 7 views
5

Sto sviluppando un framework c oggettivo che verrà utilizzato da altri colleghi sviluppatori.Come passare argomenti di dipendenze opzionali come parametri nella funzione obiettivo c framework

In questo contesto, vorrei utilizzare, se disponibile, classi disponibili di altri framework, se disponibili.

Per esempio, in questo momento sto usando AdSupport.framework (se è disponibile - legati dallo sviluppatore app) con il seguente approccio:

if (NSClassFromString(@"ASIdentifierManager")) { 
     NSString adString = [[[NSClassFromString(@"ASIdentifierManager") sharedManager] advertisingIdentifier] UUIDString]; 
} 

Comunque ora, voglio avere argomenti di funzioni pubbliche del mio framework per includere classi di dipendenze opzionali e io non sono in grado di farlo.

Ad esempio:

voglio avere una funzione:

+ (void) sendLocation: (CLLocation *) myLoc; 

ma CoreLocation.framework saranno opzionalmente legato e forse non a disposizione di un app. Come posso seguire un approccio simile con AdSupport.framework qui sopra?

ho pensato che potevo fare qualcosa di simile:

+ (void) sendLocation: (NSClassFromString(@"CLLocation") *) myLoc; 

o

+ (void) sendLocation: (id) myLoc; 

o

+ (void) sendLocation: (Class) myLoc; 

e quindi estrarre in qualche modo coordinate, ma non era in grado di raggiungere questo obiettivo. Ultima opzione (Classe) sembra compilare ma non riesco a trovare un modo per estrarre i parametri ..

Qualcuno può aiutare con quello?

risposta

0

esempio corta con MapKit (non sarà collegato al tuo app meno che lo si richiede)

Intestazione:

@class MKMapView; 
@interface MyTestInterface : NSObject 
+ (void)printMapViewDescription:(MKMapView *)mapView; 
@end 

Attuazione File:

#import "MyTestInterface.h" 
#import <MapKit/MapKit.h> 

@implementation 

+ (void)printMapViewDescription:(MKMapView *)mapView { 
    if ((NSClassFromString(@"MKMapView")) { 
     NSLog(@"%@", mapView); 
    } else { 
     NSLog(@"MapKit not available"); 
    } 
} 

@end 

Così si collegano alle intestazioni interno. Questo funzionerà solo se fornisci i binari o usi solo i framework Apple. Se fornisci il codice sorgente e vuoi interagire con framework di terze parti, devi lavorare con performSelector, NSInvocation o objc-runtime su oggetti anonimi (id).

EDIT:

Esempio con NSInvocation

intestazione:

@class MKMapView; 
@interface MyTestInterface : NSObject 
+ (void)printMapViewFrame:(MKMapView *)mapView; 
@end 

Attuazione File:

#import "MyTestInterface.h" 

@implementation 

+ (void) printMapViewFrame:(id)mapView { 
    if ([mapView respondsToSelector:@selector(frame)]) { 
     NSMethodSignature *sig = [mapView methodSignatureForSelector:@selector(frame)]; 
     if (sig) { 
      NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig]; 
      [invocation setTarget: mapView]; 
      [invocation setSelector:@selector(frame)]; 
      [invocation invoke]; 
      CGRect rect; 
      [invocation getReturnValue:&rect]; 
      NSLog(@"%@", NSStringFromCGRect(rect)); 
     } 
    } 
} 

@end