Jump to content

Allen@Grijjy

Members
  • Content Count

    28
  • Joined

  • Last visited

  • Days Won

    3

Allen@Grijjy last won the day on May 10

Allen@Grijjy had the most liked content!

Community Reputation

34 Excellent

2 Followers

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Did some more reading here. Apple specifically says that extensions are not allowed to launch their host application unless it's a Today widget, "A Today widget (and no other app extension type) can ask the system to open its containing app by calling the openURL:completionHandler: method of the NSExtensionContext class. " https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/ExtensionOverview.html#//apple_ref/doc/uid/TP40014214-CH2-SW2 You may get rejected by Apple from the App Store for violating guidelines. That being said, I suspect from reading on StackOverflow that is exactly what some Share extensions are doing and they are in the App store. I attached an example ShareViewController.m that *may* work. Of course you will need to modify the urlString and replace https:// with abcd:// to launch the Url Protocol handler. ShareViewController.m
  2. Additionally, from what I have read, you cannot open/run the containing application (in your case a Delphi host application) from the share extension if the app is not already running. However, you can start your application by running a Url Protocol handler to launch your Delphi app. I was planning on writing a blog article about this topic. I put together a small example of how to implement a protocol handler that works on macOS and iOS and Delphi apps. It is attached here. There is a small EventManager unit included to simplify the process. The only thing you really need to do is modify the info.plist.TemplateOSX.xml (or info.plist.TemplateiOS.xml) and specify your Url Protocol handler method. For this example I use "abcd". So if you run this example application and then open Safari and type a Url like, abcd://www.google.com then you will receive that message in your Delphi app. It will automatically run your Delphi app if it is not already running. You should modify your didSelectPost so that it takes the urlString and changes the HTTP/S method to use your Url Protocol Handler method and then executes OpenUrl() to open the Url Protocol Handler thereby sending the Url to your Delphi app even if your app is not running. - (void)didSelectPost { NSExtensionItem *item = self.extensionContext.inputItems.firstObject; NSItemProvider *itemProvider = item.attachments.firstObject; if ([itemProvider hasItemConformingToTypeIdentifier:@"public.url"]) { [itemProvider loadItemForTypeIdentifier:@"public.url" options:nil completionHandler:^(NSURL *url, NSError *error) { NSString *urlString = url.absoluteString; // Call your Delphi app here!!! }]; } } ProtocolHandler.zip
  3. I went back a re-read your original post. Thanks for the clarification.. I think you need to place everything inside of "didSelectPost". Warning! I have not tested this example: - (void)didSelectPost { NSExtensionItem *item = self.extensionContext.inputItems.firstObject; NSItemProvider *itemProvider = item.attachments.firstObject; if ([itemProvider hasItemConformingToTypeIdentifier:@"public.url"]) { [itemProvider loadItemForTypeIdentifier:@"public.url" options:nil completionHandler:^(NSURL *url, NSError *error) { NSString *urlString = url.absoluteString; // Call your Delphi app here!!! // Share access to an NSUserDefaults object NSUserDefaults *sharedSettings = [[NSUserDefaults alloc] initWithSuiteName: AppGroupName]; // Set shared object key/value [[NSUserDefaults sharedSettings] setObject:urlString forKey:@"TheUrlString"]; // Synchronize [sharedSettings synchronize]; }]; } } Replace TheUrlString with the key you are using for GetObject on the Delphi app side. Also you could skip the constant for AppGroupName and instead write the line like: NSUserDefaults *sharedSettings = [[NSUserDefaults alloc] initWithSuiteName: @"group.it.diesys.yadiesys"];
  4. I sent you an email with some example attachments separately.... In regards to your questions: My app must listen to receive links (both closed and open) and it is not necessary to send anything to the extension. Does this mean your app must open/run if it’s not running when the extension needs it? To do this I have to enter this code but it is not clear where. In the OnCreate of the main form? You can do it anywhere in code. I think this part is used to send data to the Share Extension and therefore in my case it should not be necessary, right? Yes, if you only want to receive from the share extension it is not required. From your description of your requirements you need to translate the example from Delphi into Objective C and put that into your plugin in XCode. Should the synchronize be called every time something is sent? Yes How does the app know when a link is sent to it? and how can I extract it? The app should poll using something like a TTimer. It needs to call synchronize to make sure it has an updated copy of the data during the polling. Where should I insert this code? NSString *const AppGroupName = @" group.it.diesys.yadiesys'"; The constant is at the top of your plugin code directly after @implementation. This shouldn't be necessary because my Extension just has to send, right? Correct. You need to do something like we show in Delphi, but in Objective-C inside of XCode in your plugin. That should look something like this: // Create and share access to an NSUserDefaults object NSUserDefaults *sharedSettings = [[NSUserDefaults alloc] initWithSuiteName: AppGroupName]; // Set shared object key/value [[NSUserDefaults sharedSettings] setObject:somevalue forKey:@"somekey"]; // Synchronize [sharedSettings synchronize]; Where should I insert this code? Now what I have to do is send the Link, how do I capture and send it? I have never made this type of app extension, so I am not sure where you place the code on XCode side until I know what extension you are making. Each app extension works differently. Are you making a “share” extension for Safari? Are you trying to capture all urls from Safari into your app? Could you explain what you are doing a little bit better? If you could clarify I might be able to advise you where to capture what you want to capture. I have never made this type of extension so I don’t know if what you want to do is possible. Apple has all sorts of weird rules and restrictions on grabbing data from other apps.
  5. Hello Massimillano, I sent you an email this morning but it said you were "out of the office". The article shows how to use XPC to exchange the information with your extension. All the code required to do that is included in the blog article, it's not much. The strange part is you have to create an "Application group" in the Apple developer portal and then add it to your info.plist in order to use XPC (inter-process communication between the app and the extension) Let me know if you have any questions
  6. Latest article on how to use the latest version of OpenSsl 1.1.1 with Delphi directly to create X.509 certificates, decode, verify, encode and sign JSON Web Tokens and generate random data. Additionally we will do this in a way that works on Delphi supported platforms including Windows, macOS, iOS, Android and Linux as well as all current compiler targets for 32 and 64-bit devices. https://blog.grijjy.com/2020/08/04/using-openssl-1-1-1-with-all-delphi-target-platforms/
  7. I am very happy that FastMM5 is now available and also with the new licensing scheme. We plan to use it in our heavily threaded 64-bit http/socket servers. While I wouldn't have used it at all if it was GPL only, having a commercial offering at a reasonable price is actually more preferable because I like the idea of a properly maintained memory manager for our commercial products. There are plenty of free memory managers around for Delphi, that are barely maintained.
  8. Allen@Grijjy

    Named pipe failure, multithreading and asynchronous I/O

    I tried it both inside the debugger and outside the debugger with 10.3 with Win32 on Windows 7. At first it didn't work at all, as you described. Then it suddenly started working after I tried solution #1 in this article, https://knowledge.autodesk.com/search-result/caas/sfdcarticles/sfdcarticles/Install-Failure-Error-997-Overlapped-I-O-operation-is-in-progress.html Now I am not so sure why it started working and I cannot stop it from working, go figure. Since I know you are skeptic of actually running and testing on Win7, I attached a screenshot.
  9. Allen@Grijjy

    Named pipe failure, multithreading and asynchronous I/O

    Worked for me with 10.3 on Win32.
  10. Allen@Grijjy

    TSslHttpCli

    I think an incorrectly spelled name like autorization would qualify as an invalid header name. Also, just because you have an access token or refresh token, doesn't mean you made a request using an authorization header yet, as those required for bearer tokens. It is very common to use query parameters as part of a URI path to obtain the access and refresh token on OAuth implementations.
  11. Allen@Grijjy

    TSslHttpCli

    You spelled authorization wrong and it won't work otherwise.
  12. Allen@Grijjy

    ANN: Find leaks in Delphi and C++ with Deleaker

    Been experimenting with it myself and there are things I like. I will give a full report on it once they address some things I reported.
  13. The example I made is trivial. It expands a queue, so the size of the leak is directly proportional to the number of records you en-queue. Even if you destroy the queue, the leak persists. I am aware of RegisterExpectedMemoryLeak function. The call stack shows the problem comes from the Collections.TListHelper.InternalSetCapacity in Delphi's collections unit, that eventually calls the ReallocMem routine: LeakExample.exe!@ReallocMem$qqrrpvi Line 4900 004070b8 LeakExample.exe!DynArraySetLength$qqrrpvpvipi Line 35920 + 0x5 bytes 0040c466 LeakExample.exe!Generics.Collections.TListHelper.InternalSetCapacity Line 4489 + 0x9 bytes 004eb6f1 In the example I provided the actual collection is a queue of records that is created and destroyed. However when the queue grows, FastMM internally calls FastReallocMem to expand and internally determines it's a large block reallocation. If I simply redirect the ReallocMem routine back to SysReallocMem inside of FastMM, everything deallocates properly. Like you said, it could be a flaw in this tool, but the problem doesn't happen with Delphi's built in memory manager. It also doesn't happen if I change FastMM's source to simply call SysReallocMem immediately upon calling FastReallocMem. It also doesn't happen with numerous other data types, just collections, specifically queues of records.
  14. Attached is the smallest example I could make of a leak (it leaks roughly 1MB) that only occurs in FastMM4 (latest edition) with FullDebugMode disabled but does not occur with the default memory manager of Delphi 10.3. To test it, just compare it with FastMM4 commented/uncommented in the .dpr. You will need some external leak analysis tool like this one, for example, https://www.deleaker.com I honestly would like to understand what is happening here because I have also used FastMM over the years in numerous projects, but I found a few issues like this one and a couple of others related to reference counted interface de-allocations. Note: I am aware that FastMM4's leak checker doesn't show any leaks, but like I said previously, I don't trust it to analyze itself. LeakExample.zip
  15. Out of curiosity, what are you all using to determine you are leaking or not? Let's assume we ignore System.pas related things. Have you compared the results of a tool like the Deleaker using the base memory manager with a large project vs. Deleaker with FastMM4 enabled (without full debug mode) or any other memory manager?
×