Jump to content

Hans♫

Members
  • Content Count

    123
  • Joined

  • Last visited

  • Days Won

    3

Posts posted by Hans♫


  1. 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

  2. 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...


  3. 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


  4. 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;

     


  5. 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

  6. @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.


  7. 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.


  8. 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


  9. On 6/3/2019 at 2:29 PM, Yury said:

    -Tokyo 10.2,3; 

    -XCode10.1;

    -fb sdk 4.42.0

     

    I tried to use the Grijjy implementation that you linked to earlier, but I still get the same linker error:

    ___isOSVersionAtLeast", referenced from: -[FBSDKApplicationDelegate application:openURL:sourceApplication:annotation:] in Frameworks/FBSDKCoreKit.framework/FBSDKCoreKit(FBSDKApplicationDelegate.o);

    However, I just realize that you do not mention your iOS SDK version. I only have the problem with iOS 12, not with iOS11 and earlier.

    What iOS SDK do you use?


  10. It is declared as a TAESBuffer:

    TAESBuffer = array [0..15] of byte;

    I would actually expect that trick to work on 64 bit, but I don't know. It was just an example of the code.

    All I can say is that the total encryption and decryption produces different results on 64 bit than on 32 bit. The reason could be very simple or very complex, but I thought I would first ask here to hear other developers experiences, before I spend more time trying find a way through.


  11. Our software has been using the EldoS AES unit (128 bit key and ECB), to encrypt data stored locally on the users computers (binary data stored in a stream). 
    Now on a 64 bit target, this library no longer works, but our software should still be able to read existing data on the client computers, even when it is the 64 bit edition of our software running.
    This leaves us with two options:

     

    1) Make the EldoS AES encryption/decryption work with 64 bit.
    2) Find another library that can decrypt existing data correctly

     

    Add 1: Did anyone convert it to work with 64 bit?
    It uses some pointer tricks, for example: 

    SomeLongWordVar := PLongWord(@InBuf[0])^

    to convert 4 bytes from an array of byte (InBuf) to LongWord. Not sure if that would work in 64 bit.

     

    Add 2: I quickly tried to decrypt with Lockbox 3, but get the error: "Invalid ciphertext - block padding is corrupted". Maybe I am using it wrong, but it could also be they are not compatible.

     

    Any suggestions what I could use or do to read the old encrypted data from a 64 bit application?
     

×