![]() |
AW: Hat Jemand schonmal mit TestFairy herumgespielt ?
Urghs, ist das für die Mobile-Interfaces bzw bindungen zu PlatformSDKs anders o.O
|
AW: Hat Jemand schonmal mit TestFairy herumgespielt ?
@MKinzler
Ja das hatte ich schon gesehen, scheint aber dasgleiche zu machen als das von Hand. Schien mir komlizierter als es direkt zu versuchen. Bin auch wieder ein stückchen weiter: Ich hatte den Namen des Interfaces umbenannt, das macht sinn das es 1:1 gleich ist wie in der Library. Jetzt bekomme ich jedenfalls einen ordentlichen Linioer error 00000001, aber warum weiis ich nicht. So siehts in der Library aus, mit dem Header:
Code:
Das ist das Interface dazu, jetzt mit gleichen Namen.
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h> @interface TestFairy: NSObject /** * Initialize a TestFairy session. * * @param appToken Your key as given to you in your TestFairy account */ + (void)begin:(NSString *)appToken; Habe auch versucht die GUUID wegzulassen, so wie in Daniels Beispiel, ist aber immer noch mit Error.
Delphi-Quellcode:
type
{ S4TfLibrary / TS4TfLibrary } // non-static (instance) methods of "TfLibrary" TestFairy = interface(NSObject) // ['{5875CABD-AEBA-4A91-A03F-C3DA9BFE24AD}'] // Interface relates to name and signature in Library procedure &begin( appToken : NSString ); cdecl; end; // static (class) methods of "MyLibrary" TestFairyClass = interface(NSObjectClass) end; TTestFairy = class(TOCGenericImport<TestFairyClass, TestFairy>) end; Gelinkt wird ann mit dieser Zeile, sollte ebenfalls Daniels Beispiel entsprechen:
Delphi-Quellcode:
{$IF DEFINED(CPUARM)}
function FAKE_LOADER : TTestFairy; cdecl; external LIB_TF_LIBRARY name 'OBJC_CLASS_$_TestFairy'; {$ENDIF} initialization {$IF DEFINED(CPUARM)} /// although this code is NEVER executed, it ensures a strong reference /// to the library - the linker is gonna LOVE (and consume) it! if FALSE then FAKE_LOADER; {$ENDIF} Die Library liegt im gleichen Verzeichnis wie die Sourcen, so definiert:
Delphi-Quellcode:
const
LIB_TF_LIBRARY = 'libTestFairy.a'; Was kann denn jetzt noch schieflaufen ? Ich versuche mal ein bischen die Verzeichnisse aus. Rollo |
AW: Hat Jemand schonmal mit TestFairy herumgespielt ?
Das Problem scheint Folgendes:
ENTWEDER ich benenne das Interface NICHT wie in der libTestFairy.a Library:
Delphi-Quellcode:
type { S4TfLibrary / TS4TfLibrary } ITestFairy = interface(NSObject) // Interface relates to name and signature in Library procedure &begin( appToken : NSString ); cdecl; end; {$IF DEFINED(CPUARM)} function FAKE_LOADER : TTestFairy; cdecl; external LIB_TF_LIBRARY name 'OBJC_CLASS_$_ITestFairy'; {$ENDIF} Dann kann ich Kompilieren und Linken, aber beim Aufruf finder er "TestFairy" aus der Library natürlich nicht. ODER ich benenne das Interface GENAU wie in der libTestFairy.a Library:
Delphi-Quellcode:
type { S4TfLibrary / TS4TfLibrary } TestFairy = interface(NSObject) // Interface relates to name and signature in Library procedure &begin( appToken : NSString ); cdecl; end; {$IF DEFINED(CPUARM)} function FAKE_LOADER : TTestFairy; cdecl; external LIB_TF_LIBRARY name 'OBJC_CLASS_$_TestFairy'; {$ENDIF} Dann bekomme ich einen Linker error ... Gibt es nochen einen Dritten Weg ? UPDATE: Lasse ich die Methode weg, dann kompiliert es: Juhuuuu Aber wie komme ich das dann wieder in mein Interface rein ? Die Signatur stimmt, nur heisst die Funktion im Orginal dummerweise "begin", könnte das Problem daher kommen ?
Code:
@interface TestFairy: NSObject
/** * Initialize a TestFairy session. * * @param appToken Your key as given to you in your TestFairy account */ + (void)begin:(NSString *)appToken;
Delphi-Quellcode:
// Interface relates to name and signature in Library
procedure &begin( appToken : NSString ); cdecl; Rollo |
AW: Hat Jemand schonmal mit TestFairy herumgespielt ?
@Memnarch
Die japanische Anleitung funktioniert, aber nur für das Übersetzen der SDK Frameworks. Mag sein das es irgendwie mit eigenen *.a libraries funktioniert, muss ich noch testen. Jedenfalls ist das schonmal OK wenn man neue SDK's einbinden will, und dazu die Pascal Units braucht. Der Compiler wirft aber auch ein paar Fehlermeldungen raus, da habe ich jetzt keine Zeit das alles zu checken. Ist wohl ein neuer Thread ... EDIT: Eine ganz blöde Idee war das libTestFairy dem SdkTransform einfach als neue Library unterzujubeln. Also einfach ein neues Unterverzeichnis unter dem SDK anlegen, und nochmal transformieren lassen. Dummerweise liegen die SDK's in irgendeinem Format (ohne .a) vor, also habe ich einmal beides ausprobiert. Es kam wirklich eine Unit dabei raus, die sieht so aus:
Delphi-Quellcode:
Aber da fehlt trotzdem jede Zuordnung zu den Interfaces.
{***********************************************************}
{ } { CodeGear Delphi Runtime Library } { } { Copyright(c) 2012-2014 Embarcadero Technologies, Inc. } { } {***********************************************************} // // Delphi-Objective-C Bridge // Interfaces for Cocoa framework libTestFairy // unit iOSapi.libTestFairy; interface uses Macapi.CoreFoundation, Macapi.CoreServices, Macapi.Dispatch, Macapi.Foundation, Macapi.Mach, Macapi.ObjCRuntime, Macapi.ObjectiveC, Macapi.QuartzCore, iOSapi.CocoaTypes, iOSapi.Foundation; // ===== External functions ===== const liblibTestFairy = '/System/Library/Frameworks/libTestFairy.framework/libTestFairy'; implementation {$IF defined(IOS) and NOT defined(CPUARM)} uses Posix.Dlfcn; var libTestFairyModule: THandle; {$ENDIF IOS} {$IF defined(IOS) and NOT defined(CPUARM)} initialization libTestFairyModule := dlopen(MarshaledAString(liblibTestFairy), RTLD_LAZY); finalization dlclose(libTestFairyModule); {$ENDIF IOS} end. Immerhin ... Rollo |
AW: Hat Jemand schonmal mit TestFairy herumgespielt ?
Oha, und mit ein bischen umbenennen wirft er das raus:
Delphi-Quellcode:
Das sieht schon besser aus, werde ich mal Testen.
{***********************************************************}
{ } { CodeGear Delphi Runtime Library } { } { Copyright(c) 2012-2014 Embarcadero Technologies, Inc. } { } {***********************************************************} // // Delphi-Objective-C Bridge // Interfaces for Cocoa framework libTestFairy // unit iOSapi.libTestFairy; interface uses Macapi.CoreFoundation, Macapi.CoreServices, Macapi.Dispatch, Macapi.Foundation, Macapi.Mach, Macapi.ObjCRuntime, Macapi.ObjectiveC, Macapi.QuartzCore, iOSapi.CocoaTypes, iOSapi.Foundation, iOSapi.UIKit; type // ===== Forward declarations ===== {$M+} TestFairy = interface; // ===== Framework typedefs ===== {$M+} __builtin_va_list = Pointer; __darwin_va_list = __builtin_va_list; // ===== Interface declarations ===== TestFairyClass = interface(NSObjectClass) ['{32B9756A-9F33-47AE-AFBD-4A25D21BD540}'] [MethodName('begin:')] {class} procedure begin(appToken: NSString); cdecl; { * * Initialize a TestFairy session. * * @param appToken Your key as given to you in your TestFairy account } [MethodName('begin:withOptions:')] {class} procedure beginWithOptions(appToken: NSString; withOptions: NSDictionary); cdecl; { * * Initialize a TestFairy session with options. * * @param appToken Your key as given to you in your TestFairy account * @param options A dictionary of options controlling the current session } {class} procedure setServerEndpoint(serverOverride: NSString); cdecl; { * * Change the server endpoint for use with on-premise hosting. Please * contact support or sales for more information. Must be called before begin * * @param serverOverride } {class} function version : NSString; cdecl; { * * Returns SDK version (x.x.x) string * * @return version } {class} procedure hideView(view: UIView); cdecl; { * * Hides a specific view from appearing in the video generated. * * @param view The specific view you wish to hide from screenshots * } {class} procedure hideWebViewElements(selector: NSString); cdecl; { * * Hides a specific html element from appearing in your UIWebView * * @param selector The specific selector you wish to hide from screenshots. Multiple selectors can be comma separated } {class} procedure pushFeedbackController; cdecl; { * * Pushes the feedback view controller. Hook a button * to this method to allow users to provide feedback about the current * session. All feedback will appear in your build report page, and in * the recorded session page. * } {class} procedure sendUserFeedback(feedbackString: NSString); cdecl; { * * Send a feedback on behalf of the user. Call when using a in-house * feedback view controller with a custom design and feel. Feedback will * be associated with the current session. * * @param feedbackString Feedback text } {class} procedure updateLocation(locations: NSArray); cdecl; { * * Proxy didUpdateLocation delegate values and these * locations will appear in the recorded sessions. Useful for debugging * actual long/lat values against what the user sees on screen. * * @param locations Array of CLLocation. The first object of the array will determine the user location } {class} procedure checkpoint(name: NSString); cdecl; { * * Marks a checkpoint in session. Use this text to tag a session * with a checkpoint name. Later you can filter sessions where your * user passed through this checkpoint, for bettering understanding * user experience and behavior. * * @param name The checkpoint name } {class} procedure setCorrelationId(correlationId: NSString); cdecl; { * * Sets a correlation identifier for this session. This value can * be looked up via web dashboard. For example, setting correlation * to the value of the user-id after they logged in. Can be called * only once per session (subsequent calls will be ignored.) * * @param correlationId Id for the current session } [MethodName('identify:')] {class} procedure identify(correlationId: NSString); cdecl; { * * Sets a correlation identifier for this session. This value can * be looked up via web dashboard. For example, setting correlation * to the value of the user-id after they logged in. Can be called * only once per session (subsequent calls will be ignored.) * * @param correlationId Id for the current session } [MethodName('identify:traits:')] {class} procedure identifyTraits(correlationId: NSString; traits: NSDictionary); cdecl; { * * Sets a correlation identifier for this session. This value can * be looked up via web dashboard. For example, setting correlation * to the value of the user-id after they logged in. Can be called * only once per session (subsequent calls will be ignored.) * * @param correlationId Id for the current session * @param traits Attributes and custom attributes to be associated with this session } {class} procedure pause; cdecl; { * * Pauses the current session. This method stops recoding of * the current session until resume has been called. * * @see resume } {class} procedure resume; cdecl; { * * Resumes the recording of the current session. This method * resumes a session after it was paused. * * @see pause } {class} function sessionUrl : NSString; cdecl; { * * Returns the address of the recorded session on testfairy's * developer portal. Will return nil if recording not yet started. * * @return session URL } {class} procedure takeScreenshot; cdecl; { * * Takes a screenshot. * } end; TestFairy = interface(NSObject) ['{D9486008-3B18-43B2-87EB-CFD02703D7B5}'] end; TTestFairy = class(TOCGenericImport<TestFairyClass, TestFairy>) end; PTestFairy = Pointer; // ===== Exported string consts ===== function TFSDKIdentityTraitNameKey: NSString; function TFSDKIdentityTraitEmailAddressKey: NSString; function TFSDKIdentityTraitBirthdayKey: NSString; function TFSDKIdentityTraitGenderKey: NSString; function TFSDKIdentityTraitPhoneNumberKey: NSString; function TFSDKIdentityTraitWebsiteAddressKey: NSString; function TFSDKIdentityTraitAgeKey: NSString; function TFSDKIdentityTraitSignupDateKey: NSString; function TFSDKEnableCrashReporterKey: NSString; function TestFairyDidShakeDevice: NSString; function TestFairyWillProvideFeedback: NSString; function TestFairyDidCancelFeedback: NSString; function TestFairyDidSendFeedback: NSString; // ===== External functions ===== const liblibTestFairy = '/System/Library/Frameworks/libTestFairy.framework/libTestFairy'; procedure TFLog(format: Pointer {NSString}); cdecl; external liblibTestFairy name _PU + 'TFLog'; procedure TFLogv(format: Pointer {NSString}; arg_list: array of const); cdecl; external liblibTestFairy name _PU + 'TFLogv'; implementation {$IF defined(IOS) and NOT defined(CPUARM)} uses Posix.Dlfcn; var libTestFairyModule: THandle; {$ENDIF IOS} function TFSDKIdentityTraitNameKey: NSString; begin Result := CocoaNSStringConst(liblibTestFairy, 'TFSDKIdentityTraitNameKey'); end; function TFSDKIdentityTraitEmailAddressKey: NSString; begin Result := CocoaNSStringConst(liblibTestFairy, 'TFSDKIdentityTraitEmailAddressKey'); end; function TFSDKIdentityTraitBirthdayKey: NSString; begin Result := CocoaNSStringConst(liblibTestFairy, 'TFSDKIdentityTraitBirthdayKey'); end; function TFSDKIdentityTraitGenderKey: NSString; begin Result := CocoaNSStringConst(liblibTestFairy, 'TFSDKIdentityTraitGenderKey'); end; function TFSDKIdentityTraitPhoneNumberKey: NSString; begin Result := CocoaNSStringConst(liblibTestFairy, 'TFSDKIdentityTraitPhoneNumberKey'); end; function TFSDKIdentityTraitWebsiteAddressKey: NSString; begin Result := CocoaNSStringConst(liblibTestFairy, 'TFSDKIdentityTraitWebsiteAddressKey'); end; function TFSDKIdentityTraitAgeKey: NSString; begin Result := CocoaNSStringConst(liblibTestFairy, 'TFSDKIdentityTraitAgeKey'); end; function TFSDKIdentityTraitSignupDateKey: NSString; begin Result := CocoaNSStringConst(liblibTestFairy, 'TFSDKIdentityTraitSignupDateKey'); end; function TFSDKEnableCrashReporterKey: NSString; begin Result := CocoaNSStringConst(liblibTestFairy, 'TFSDKEnableCrashReporterKey'); end; function TestFairyDidShakeDevice: NSString; begin Result := CocoaNSStringConst(liblibTestFairy, 'TestFairyDidShakeDevice'); end; function TestFairyWillProvideFeedback: NSString; begin Result := CocoaNSStringConst(liblibTestFairy, 'TestFairyWillProvideFeedback'); end; function TestFairyDidCancelFeedback: NSString; begin Result := CocoaNSStringConst(liblibTestFairy, 'TestFairyDidCancelFeedback'); end; function TestFairyDidSendFeedback: NSString; begin Result := CocoaNSStringConst(liblibTestFairy, 'TestFairyDidSendFeedback'); end; {$IF defined(IOS) and NOT defined(CPUARM)} initialization libTestFairyModule := dlopen(MarshaledAString(liblibTestFairy), RTLD_LAZY); finalization dlclose(libTestFairyModule); {$ENDIF IOS} end. Rollo |
AW: Hat Jemand schonmal mit TestFairy herumgespielt ?
Ich habe immer noch den Linker-Error, jetzt werfe ich bald das Handtruch.
Schliesslich brauchge ich TestFairy nur zum Debuggen und Bug-Fixen, wenn das schon selber zum Bug wird dann kann ich es auch lassen. Hier noch ein paar Interessante Links zum Thema iOS Linikung: ![]() ![]() ![]() ![]() Aber mit der konkreten Library komme ich nicht weiter. Gibt es denn noch andere Ideen ? Gerne auch Alternativen zu TestFairy, aber bitte bezahlbar. Rollo |
AW: Hat Jemand schonmal mit TestFairy herumgespielt ?
Ich habe noch eine Erkenntnis:
Ich kann mit ![]() Nehme ich aber dieses XCode-Project und erzeuge die libMyLibrary neu dann geht es nicht mehr. Es kommt der gleiche Linkerfehler wie bei mir jetzt. - egal ob XCode 3.2 oder XCode 6.3 kompatibel. Ich bin jetzt kein XCode-Experte, aber vermutlich ist da irgendetwas umgestellt worden am Binary seit 2013, vielleicht hat jemand eine Idee ? Und wie bringe ich das Delphi bei ? Rollo |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:53 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz