-
Content Count
1607 -
Joined
-
Last visited
-
Days Won
36
Everything posted by Dave Nottage
-
I have added a demo to the HowTo repo that demonstrates how to achieve this. Please read the readme for instructions. Note that there is no special folder - it's a case of configuration in order to share files from the documents folder.
-
How to detect when a Form is active in Designer
Dave Nottage replied to luciano_f's topic in GExperts
Thanks.. your ticket is the explanation I was looking for. -
How to detect when a Form is active in Designer
Dave Nottage replied to luciano_f's topic in GExperts
Just so I understand: why do you need to do this? -
How to detect when a Form is active in Designer
Dave Nottage replied to luciano_f's topic in GExperts
Can you explain this in another way? It sounds very confusing. -
I always install macOS support anyway, so had not noticed. I haven't seen the requirement anywhere (as yet), so someone might want to report the issue ๐
-
I was going to expand on it, but Uwe has done it! https://www.uweraabe.de/Blog/2023/10/04/tzipfile-improvements-in-delphi-12/
-
You mean it worked after installing macOS support? Compiling for iOS Simulator should not require it, as far as I know.
-
dsymutil.exe should be in the bin folder of your Delphi install, e.g. C:\Program Files (x86)\Embarcadero\Studio\22.0\bin If it is not, then it seems your install of Delphi did not complete correctly, which may mean you need to reinstall. Less drastic is perhaps uninstall iOS support and reinstall it using Tools | Manage Platforms
-
I was looking at the wrong part of IdGlobal, i.e. line 2865 (in Delphi 11.3)
-
If I understand correctly, the current beta of Xcode is relevant only to those developing for Vision OS - it is otherwise the same as the released version. Can you provide evidence that this is the case? Regardless, I'm not sure why Indy chooses to use its own function over the one in System.pas - the code for it is executed differently on iOS than on Windows.
-
After a bit of experimenting and searching around, it appears it's currently not possible. Here is one link relating to the issue: https://bugs.chromium.org/p/chromium/issues/detail?id=669492 I expect you'll need to implement photo taking in the app itself, and then when the user taps "Select Photo" or "Take A Photo" link in the TWebBrowser, they'll be able to select the image that has been taken.
-
They're the only ones I have seen so far. On Facebook: https://www.facebook.com/groups/137012246341854 and https://www.facebook.com/groups/342580832556845
-
I've seen similar issues reported on social media groups. I'll be testing it myself later
-
Interestingly enough, that's exactly the fix that was reported here ๐
-
Send sqlite database file with share sheet on IOS and Android
Dave Nottage replied to grantful's topic in Cross-platform
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. -
Send sqlite database file with share sheet on IOS and Android
Dave Nottage replied to grantful's topic in Cross-platform
I have kept Kastri very much up to date, and I "officially" support the last 2 major updates, i.e. presently 10.4.x and 11.x. Rest assured that the same will apply to Delphi 12. -
Send sqlite database file with share sheet on IOS and Android
Dave Nottage replied to grantful's topic in Cross-platform
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 -
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.
-
The In-App purchase issue might have been occurring only on earlier betas. Chris has extreme users ๐
-
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.
-
What happens if you run it via the debugger?
-
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?
-
Can you give an example of a site where it does this?
-
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 );
-
Decryption of values encrypted by crypto-js, using OpenSSL
Dave Nottage posted a topic in General Help
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