Jump to content

Dave Nottage

Members
  • Content Count

    1296
  • Joined

  • Last visited

  • Days Won

    29

Posts posted by Dave Nottage


  1. 29 minutes ago, grantful said:

    I have looked at the uses clause in the demo and I have the same  thing in mine.  I am sure i am not including something.

    Your project appears to include a folder in its search path that contains the file Macapi.ObjectiveC.pas, which by default is in the source\rtl\osx folder in the Delphi install, but perhaps you have a copy of the file elsewhere. The fact that it reports: Undeclared identifier: 'SObjCClassRegistrationFailed' means that there's a mismatch between the Macapi.ObjectiveC.pas it finds, and the System.RTL.Consts unit, which contains the missing identifier.


  2. 6 minutes ago, grantful said:

    here is the error  FShareSheet.SharedFileName is the undeclared identifier. 

     

    so the .sharedFileName is the issue.

     

    i am looking in the FMX.MediaLibrary.Actions and can not see anything about the shared file name.

    Where did you have the idea that SharedFileName was a property of TShowShareSheetAction? This class supports sharing only images and text.

     

    If you want to share a file, you may be interested in this: https://github.com/DelphiWorlds/Kastri/tree/master/Demos/ShareItems


  3. 47 minutes ago, tdalke said:

    Has this issue been resolved? (Delphi app crashing on iOS 17)

    No official fix as yet, however I have come up with the following workaround - Note: this has had no testing beyond a blank app:

     

    1. Copy FMX.Platform.iOS from source\fmx into your project folder.

     

    2. In the TApplicationDelegate.applicationDidFinishLaunchingWithOptions method towards the end, make the following change (i.e. add the one line of code indicated😞

        // Creating window
        WindowManager := PlatformCocoaTouch.WindowManager;
        WindowManager.Window := TFMXWindow.Create(MainScreen.bounds);
        WindowManager.RootViewController := TFMXViewController.Create;
        // *** iOS17 SDK crash issue - Add the following line: ***
        WindowManager.RootViewController.Super.init;
        WindowManager.NativeWindow.makeKeyAndVisible;

    Note also that this measure is needed only if you are building against the iOS 17 SDK - it is not required when building against earlier SDKs.

    • Like 2
    • Thanks 3

  4. 39 minutes ago, Hans♫ said:

    t's strange that we have not had any reports from iOS 17 users, and our own tests on iOS 17 also runs fine.

    The In-App purchase issue might have been occurring only on earlier betas. Chris has extreme users 😉

     

    • Like 1

  5. 36 minutes ago, Dave Nottage said:

    What happens if you run it via the debugger?

    Never mind - it seems debugging from Delphi is not possible for iOS 17 devices at the moment. I confirm that apps built against iOS 17 SDK crash on start. For now, you'll need to use an older SDK (e.g. iOS 16.4 SDK), if you had imported that earlier.

    • Like 1

  6. 2 hours ago, avesuvorov said:

    I'm creating a simple "Hello world" application. When opened on iPhone, the program closes.

    I changed the FMX.inAppPurchase.iOS.pas file on the advice of Chris Pim, but nothing helped

    If it's just a simple "Hello world", you will not need to modify FMX.inAppPurchase.iOS, since it won't be using it. 

     

    Does this happen if you start a completely blank project, and run that?


  7. The process on Android is to:

     

    Check the checkbox for Camera permission in the Uses Permissions of the Project Options

     

    Request the permission at runtime, e.g:

      PermissionsService.RequestPermissions(['android.permission.CAMERA'],
        procedure(const APermissions: TClassicStringDynArray; const AGrantResults: TClassicPermissionStatusDynArray)
        begin
          if AGrantResults[0] = TPermissionStatus.Granted then
            // Permission was granted
        end
      );

     

    • Like 2

  8. 19 hours ago, Marcelo Bernardi said:

    Remembering that this only happens if the device is running Android 13

    It's because changes are required to the FMX code, specifically in FMX.MediaLibrary.Android.pas. If you have a Delphi subscription, you would be able to take advantage of changes in the Yukon beta, as per this information.


  9. 9 minutes ago, Kas Ob. said:

    So this 

    
    EVP_CIPHER_CTX_set_padding(LContext, 0);

    After EVP_DecryptInit_ex should solve the failure of EVP_DecryptFinal_ex,

    That it does, thanks! 

    10 minutes ago, Kas Ob. said:

    the rest is up to you to find and fix, specially that HMAC !!!!!, where it comes from ?

    From other code I found. Yes, I guess that part is wrong since the output is wrong.


  10. The goal is to be able to encrypt some data using crypto-js (in Javascript) and decrypt the value in a back end built with Delphi, using OpenSSL (since crypto-js claims to be OpenSSL compliant).

     

    This is the Javascript code:

    const CryptoJS = require('crypto-js');
    
    var IV = '583066480e215358084bc6640df95fdd';
    var passphrase = 's0m3s3cr3t!';
    
    // According to:
    //   https://stackoverflow.com/a/75473014/3164070
    // IV is ignored, so can be anything!
    
    function encrypt(text: string): string {
      var key = passphrase;
      var iv = CryptoJS.enc.Hex.parse(IV);
      console.log('iv: ' + iv.toString());
      var encrypted = CryptoJS.AES.encrypt(text, key, { iv: iv });
      return encrypted.toString();
    }

    This is the Delphi code. Note that OpenSSL.Api_11 comes from Grijjy (as well as the SSL binaries):

    unit Unit1;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
    
    type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    uses
      System.NetEncoding,
      OpenSSL.Api_11;
    
    const
      cPassphrase = 's0m3s3cr3t!';
    
    procedure CryptoError;
    var
      LError: TBytes;
      LMessage: string;
    begin
      SetLength(LError, 120);
      ERR_load_crypto_strings;
      ERR_error_string_n(ERR_get_error, @LError[0], Length(LError));
      LMessage := TEncoding.UTF8.GetString(LError);
      // Display the message
    end;
    
    function DecryptAES256(const AValue: string): string;
    var
      LContext: PEVP_CIPHER_CTX;
      LOutputLen, LFinalLen: Integer;
      LBytes, LSalt, LIV, LEncryptedText, LKey, LOutput: TBytes;
    begin
      Result := '';
      LBytes := TNetEncoding.Base64.DecodeStringToBytes(AValue);
      // crypto-js returns an OpenSSL result, i.e. "salted__" + salt + encrypted text
      LSalt := Copy(LBytes, 8, 8);
      LEncryptedText := Copy(LBytes, 16, MaxInt);
      SetLength(LKey, EVP_MAX_KEY_LENGTH + EVP_MAX_IV_LENGTH);
      // Calc key and IV from passphrase and salt
      if PKCS5_PBKDF2_HMAC(cPassphrase, Length(cPassphrase), @LSalt[0], Length(LSalt), 1000, EVP_sha256, Length(LKey), @LKey[0]) = 1 then
      begin
        LIV := Copy(LKey, EVP_MAX_KEY_LENGTH, EVP_MAX_IV_LENGTH);
        LKey := Copy(LKey, 0, EVP_MAX_KEY_LENGTH);
        // Create a new cipher context
        LContext := EVP_CIPHER_CTX_new();
        if LContext <>  nil then
        try
          // Initialize the decryption operation with 256 bit AES
          if EVP_DecryptInit_ex(LContext, EVP_aes_256_cbc, nil, @LKey[0], @LIV[0]) = 1 then
          begin
            SetLength(LOutput, Length(LEncryptedText) + EVP_MAX_BLOCK_LENGTH);
            // Provide the message to be decrypted, and obtain the plaintext output
            if EVP_DecryptUpdate(LContext, @LOutput[0], @LOutputLen, @LEncryptedText[0], Length(LEncryptedText)) = 1 then
            begin
              if EVP_DecryptFinal_ex(LContext, @LOutput[LOutputLen], @LFinalLen) = 1 then
              begin
                Inc(LOutputLen, LFinalLen);
                Result := TEncoding.UTF8.GetString(LOutput);
              end
              else
                CryptoError;
            end
            else
              CryptoError;
          end
          else
            CryptoError;
        finally
          EVP_CIPHER_CTX_free(LContext);
        end;
      end;
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      // Decrypt value output by crypto-js
      DecryptAES256('U2FsdGVkX1812TdTm8MD2w4u2AaxUB2PdurCNOmu4bmutkR1Ul7Z1+bGXDsdlNK5'); // This is just an example value. Generate a new one from the Javascript code
    end;

    The code "fails" at the EVP_DecryptFinal_ex stage. Have I missed anything obvious?

     

    I know there's 3rd party code that will probably handle this, however it's just this function that is required (for now), so I'd prefer to avoid introducing a bunch of dependencies


  11. On 9/9/2023 at 2:36 AM, grantful said:

    I am just wondering is there a way to access this and use it in my iOS app

    Should be possible using Vision and VisionKit, as indicated by this article. It's in Swift, so you'd need to know how to translate it into Delphi, but you could use these imports:

     

    https://github.com/DelphiWorlds/Kastri/blob/master/API/DW.iOSapi.Vision.pas

    https://github.com/DelphiWorlds/Kastri/blob/master/API/DW.iOSapi.VisionKit.pas  Please take heed of the notes in this unit!

     


  12. 59 minutes ago, Brian Evans said:

    A HTTP GET doesn't use a body

    It can, but there are warnings against doing it. This is an interesting article on the topic.

     

    The fact that it is possible (even though ill advised) means that the code in Delphi that turns the GET into a POST on Android, is a bug.

    Jon R should describe why they need to subvert the warnings against doing it 🙂

    • Like 1

  13. 23 hours ago, Dave Nottage said:

    You’ll need TEdgeBrowser or something similar to actually render it for you

    I've decided to go down this route - it has turned out easier than I expected, especially when using ExecuteJavascript to extract the relevant parts out of the HTML

×