Jump to content

Hans♫

Members
  • Content Count

    130
  • Joined

  • Last visited

  • Days Won

    3

Posts posted by Hans♫


  1. 12 hours ago, Dave Nottage said:

    There's someone in another post here asking about whether there are updated imports for the FB SDK.

    I didn't answer this one because the steps to include the FB SDK is pretty much the same as mentioned in the GRIJJY blog. Though I never needed to fix anything regarding Delegates, so depending on your needs, this pretty long part can be skipped.

    Also, my first implementation of the FB SDK was made in 2015-16, before anyone else had published solutions for it. My implementation is much simpler and focus only on the areas that I needed my self. Therefore it is not compatible with the GRIJJY source code.

     

    However,

    @MikeMon I'll be happy to share my headers and units to implement the Facebook API.


  2. On 1/29/2020 at 10:04 PM, Dave Nottage said:

    If you're still having trouble, please look at line 175 here:

    https://github.com/DelphiWorlds/KastriFree/blob/master/API/DW.iOSapi.Firebase.pas

    Basically forces the linker to link to libclang_rt.ios.a, which has the "missing" symbol

    Thanks Dave, it solved the problem!

     

    I added the fake includer function to the FB SDK headers as you suggested:

    procedure CLangRTLoader; cdecl; external '/usr/lib/clang/lib/darwin/libclang_rt.ios.a';

    Now it links with the FBSDK 4.36 without problems, and after a few hours of work to adapt my code to the new API version, everything works!

    (I didn't try newer versions for now, as they might require further updating of my code and headers)
     

    • Like 1

  3. 56 minutes ago, Rollo62 said:

    @Hans♫

    Congratiulations from my side too.

    Thanks 🙂

     

    57 minutes ago, Rollo62 said:

    @Hans♫

    May I ask: does FB has part in that success story ?

    Did you make a special FB promotion, advertising to get there ?

    I don't think that our FB activities have had any influence on Apples decision to feature EarMaster.

    From my point of view, FB advertising is useful if you have a free app and it targets something that people have a personal interest in.

    When you are viewing you FB news thread, you are not in "commercial mode", but instead you can easily be attracted by an add about something you are passionate about.

    It's however important to submit all in-app purchases to FB, so you can calculate the ROI, which is what we mainly use our FB integration for.

    • Like 1

  4. Our iOS app, EarMaster, made with Delphi is now featured in App Store, in the "Best of the month - New apps we love".

    Nice to see that a Delphi app can get this kind of approval from Apple.

     

    PS. I am in Denmark, so I see the Danish app store, but I am curious to know, in what other countries it has been featured too?

    2020-01-29 10.30.13.png

    • Like 12
    • Thanks 1

  5. Thanks a lot Dave for looking into this!

    I removed the [Weak] attribute in the test program, but it still crashes regularly, though it does seem to increase the probability of success. 

     

    When I have a successful request and then perform the same request again, then I also get an AV. It seems like the AppStore request messes up some memory. Sometimes it is in an area that prevents us from finishing the request, and sometimes it is a different place that will allow a successful request, but will cause problems later. Also, if I run the test program directly from the ScratchDir on the Mac, then it is never successful and crashes every time.

     

    It's strange that the Objective-C wrapping seems to work all other places, but not here...


  6. Maybe this is a bug in the OSX64 compiler? I have attached the small test project that produces the error. It should compile and run out of the box.

    Are there someone out there with the knowledge needed to look into this, that I could hire to solve this?

     

    I see only two outcomes: Either some code in the test project can be changed to solve it, or a bug report should be filed to Embarcadero.

    MacInAppTest.zip


  7. The FMX.InAppPurchase component already implements in-app purchase for iOS, and since OSX uses the same StoreKit library, I simply added an OSX copy of the iOS implementation and adjusted it to "work" on OSX. It works as far as it compiles and runs, and I can call "QueryProducts", which also initiates a Delegate callback. 
    Once in a while I can even successfully read the product details from App Store that I receive in the callback, but most of the time the callback fails with an AV. It seems to be random where it fails. If I restart paserver before each run I can increase the chance that it works, but except from that I did not find any correlation between changes I have made and a successful request.

    The testprogram works fine on iOS. On OSX I have tried to target both Mojave and Cataline, and both 32 bit and 64 bit editions. They all fail.

    As the OSX code is the same as the iOS code, I guess that the problems are related to differences between the iOS and the OSX target in the Objective-C handling and wrapping.


    Any ideas what could be wrong, or what I should try?
    (or maybesomeone with more knowledge about Objective-C wrapping and the inner workings of Delphi could help me with this?)
     

     

    Below are some extracts from the code in my new unit "FMX.InAppPurchase.Mac". My test program creates TiOSInAppPurchaseService and call QueryProducts. It works without errors, and a few seconds later the TiOSProductsRequestDelegate.productsRequest callback is called. From here random AV's happens. Usually it fails on the first line FIAPService.FProductList.Clear, and sometimes it fails earlier in "DispatchToDelphi" or later in one of the following lines.

    TIAPProductList = class(TList<TProduct>)
    end;
    
    procedure TiOSInAppPurchaseService.QueryProducts(const ProductIDs: TStrings);
    var
      ProductIDsArray: NSMutableArray;
      ProductIDsSet: NSSet;
      ProductID: string;
    begin
      ProductIDsArray := TNSMutableArray.Create;
      for ProductID in ProductIDs do
        ProductIDsArray.addObject(PStrToNSStr(ProductID));
      ProductIDsSet := TNSSet.Wrap(TNSSet.OCClass.setWithArray(ProductIDsArray));
      FProductsRequest := TSKProductsRequest.Wrap(TSKProductsRequest.Alloc.initWithProductIdentifiers(ProductIDsSet));
    ...
      FProductsRequest.setDelegate((FProductsRequestDelegate as ILocalObject).GetObjectID);
      FProductsRequest.start;
    end;
    
    constructor TiOSInAppPurchaseService.Create;
    begin
    ...
      FProductsRequestDelegate := TiOSProductsRequestDelegate.Create(Self);
      FProductList := TIAPProductList.Create;
    end;
    
    
    constructor TiOSProductsRequestDelegate.Create(const IAPService: TiOSInAppPurchaseService);
    begin
      inherited Create;
      FIAPService := IAPService;
    end;
    
    procedure TiOSProductsRequestDelegate.productsRequest(request: SKProductsRequest; didReceiveResponse: SKProductsResponse);
    begin
      FIAPService.FProductList.Clear;
    ...
    end;

     


  8. Good news about iOS crashes!

    I owe Embarcadero and all of you to show the updated crash report graph. The problem was an internal hard limit in librtlhelper.a on the number of OC wrappers that could be created. As my app uses the TMC iCL native components, and is a large and comprehensive app, it wraps thousands of OC objects. Each new Delphi version used more and more OC wrappers on its own, leaving less for use in the app. That's seen clearly on the previous graph I showed.

     

    Marco sent an updated version of librtlhelper.a to me with a higher internal limit, and the result is seen clearly on the graph below. There are still some crashes though, which might indicate that a some of our users still reach the limit, <irony>since I can't imagine that there can be other errors in our software</irony>.

     

    IOS_Crashes.thumb.jpg.4a5a9050ea6ee3ec78393d68e3a796d8.jpg

    • Like 2
    • Thanks 2

  9. @sjordi Yes, I know about this. It is standard procedure to open the Xcode devices with every new device, so it can be prepared for debugging.

    @Sherlock Yes, I can debug on iOS 12, both before and after upgrading to XCode 11 - so the problem is with either iOS 13 or iPhone 11 Pro.

     

    I don't have anymore time to spend on this right now, there are endless combinations of things to try and test. But I hope someone else will investigate this further.


  10. I can confirm what is said previously: I can deploy my app to an iPhone 11 Pro with iOS 13 through Xcode 11, and the app runs fine.

    However, I cannot run it from Delphi ("Run" or "Run without debugging"). They both deploy the app to the device, but then shows the message "Can't start debugserver on device - device support image was not mounted". After that, I can just run the app manually on the device, but without debugging. Not a big problem as debugging usually fails anyway, so running in debugmode is already the very last option for me.


  11. Yes, I am using an empty app to test it. It only contains a few lines that uses the FBSDK.

     

    This is the code. It calls the "ActivateApp" function and tries to show a Facebook Link Sharing Dialog on iOS. But it fails in the linking process (with the errors mentioned earlier), so the code never executes. Note, I had to add some Objective-C classes to the Grijjy unit, as it did not include all the ones I need (the modified unit is attached):

     

    uses
      System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
      iOSapi.UIKit, iOSapi.Foundation,
      Macapi.Helpers,
      Grijjy.FBSDK.iOS.API,
      FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs;
    
    type
      TForm1 = class(TForm)
        procedure FormShow(Sender: TObject);
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.fmx}
    
    function GetRootViewController: UIViewController;
    begin
    //Get the main window to be the parent of the facebook window (First window is always the main window)
      Result := TUIWindow.Wrap(TUIApplication.Wrap(TUIApplication.OCClass.sharedApplication).windows.objectAtIndex(0)).rootViewController;
    end;
    
    procedure ShowShareDialogMode(aContent: Pointer);
    var lFBSDKShareDialog: FBSDKShareDialog;
    begin
      lFBSDKShareDialog := TFBSDKShareDialog.Create;
      lFBSDKShareDialog.setshareContent(aContent);
      lFBSDKShareDialog.setFromViewController(GetRootViewController);
      lFBSDKShareDialog.setMode(FBSDKShareDialogModeNative);
      if not lFBSDKShareDialog.canShow then //if FB app not installed, fallback to web access
        lFBSDKShareDialog.setMode(FBSDKShareDialogModeFeedBrowser);
      lFBSDKShareDialog.Show;
    end;
    
    procedure ShareLink(const aLink: string);
    var lLinkContent: FBSDKShareLinkContent;
    begin
      lLinkContent := TFBSDKShareLinkContent.Create;
      lLinkContent.SetcontentURL(StrToNSUrl(aLink));
      ShowShareDialogMode( NSObjectToID(lLinkContent) );
    end;
    
    procedure TForm1.FormShow(Sender: TObject);
    begin
      TFBSDKAppEvents.OCClass.activateApp;
      ShareLink('');
    end;

     

    Grijjy.FBSDK.iOS.API.pas

×