Quantcast
Channel: Delphi Worlds
Viewing all 80 articles
Browse latest View live

Integrating iOS support with Delphi’s FCM

$
0
0

Before the release of Delphi 10.3.2, Embarcadero released a patch for including FCM (Firebase Cloud Messaging) for Android in your apps, and now that support is included in Delphi 10.3.2. This article describes how to include support for iOS in FCM.

UPDATE: With many thanks to Antonello Carlomagno, the iOS implementation now has been tested more, and fixes applied as a result. Please update the demo files so that your iOS app will now receive events whilst the app is in the foreground or background.

TL;DR – The demo for including iOS in FCM is here. Note that it depends on other files in Kastri Free.

This solution is based around existing code that is used in my FCM solution, presented here. I created a unit (DW.PushNotification.iOS) which is similar to FMX.PushNotification.Android, that is meant as a “replacement” of sorts for FMX.PushNotification.iOS.

This new push notification unit uses other units from Kastri Free to provide the necessary implementation for iOS. It also relies on framework files from the Firebase 6.2.0 iOS SDK, however those that are required are also part of Kastri Free. The key things to remember for iOS when you’re including it in your own project are:

  • Add GoogleServices-info.plist (download it from your project in Firebase Console) to your deployment (use a Remote Path of ./)
  • Include -ObjC in the “Options passed to the ld linker” setting in the Linking options, which is under Building\Delphi Compiler in the Project Options. You’ll soon know if you’ve missed this because your app will crash on startup.
  • Include paths to the Firebase SDK frameworks (these are in the Search path in the Project Options of the demo for iOS Device 64-bit configuration)

Go here for information on how to configure your app for FCM for Android.

As described above, the demo for this solution can be found here. It has had fairly minimal testing, so if you have any issues, please report them here.


Using OpenSSL with Indy in notarized apps on macOS

$
0
0

The requirement for macOS apps to be notarized has thrown a few challenges, one of them being that developers are having trouble with apps that use Indy components with SSL. This article describes how to overcome that issue.

Rather than dive headlong into working out why the notarized app would not work, I decided to “start from scratch” (in a way), and work out how to build the dylibs for macOS. The results are located here (i.e. macOS binaries for OpenSSL, version 1.0.2s).

The binaries need to be added to your application via the Deployment Manager, and the Remote path value for each binary is: Contents\MacOS, e.g:

Note that in this picture, I have selected All configurations for macOS 64-bit, so that both Debug and Release are shown.

In the project source, add System.IOUtils and IdSSLOpenSSLHeaders to the uses clause, and call IdOpenSSLSetLibPath, like this:

program NotarizedIndy;

uses
  System.StartUpCopy,
  System.IOUtils,
  FMX.Forms,
  IdSSLOpenSSLHeaders,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  IdOpenSSLSetLibPath(TPath.GetDirectoryName(ParamStr(0)));
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

After compiling and notarizing your application, you should find that Indy with SSL now works.

Tools that I use

$
0
0

In this post, I’ll be taking a look at some of the tools that I use in the process of software development that I swear by. It’s not all about Delphi 😉

Before around 2011, I used to be a bit of a “it’s Windows or nothing” kind of person. When I started down the path of developing for iOS and macOS, all that changed; I needed a Mac to be able to develop for those platforms, so I started using one and have never looked back. Most of the tools I use I prefer the Mac version, because it means not having to fire up a Windows VM to run the tool. Today I’m presenting a list and a summary of some of the tools I use. In future I’ll revisit some of these and cover them in more detail in terms of how/why I use them.

Here’s a list of those that I use most:

VirtualBox

Of course to use Delphi I still need Windows, so for the most part I have been using VirtualBox to create Windows VMs to run Delphi on.

Parallels

When a new release of Xcode and/or macOS comes out, as many of you may know, Delphi has not always “played nice” with them, so having a VM of macOS to test out Xcode has been essential. Unfortunately, VirtualBox has not always been able to keep up with changes in macOS, so a while ago I decided to use Parallels for running macOS VMs, on my Mac 🙂

Laravel

Whilst Delphi is an excellent product for creating back-end applications, PHP applications are relatively easily deployed on any platform (including Raspberry Pi running an ARM Linux variant), and my PHP framework of choice is Laravel. I stumbled upon it around the beginning of 2017 and was very impressed. It can be used to create the front-end part of the application using its Blade templating engine, however it also plays very well with Vue. Laravel is quite mature now, and has a large thriving community.

TablePlus

I’ve just recently come across this one, after being a long time user of Sequel Pro. TablePlus supports a number of databases, has a much nicer UI and supports dark theme.

Insomnia

As with TablePlus, I’ve just recently come across Insomnia, which is an awesome REST testing tool. I find it is much “cleaner” and easier to use than PostMan.

Visual Studio Code

Any editing that I need to do outside of Delphi, I use Visual Studio Code, including all my Laravel work, editing of Java source for jars included in my Delphi projects, and a whole bunch of other files.

Fork

Fork is a graphical git client that runs on macOS or Windows, and is the best one I’ve come across. It’s also free!

Slack

Slack is a collaboration tool that is probably used mostly for chat, however it also allows integration of many other applications such as Github, JIRA, Google Calendar, Outlook, Zoom, Trello and more. You and your team can receive notifications right in the Slack channel that subscribes to those applications. One of Slack’s biggest drawbacks is that usually someone who is already on the “team” needs to invite others. Fortunately there are ways of having people “invite themselves”, including using a small PHP application that automatically sends the invite, such as the one I use where you can invite yourself to the Delphi Worlds Slack team 🙂

Here’s a list of tools that I have developed myself:

Codex

An add-in (or expert) for Delphi that adds functionality that I use all time, including

  • Building a jar from Java source, so that it can be included in Delphi projects
  • A front-end for Java2OP, to help import Java classes into Delphi units
  • Image assets manager for easily configuring splash screens and icons for mobile projects.

..and it also includes (amongst other things) some “tweaks” for the IDE.

Mosco

Mosco (MacOS COmpanion) is a combination of an add-in for Delphi and an application that runs on the Mac. It supplements what PAClient and PAServer do.

Device Lens

A tool for displaying logs emitted from mobile devices. Presently, it supports viewing logcat output from Android devices, however support for viewing iOS device logs (via Mosco) is in the works.

Cross-platform location monitoring

$
0
0

Previously, I have written two articles on monitoring location changes: one for iOS, and one for Android. This article and the related demo brings everything up-to-date and merges support for both operating systems.

STTP (Straight To The Point – I’m coining an acronym to replace TLDR)

If you’re just after the demo, you may find it here. As with most demos in the articles in this blog, it is dependent on the Kastri library. Please be aware that for iOS you will need to apply the System.iOS.Sensors patch as detailed below. Delphi 10.4 users: An update for the demo is coming soon, as it will not require the patch for iOS.

Requirements

As per the previous articles, the aim is to be able to monitor location changes reliably, including when the application is not running. Due to restrictions introduced in later versions of Android, and some shortcomings in the iOS implementation in Delphi, there some “hoops to jump through” to make this all happen.

Project Groups

The demo has 2 project groups: one containing the application and service (CPLAndroidGroup), and one that contains just the application (CPLAppOnlyGroup). CPLAppOnlyGroup is useful for compiling for iOS, because if you compile just the application in the CPLAndroidGroup for iOS, the IDE will still compile the service, regardless of the fact that you are not compiling the application for Android. This issue has been reported, here.

Grijjy Cloud Logger

You may notice in the code that use is made of the excellent Grijjy Cloud Logger framework. This has been useful for debugging so I have left the code in, and if you want to use it, you will need to add defines (CLOUDLOGGING) in the Project Options for the supported platform targets.

Unfortunately at present there is no support for Grijjy Cloud Logging on Android 64-bit. Hopefully this will be rectified soon.

If you choose to use Grijjy Cloud Logging, you will need to either define user override environment variables in the IDE options that correspond to the library locations:

..or modify the project search paths to point to the required libraries.

You will also need to modify the value for cCloudLoggingHost in the CPL.Consts unit in the Common folder, to point to your cloud logging broker instance.

Application

The application has been refactored to integrate the iOS implementation to make things work smoother, and hopefully be easier to follow. Notably, it now includes the DW.ServiceCommander.Android unit, which contains:

TServiceCommander

This class:

  • Handles the BecameActive and EnteredBackground application events, sending a local broadcast to the service to inform it of the change so that the service can enter or exit foreground mode.
  • Has a StartService command that starts the service if it is not already running.
  • Has a SendCommand method to send any other commands that the service needs to receive.

DW.Location unit

This unit and the units it uses contain the classes necessary for integrating iOS support, and for Android for receiving location messages from the service. The iOS implementation uses TLocationSensor which comes with Delphi, however there are some customizations that are necessary, which are detailed later in this article.

Android Service

On Android, the application needs a service, and since it needs to be able to track location when the app is not running, it needs to start when the device starts. As per the previous Android demo, instead of using TLocationSensor, I chose to write custom code; mostly for more control, and also so that it can be easily “swapped out” for another implementation such as one that uses FusedLocationProviderClient.

The ServiceModule has been refactored to decouple some of the functionality, namely:

TBackgroundMonitor

The OnScreenLockChange event is fired when the screen is locked.

When the device enters “doze” mode, an alarm is set so that the service will be invoked when the alarm fires, and the OnDozeChange event fires so that any additional action may be taken.

TLocationUpdater

This class is responsible for processing the location update. It may send the location details to a server, and/or store the location in a local database.

TLocation

This class existed in the prior version of the demo, however it has been refactored somewhat to improve reliability.

Starting the service at boot time

The service starts when the device starts by using a broadcast receiver (A Java class called DWMultiBroadcastReceiver, in dw-kastri-base.jar) which is configured in AndroidManifest.template.xml

The android.intent.action.BOOT_COMPLETED and android.intent.action.QUICKBOOT_POWERON intent filters ensure that the broadcast receiver receives these intents on cold boot and restart. In the Java code for DWMultiBroadcastReceiver, the metadata is checked for an entry named DWMultiBroadcastReceiver.KEY_START_SERVICE_ON_BOOT, and the metadata value is used as the name of the service to start:

Note that DWMultiBroadcastReceiver also exists in dw-multireceiver.jar, however I am in the process of merging Java code used in Kastri in an effort to reduce the number of jar files.

Considerations for later versions of Android

In Android 10, using location services via a service requires requesting a runtime permission of android.permission.ACCESS_BACKGROUND_LOCATION, so this permission is added to AndroidManifest.template.xml (the permission cannot be  configured via the IDE), and the permission is requested in code.

From Android 8, a service is required to start in foreground mode if the application goes to the background or is not running. The previous demo went some way to solving this, however it was not 100% reliable; this demo should work as it should. Since the demo uses a regular service, when starting in the foreground the service needs to post a notification which is visible in the status bar, and a banner is visible in the lock screen. Although this is a tad intrusive, presently it’s the only option using a plain Service constructed in Delphi, as using an Intent Service is currently broken in Delphi. Note: This issue has now been fixed in Delphi 10.4, so this demo may be updated to use an IntentService.

iOS

Delphi implementation issues

Note: the issues described here have been fixed in Delphi 10.4. An update to the demo for Delphi 10.4 users is coming soon…

As per the previous article about location monitoring on iOS, the main issue is that using TLocationSensor “out of the box”, location updates do not occur when the application is in the background or the application is not running. The easiest way to solve this was to patch the System.iOS.Sensors unit, which uses code from the DW.iOS.Sensors unit to help manage the usage (e.g. When In Use and Always), background status (normal and significant changes) and activity (such as Auto and Fitness).

Applying the System.iOS.Sensors unit patch

The easiest way to apply the patch is with Codex, using the Source Patcher function:

If you have not already installed the Patch executable, there is a download link in the Source Patcher dialog:

After downloading/installing, you will need to change the name of the executable to something other than patch.exe (such as p.exe), as Windows thinks it is some kind of installer and will not run without elevated privileges.

Select the patch executable, source file, patch file, and destination folder, e.g:

The System.iOS.Sensors.10.3.3.patch file is supplied with the demo in the Patches folder

The patched code in the resulting file is indicated by comments beginning with // DW, so they’re easy to find.

Testing the demo

I would like to have done more testing on this demo than I have (so far), however it can be rather time consuming, since some of the “live” testing requires physically moving from place to place. I’d like to once again thank Atek Sudianto from Jakarta, for running this demo through its paces.

Android

Normally a device will not go into “doze” mode until a couple of hours of inactivity, when not connected to any charging source. This can make it difficult to debug since debugging normally requires the device to be plugged in to the computer doing the debugging, however I stumbled across a technique for “faking” doze mode. Long story short: it’s via an adb command, and I have now integrated this function into Device Lens:

As pictured, click the “minus” button to fake doze mode, and the “plus” button to restore it to normal.

To test the service starting at boot, either turn the device off, then back on again, or use the device’s reset facility. Shortly after the device starts, you should see the notification icon for the app (default is the Firemonkey icon) in the status bar. This is because the service has started in foreground mode, which requires a notification being displayed.

If you then start the application, you should see the notification icon disappear, because the service has exited foreground mode.

iOS

Location updates on iOS when the app is in the background or not running have been exceedingly frustrating (regardless of the issues in Delphi) ever since I’ve started using them. When first testing this new demo, I found that it did not appear to be generating updates, despite the device having moved significantly (more than 500 metres, apparently), then after a while (a day or so), location updates started happening (there were no code changes), without the device moving significantly.

I’d be interested to hear from others about their experiences with background location updates on iOS (using their own code or the demo from this article), so please feel free to leave a comment.

Looking to the future

I have been working on an implementation of location updates that uses FusedLocationProviderClient, however it has been left out for now due to time constraints.

I am also looking into solving the intrusive notification that shows when the service is in the foreground on Android. Indications are that a JobIntentService should be used, however as described earlier this is currently broken in Delphi, though I am looking into solving that issue, as well as investigation other methods.

Finally, hopefully the location services issues for iOS in Delphi will be solved in Delphi 10.4, removing the need to patch the Delphi source.

Expanding Embarcadero’s FCM implementation, revisited

$
0
0

Back in October last year, I wrote about integrating iOS support for FCM using Embarcadero’s implementation. In this article, I describe a revised demo that simplifies things and fixes a couple of issues.

STTP

The new demo can be found here. Please be aware that the ShowBannerIfForeground must be set to False if you don’t want a banner showing while the app is in the foreground, and that both data and notification elements must be present for Android push messages when the app is running, for everything to work as expected. See below for more details.

The new demo

The previous demo was basically just an expansion of example code presented by Embarcadero when their support for FCM (Android only) was introduced. The new demo encapsulates that code into its own unit, so all that needs to be done is to create an instance of the class (TPushNotifications) and assign a couple of event handlers.

The issues

Showing a banner when the app is not running

One of the main issues with the FCM implementation for Android is that a banner does not show when the application is not running, i.e. all that shows is the notification icon in the status bar.

The banner shows only if the Importance of the channel is set to High, so the startup code in TPushNotifications creates the channel, and sets the Importance to High. The channel id is extracted from the application metadata (in AndroidManifest.xml) using some code recently introduced into the Kastri Free library (DW.OSMetadata.XXX units).

Much larger issues

There are some extremely annoying quirks with FCM on Android, and I’m hoping I’m just doing something wrong and that someone can point it out, however from what I’ve discovered:

When an app is in the background (i.e. still running, but not in the foreground), in order for a notification to be received, the payload must contain a data element. However, if the app is not running at all, the payload must contain a notification element, otherwise no notification is presented.

In addition, when the app is in the foreground, no banner shows at all. To allow for this, I’ve updated the code to present a local notification, which will show when the ShowBannerIfForeground property of TPushNotifications is set to True. Note that this property applies to Android only, as it works on iOS.

Now all will work as expected, as long as messages sent to Android devices contain both a notification and data element (they can contain the same data).

Configuration

Remember to import your google-services.json file for Android:

..and to provide your Google-Services.info.plist for iOS (for the demo, it will go in the Resources folder)

Sending messages

I’m planning an article which covers creating a server which includes sending messages, however for now for testing you could use the standalone testing tool: PushIt.

As above, messages to Android devices should contain both a notification and a data element for everything to work correctly. Here’s an example payload:

{
  "to":"fDYt7NwXGyM:APA91bE_5ACVjyRubh3-s_kRD6Ig83LX8VKcsEFCxIfDemw49AIHudDGVQwnJ5r1UMlPBc2A2P6yrEZ6fbBsejrHaX5vQQ-RdpUbRiRk1UURknTDrJfMIMqkTZGd0mstxLWsMaI-pWjl",
  "notification":{
    "android_channel_id":"EMBTFCMv2",
    "title":"Testing.. 1..2..3..",
    "body":"FCM still rules!"
  },
  "data":{
    "android_channel_id":"EMBTFCMv2",
    "title":"Testing.. 1..2..3..",
    "body":"FCM still rules!"
  }
}

For iOS, there should be a notification element only.

Conclusion

I sincerely hope that I’ve missed something in regards to what needs to be in the payload to make things work as expected on Android, so if anyone can shed some light on the problem please let me know, however I do know that using the methods above works.

Fixing gesture “lag” near the screen edge on iOS

$
0
0

An enquiry I had from a Hans Jakobsen of EarMaster (brilliant music teaching software for PC, Mac, iPad and iPhone) recently was regarding an apparent “lag” for the OnMouseDown event for controls near the edge of the screen on devices with later versions of iOS. This article poses a workaround for the problem.

A description of the problem

Hans had already done some research about the issue, and came across this link, and he asked me to look into how to solve it in Delphi.

Implementing preferredScreenEdgesDeferringSystemGestures

Firstly, I needed to find exactly where to implement the changes. The article says that in order to indicate which edges should take “precedence” (over system gestures) in your app, the preferredScreenEdgesDeferringSystemGestures method needs to be “overridden” in the class that implements UIViewController. In the case of Delphi, this is TFMXViewController in the FMX.Platform.iOS unit. Fortunately, this class is declared in the implementation section, so the unit can be “patched” without having to recompile any other units. It was then a simple matter of adding the method to the FMXViewController interface and implementing it in TFMXViewController (see changes below)

Telling iOS which edges to prefer

Next up was how to determine what edges are “preferred”, so I used an old trick of defining a property that could be set outside of FMX.Platform.iOS, which that unit could then use. The DW.ScreenEdgeManager unit declares a record called TScreenEdgeManager, which has a private field FPreferredScreenEdges which is a set of the desired “preferred” edges. The private field value is set inside the SetPreferredScreenEdges method, and that method ensures that the changes are flagged in the system by calling setNeedsUpdateOfScreenEdgesDeferringSystemGestures. This indicates to iOS that the next time a system gesture happens, it will need to call preferredScreenEdgesDeferringSystemGestures on the view controller to discover which edges apply.

The setNeedsUpdateOfScreenEdgesDeferringSystemGestures (as per the article I linked to) method was added in iOS 11, and since Delphi has a bit of catching up to do with iOS API changes, a bit of “hackery” was needed to call this method as can be seen by the declaration of UIViewControllerEx and TUIViewControllerEx, which essentially “extends” UIViewController.

The demo

I’ve created a demo that uses the patch for FMX.Platform.iOS and the DW.ScreenEdgeManager unit to demonstrate how this works, and the difference between when there’s no “preferred” edges and where they are. Instead of creating a patch file this time, I’m detailing the changes you need to make. Copy FMX.Platform.iOS from the Delphi source\fmx folder into the demo project folder, and:

Add DW.ScreenEdgeManager to the implementation uses clause

uses
  System.Classes, System.SysUtils, System.Types, System.UITypes, System.TypInfo, System.Messaging, System.RTLConsts,
  System.Math, Macapi.ObjCRuntime, Macapi.CoreFoundation, Macapi.Helpers, iOSapi.CocoaTypes, iOSapi.Foundation,
  iOSapi.CoreGraphics, iOSapi.Helpers, FMX.Graphics, FMX.Consts, FMX.Controls, FMX.Canvas.GPU, FMX.TextLayout,
  FMX.Text, FMX.Styles, FMX.Gestures, FMX.Context.GLES, FMX.Forms3D, FMX.Utils, FMX.Graphics.iOS, FMX.Context.GLES.iOS,
  FMX.Controls.iOS, FMX.Gestures.iOS, FMX.Helpers.iOS, FMX.Dialogs.iOS, FMX.Platform, FMX.Platform.Timer.iOS,
  FMX.Platform.SaveState.iOS, FMX.MultiTouch.iOS, FMX.Platform.Metrics.iOS, FMX.Platform.Device.iOS,
  FMX.Platform.Screen.iOS, FMX.Platform.Logger.iOS,
  DW.ScreenEdgeManager; // <-------

Add the preferredScreenEdgesDeferringSystemGestures method to FMXViewController and TFMXViewController

  FMXViewController = interface(UIViewController)
    ['{FB1283E6-B1AB-419F-B331-160096B10C62}']
    // Some code snipped here
    function preferredScreenEdgesDeferringSystemGestures: UIRectEdge; cdecl; // <------
  end;

  TFMXViewController = class(TOCLocal)
    // Some code snipped here
    function preferredScreenEdgesDeferringSystemGestures: UIRectEdge; cdecl; // <------
  public

Add the implementation of TFMXViewController.preferredScreenEdgesDeferringSystemGestures

function TFMXViewController.preferredScreenEdgesDeferringSystemGestures: UIRectEdge;
const
  UIRectEdges: array[TScreenEdge] of UIRectEdge = (UIRectEdgeTop, UIRectEdgeLeft, UIRectEdgeBottom, UIRectEdgeRight);
var
  LScreenEdge: TScreenEdge;
begin
  Result := UIRectEdgeNone;
  for LScreenEdge := Low(TScreenEdge) to High(TScreenEdge) do
  begin
    if LScreenEdge in TScreenEdgeManager.PreferredScreenEdges then
      Result := Result or UIRectEdges[LScreenEdge];
  end;
end;

To see the effect of the changes, run the app on a device which (for example) has a “swipe” bar at the bottom, and tap and hold the button at the point where the swipe bar is. It might take a couple of tries, however you will notice that most of the time, there is a noticeable delay between when the button is tapped and the rectangle changes color. Now check the “Fix lag” checkbox and repeat the earlier steps. The rectangle changes color immediately, every time.

Introducing MonkeyBuilder

$
0
0

If you develop mobile apps for the app stores with Delphi, you’ll know that building and deploying a release is not a trivial task. MonkeyBuilder can reduce the time you spend from hours into just minutes!

Some MonkeyBuilder history

MonkeyBuilder is the brainchild of Graham Murt of Kernow Software. You may be familiar with his Pentire component library (formerly ksComponents), and his TksInputList component. He also has 3 mobile apps on the app stores, namely iFire, iRescue and iCrew. As you may have guessed, these are all emergency services related apps. Graham found he was spending a great deal of time in the build/deployment process, so he set about writing a tool that would allow him to automate the whole process.

During the development of MonkeyBuilder, Graham sought a way of retrieving certificate and provisioning profile information from the Mac, and asked about it on the Delphi Worlds Slack channels. Fortunately, I had already developed a means of doing just that in Mosco: an app that runs on the Mac that other apps can connect to and query information like certificates and profiles. So now a partnership has been born between myself and Graham to deliver MonkeyBuilder.

MonkeyBuilder is presently in beta

The first release of MonkeyBuilder is just around the corner, and to help us along we are calling for beta testers, so if you are interested, please use the contact form to let us know.

Visit the MonkeyBuilder website

The MonkeyBuilder website is also still under construction, however it has a couple of screenshots, a demo video (on the screenshots page), and the proposed pricing is also there, so please check it out.

It’s time to Get Excited!

$
0
0

The release of Delphi 10.4 Sydney is just around the corner. I’ve specifically been given permission to show updates and new features in the product, so let’s get to it..

Note: This is pre-release information

As such, any or all of it may change. Please check the What’s New when the product is officially released.

API enhancements and fixes

One of the things you may notice is that there have been fixes to existing APIs on macOS, and additions to APIs on macOS and iOS. In particular, there’s been a number of methods added to imports of Objective-C classes that developers have been asking for, such as for NSNotificationCenter and NSObject.

In Delphi 10.4 Sydney, the dependence on QTKit has now been totally removed – no more annoying warnings when uploading to the macOS App Store, and a couple of issues regarding permissions have now been solved.

Improvements to existing components

The implementation for TWebBrowser on macOS and iOS has now been migrated to use WKWebView. This means it now supports playing mp4 files from web pages that are navigated to, and there should be no more warnings when you upload your app to the store.

There are also improvements to TLocationSensor for iOS. 3 new properties have been added (all related to iOS only), namely:

  • ActivityType – this property corresponds the to the activityType property for CLLocationManager on iOS
  • UsageAuthorization – now you can specify what kind of usage is requested when starting TLocationSensor, i.e. Always and WhenInUse
  • OnLocationUpdatesPausedChange event – this notifies when location updates “paused” state has changed.

Also, you should now find that location updates occur when the app is in the background, or when the app is not running, as long as you include location in UIBackgroundModes in the Project Options.

..and much, much more!

The above mentioned changes are just some of many. Please check the blogs of other MVPs, and product managers like Marco Cantu, Sarina Du Pont and David Millington, for more news about Delphi 10.4 Sydney.


Introducing Kastri

$
0
0

Coinciding with the release of Delphi 10.4 Sydney, commercialization of Kastri has morphed into using Github Sponsors to help fund its development. This article details whats changed, whats new, and the future of Kastri.

Kastri Free

Be assured the Kastri Free repo will remain, however all new development will continue in the new Kastri repo.

Github Sponsors

There are 3 tiers of monthly sponsorship and any tier will help support and guarantee the future development of Kastri as well as contribute to enhancing the product as technology changes. All sponsors will have exclusive access to the #sponsors channel in the Delphi Worlds Slack Team where they can participate in making feature suggestions, highlight enhancements and best practices for how they use Kastri and other Delphi Worlds libraries in their development.

 Tier 1 – $5.00

Every developer knows that coding is fuelled by coffee. This level gives you the satisfaction of knowing you’re supporting Kastri and other repos, and allows us to stock the coffee machine. (Please note on Fridays this may go towards beer or a nice red.)

Tier 2 – $20.00

Aimed at those lone developers slaving away on their keyboards and use Kastri or any other repo for commercial purposes. Ideally you’ll have less than 100 users across your products.  Included at this level are 2 priority support incidents* per year.

Tier 3 – $50.00

Choose this tier if you are using my libraries or components in commercial applications and they provide a significant asset among your tools as a developer or organisation. At this level you receive 4 support incidents* per year

*Support incidents are related to the Kastri repo only. Details of how support incidents will be handled are being finalised.

Click Here to start sponsorship of Delphi Worlds

Supported Delphi Versions

Supporting older versions can be time consuming, however more importantly: Kastri revolves mostly around mobile development, and if you’re deploying to the app stores, staying current is essential. Kastri will now support Delphi 10.3 and above only

The New Repo

If you visit the new repo, you’ll find there has been a number of changes from Kastri Free.

  • New API import files – including some that will be used in upcoming features
  • Renamed/rationalized API import files – some imports have been aggregated, and some have had the file renamed to better reflect what is in it
  • ComponentHelpers (which really should have been named Interposers) has been removed and the files moved into Core
  • Some of the Demos that were in Kastri Free have not been migrated, because they’re not relevant to Kastri requirements, and some have been revamped (or will be)
  • New Features have been added, namely: Biometrics (TouchID/FaceID on iOS and Fingerprint support on Android), and Speech Recognition.
  • Files in the Java and ThirdParty folders have been reorganized
  • A new folder called Tools that will contain executables used for build automation etc.

Upcoming Features

New features are coming to Kastri, and your sponsorship will help make them a reality sooner. They include:

  • Photos library support – a platform agnostic means of managing collections of photos stored on the device, and a Facebook-style photos selector
  • Apple Login – implementation of Apple Login that adheres to the App Store guidelines
  • Universal Links – support for custom schemes and universal links on iOS
  • Camera – a revamp of the original Delphi Worlds Camera project, with support for iOS and Android

Delphi 10.4 Sydney

Kastri has already been tested with Delphi 10.4 Sydney, and is fully compatible.

Sponsor Today!

Click Here to start sponsorship of Delphi Worlds to ensure the future development of Kastri as well as contribute to enhancing the product as technology changes.

Codex 1.3, and other stuff in the works

$
0
0

If you follow the Codex repo, you would have noticed that version 1.3 was actually uploaded a couple of days ago. This article describes a what’s new and changed in Codex, and things I’m working on for Kastri.

Codex

Editor Tabs On Left

With the release of Delphi 10.4 Sydney came some changes to the IDE, which includes the StatusBar at the bottom of the code editor windows. Those changes in particular broke the “Editor Tabs On Left” feature of Codex. I struggled for a while to make them work again, however the best I could do so far is to have them appear on the left only if the macro toolbar that appears in the extreme left is hidden, and even then when the desktop changes (such as when debugging) it would all fall apart again, so I have shelved that feature in 10.4 for now.

ADB Connect

Codex 1.3 has a new feature: ADB Connect. This allows you to connect to an Android device over a network, as long as your machine can “see” the other address. The option is available via Tools|Codex|ADB Connect, or via the new Codex toolbar that you can enable by right-clicking the Delphi main toolbar and checking the Codex item:

In order to connect to a device via IP, first the device needs to be connected to a machine via a USB cable, then at a command prompt, run this command:

[path_to_adb]\adb tcpip 5555

Where [path_to_adb] is the path to the adb command on the machine, which means it will need to have at least the Android SDK tools installed (i.e not necessarily the whole SDK). This is all made simple via DeviceLens, which can help with installing the Android SDK tools, and actually run the command required to put the device into TCPIP mode:

Once the device is in TCPIP mode, you can use the ADB Connect feature to connect to the device:

The “configure for TCPIP” part could appear in a future version of Codex. ADB Connect was developed in response to being able to debug/monitor a device over a VPN, so the device may not even be in the same country as the machine that has Codex on it.

Total Clean

A menu item has been added to the Project Manager context menu called Total Clean:

This option will remove all files in the projects output folders for every platform as well as the folders themselves (if it can), so please use it when you’re absolutely sure that’s what you want to do.

In the works for Kastri

As per the last article, there are a number of things planned for Kastri. Becoming a Github Sponsor will help make these a reality. I’m currently working on:

Apple Signin support

As per Apple’s guidelines, if you offer login via any of the major social media providers, you must also offer login via Apple Signin (this has applied since April 2020). I have an implementation in testing phase, so if you’re interested in helping out, please join my Slack team and go to the #kastri channel.

Camera for Mobile

A while ago I published this project, which implements the device camera using the newer Camera2 API on Android. I had plans to add iOS support when I started it, and actually had a private project that did implement it on iOS, however I shelved all of it due to time constraints. When joining Github Sponsors, I figured I should include features that would help encourage developers to sign up for sponsorship, so I have resurrected the camera project to be part of Kastri.

Some of the work has been done, including having the camera preview take advantage of the native view implementation included in Delphi so that it has z-order support, e.g. you can have the preview on a tab of a tab control, and switch tabs without having to turn off the preview. Also, because it uses native classes for the preview, performance is way above that of the built-in camera component in Delphi

Other items in the works

These items are planned:

  • Photos library that makes use of the Photos framework on iOS, and has implementation for Android
  • Universal Links support on iOS
  • Background Task management for iOS
  • Background Fetch for iOS (improved version)
  • Sensors (using the OS APIs)

All items currently in the works or planned have a much better chance of becoming a reality and potentially sooner with sponsorship, so please consider becoming a sponsor today!

 

Using a prior iOS or macOS SDK with Delphi

$
0
0

When a new version of Xcode comes out, invariably there is only one SDK for iOS and macOS included. As is Apple’s way, sometimes they change something in the new SDK that breaks the SDK import in Delphi. This article describes a couple of solutions for it.

The problem

The typical scenario is: you start a completely new install of Delphi, either because you’re a new user, or you like to start a new installation with a new version. You install Xcode on the Mac (or already have), and you go to import the SDK in Delphi, using Tools|Options, Deployment > SDK Manager.

At the time of writing, the latest released version of Xcode is 11.6. In Delphi’s SDK Manager you go to import the iOS SDK, and the only SDK available is iOS 13.6. You select that, import the SDK, then attempt to compile an iOS application. Unfortunately you are greeted with:

ld: file not found: /usr/lib/system/libcache.dylib for architecture arm64
[DCC Fatal Error] F2588 Linker error code: 1 ($00000001)

This is because Apple have changed what is distributed with the iOS 13.6 SDK. In the SDK folder (/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.SDK). The /usr/lib/system folder underneath simply does not exist. (I will update later as to why this is, since I am yet to find out).

So what can you do about this? If you have access to an installation of Delphi where the iOS 13.x SDK (preferably iOS 13.5) had been imported, the solution may be relatively trivial.

Solution 1

By default, SDKs are imported into C:\Users\[username]\Documents\Embarcadero\Studio\SDKs (where [username] is the login name for that computer.) You could:

  • Copy the iPhoneOS13.5.sdk folder from the SDKs folder on wherever the other Delphi installation is, to corresponding folder of the machine of your new installation
  • Export the HKEY_CURRENT_USER\Software\Embarcadero\BDS\21.0\PlatformSDKs\iPhoneOS13.5.sdk (21.0 = Delphi 10.4) registry key from that machine, and import it into the registry of the new installation

Solution 2

Only if you’re unable to use Solution 1 (hint: another developer may be able to help you out), you may consider downloading an older version of Xcode so that you can obtain the older SDK. Older versions of Xcode can be downloaded from here. (you may need to sign in). You could:

  • Download Xcode 11.5, and extract it somewhere on your Mac, other than in the Applications folder where the current version is.
  • Open a Terminal window on the Mac (/Applications/Utilities/Terminal), and enter the following:
    sudo xcode-select -s [path]/Xcode.app

    Where [path] is the path where you extracted the older version to.

  • In Delphi, you should now be able to import the iOS 13.5 SDK. Once you have, you can execute the following command to switch Xcode back to the default:
    sudo xcode-select -r

    Alternatively, you could not execute this command and work with Xcode 11.5 being active for as long as is practicable.

macOS SDKs

The above solutions may well work similarly for macOS SDKs if you’re stuck in the same situation.

 

Manual install for Android SDK/NDK in Delphi

$
0
0

If, for whatever reason, you want to set up the Android SDK/NDK (perhaps there was a failure during your Delphi install), the manual process can be a little involved. This article lays out the steps which includes using an AndroidSDKInstaller app that makes life a little easier.

In Case You Missed It

RAD Studio 10.4.1 has been released recently! I may do my own post about what is included, however I recommend checking the blog roll on the right hand side of this page, as well as your own favourite blogs and newsfeeds.

Jim McKeeth’s Android SDK/NDK article

Last year, Jim McKeeth wrote this excellent article which describes how to install the SDK/NDK manually, so you may wish to read that first, however there’s some manual steps that can be done via the command line that I’ve automated in the installer.

Install the JDK

As per Jim’s article,  the first step is to install a JDK. You will need to install it in order for the AndroidSDKInstaller app to work, if you are going to use it. You can choose the AdoptOpenJDK, or you can still install the JDK from Oracle – please use the Windows installer for your system (x86 if 32-bit only, or x64 if 64-bit) at the bottom of the Java SE Development Kit section.

Using AndroidSDKInstaller

Once the JDK has been installed, you can use the AndroidSDKInstaller that has been built to ease the process of installing the Android SDK tools, build-tools and platforms. The installer has been purpose-built to provide the minimum required to use with Delphi.

When running the installer, click the Download button to download the SDK tools. I recommend creating a folder dedicated to where the SDK and NDK will end up being installed. In this example, I’ve created a folder called Android, and a subfolder called SDK where the SDK tools will be downloaded to, and also where the build-tools and platforms will be installed:

Once you’ve selected the SDK folder, the installer will then download and extract the SDK tools, and retrieve the packages available for install. The Select SDK button can be used in the case where you have an existing SDK, and just want to install extra build-tools and/or platforms.

Once the installer has retrieved the lists of packages, it will then look like this:

As can be seen, Platform Tools is checked by default – Delphi requires these in order to function. You have a choice of Build Tools and Platforms that you can install, however it is recommended just to install those that will work with your installed version of Delphi. In Delphi 10.4.x, I recommend using build-tools version 29.0.2, and platform android-29. Once you have selected the build-tools and platform, click the Install button:

The installer will inform you when it has finished. Click OK, then click Close

Installing the NDK

As per Jim’s article, the latest NDK can be downloaded from here, however it is recommended that you use a version that is known to work. In the case of Delphi 10.4, NDK version r21b is known to work. Older versions such as this one can be downloaded from here.

Following on from the example above, I recommend extracting the NDK to a folder called NDK, at the same level as the SDK:

Adding the SDK/NDK in Delphi

For this step, I’ll refer back to Jim’s original article, rather than just repeating it. Please see the section “Setting Up The IDE SDK Manager”, remembering where you installed the SDK/NDK as per the instructions above.

Important information about the NDK settings

If, like me, you happen to be targeting devices including those that have older versions of Android (some of them have Android 4.4!), you will need to make a couple of tweaks to the NDK settings. These are:

  • NDK API Location
  • C++ Builder NDK Library Path (not essential if you are not using C++ Builder, however included here for completeness)
  • Delphi NDK Library Path

As per the following screenshot, I have changed the platform level for each of these settings to android-19. This is the lowest API level supported by the native code in the resulting Delphi application, and corresponds to Android 4.4:

A complete list of released Android versions and their API levels can be found here.

Conclusion

That should cover all of the steps. If I’ve missed anything, please let me know in the comments. Hopefully the AndroidSDKInstaller app makes this process a lot easier for you!

Book Review: Coding Faster In Delphi

$
0
0

The guy next door to me.. well, almost; Alister is in NZ, wrote this book called Coding Faster In Delphi, I was actually invited to review it before publishing, however time once again had the better of me. Now I have had some time to take a peek, and I must say, I am impressed!

This book is extremely well thought out, and focuses on many aspects of how you may code faster in Delphi. Did I say many? Everything related to boosting your productivity is covered!

Speed Typing

I must admit that I skimmed a little over the part about speed typing. I’m a bit of an “old dog” when it comes to that, however no-one is exactly the same, so if you think you could do with some improvement in this area, please pay attention

Keyboard Shortcuts

One part that does deserve plenty of attention is Keyboard Shortcuts, and I intend to memorizse these because it’s something I have sadly neglected over the years. Alister lays out all the important ones that will help save you oodles of time.

Lesser Known Features

Alister also describes in detail many features that maybe could do with more exposure than they would otherwise receive. These include things like Sync Edit, Macros, Templates, Surround, and more.

Topic Summary

Here’s a quick summary of the topics (not exhaustive; there is more!):

Touch Typing
Code Editor Keyboard Shortcuts
CodeInsight (actually, Code Completion)
Code Templates
MultiPaste
The Editor Toolbar
IDE Insight
Structure View
Class Explorer
Code History
Macros
Surround
SyncEdit
Form Designer Keyboard Shortcuts
Quick Edits
Quick Actions
Object Inspector
Structure View
Component Palette
Editing Form Source
Alignment
VCL Guidelines
Customising the IDE
Write Your Own IDE Plugin
Language Features
Interfaces
Generics
Inline Variables
Parallel Programming
Multiple Threads
Regular Expressions
Enhanced RTTI
Third-Party Tools
Metaprogramming
Mida Converter
Physical Environment (eg Hardware, Chair, Desk, and more!)
Environmental
Interruptions
Multitasking
Asking Questions
Social Networks

Once again, this is an excellent book and one you would do well to have in your arsenal. Please visit the site, order now and start Coding Faster!

Memorizor: A showcase of Delphi and Kastri

$
0
0

Over the past few years, I have been helping others with writing their mobile apps, or some parts of their apps where they have called on my expertise to do the implementation. I am happy to announce that I have published a mobile app that I can truly call my own: Memorizor.

A showcase of Delphi and Kastri

I actually started Memorizor just under 3 years ago, however because it was a personal project it received less attention than it otherwise should have. After releasing Kastri a few months ago and starting to seek sponsorship for the project, I felt it was time to put together a showcase of some of the current features of Kastri as well as giving a preview of what is in the works, so I chose to resurrect Memorizor because it was the perfect candidate.

What is, and isn’t, in Memorizor

As above, Memorizor makes use of some of the current features of Kastri, and some that are to be released in the future. Of the current features, It includes a number of units from the API and Core folders, as well as the Speech Recognition feature. Some of the “to be released” features include:

  • Implementation of the native AlertView on iOS. The released feature will contain support that mimics the AlertView, for other platforms.
  • Native image controls
  • Native camera support
  • Image zoom/pan

The rest is all “out of the box” Delphi. Some of the notable parts of Delphi that are used:

  • Local Notifications
  • LocationSensor
  • TMapView
  • ListView with dynamic appearance
  • FireDAC (just TFDMemTable)

Some challenges

As any seasoned Delphi developer (or perhaps any developer, for that matter), some things do not go to plan. There were a number of issues that I needed to work around, and have decided to list them here:

The ComboBox challenge

The last one in the list above deserves an expanded explanation: some developers suggest using a workaround where the ItemIndex is stored before the combo “drops down”, and when the combo “closes up”, check the two values, which works for most situations, but not for mine. In Memorizor, on the Reminder screen (where the “remind mode” can be changed), if the user taps the combo that is “blank”, the first item in the combo is selected (thus no longer “blank”) and the picker appears. The user might then change the value to something else, however they may decide to tap Cancel anyway. This means the value before and after the selection are different, however the user tapped Cancel, so the value should not be applied. Long story short, I defined a new message class: TComboBoxCancelMessage, and patched FMX.Pickers.iOS.pas to send an instance of that message if the user taps Cancel.

Permissions challenges

Requesting permissions for access to device resources has become an everyday thing now, however it can become annoying when an app confronts you with a barrage of permissions requests. In Memorizor, I have paid strict attention to delaying requests for permission until they are absolutely needed.

When implementing Local Notifications, I noticed something a bit odd – I was delaying creation of TNotificationCenter until it was actually needed, however it did not seem to matter: the permissions request would appear always as soon as the app started. The answer is that in FMX.Platform.iOS, in the TApplicationDelegate.applicationDidFinishLaunchingWithOptions method the code checks for whether the app has FMLocalNotificationPermission set to true in the Project Options, and calls TiOSHelper.SharedApplication.registerUserNotificationSettings which prompts the user to grant permissions – that’s why it happens at startup. The solution was to set FMLocalNotificationPermission to false, and do that part myself in my own code, when it actually needs permission. 

For things like access to camera, speech recognition, and locations, these were relatively easy to defer the request until absolutely needed, however you should still be mindful about it.

Other challenges

As I have been writing this, I realise that there were actually quite a number of challenges to overcome. Most had nothing to do with issues in Delphi itself; just regular scenarios where more effort was needed than first realised. I’ll store them away for now, for appearance in future articles.

Android version

Now that the iOS version has been published, I’m working on completing the Android version, which brings its own set of challenges. I plan to have that available by mid next month.

Thanks

I’d like to thank my current sponsors, those who used the Paypal tip jar (in the top right of this page), those who tested Memorizor for me, and of course to Embarcadero for their amazing development tool Delphi, all for their help in making this possible.

Conclusion

This has been a long road, however I have laid the foundations with Memorizor which should make it easier for me to do add new features, and to be able to build the next app. It has also boosted my own appreciation of the work I’ve put into Kastri. I hope that what can be seen in Memorizor encourages you to take another look at Kastri and consider becoming a sponsor to help continue its enhancements and new features.

Native Camera for iOS and Android

$
0
0

A few years ago I started a project for native camera support for Android using the Camera 2 API, partly because the built-in camera support for Delphi was underperforming greatly. I have resurrected the project, added support for iOS, and it is now included in Kastri.

Existing camera support in Delphi

As many of you are probably aware, the existing camera support in Delphi is not very performant, especially on Android. Erik Van Bilsen of Grijjy has provided some hints and workarounds to increase performance, however it still has a way to go.

Camera support in Kastri

Camera support in Kastri builds on the original standalone camera project, and adds support for iOS. On both platforms, instead of using the built-in camera app on devices, native APIs are used. Native controls are also used for displaying the camera preview, so the result is an huge improvement over the existing support in Delphi.

Some caveats

Please be aware that this is a “first release” of camera support. It provides basic turn on/off of the preview, capturing of a still image, and inclusion of location metadata. Other features will be added over time, including:

  • Face detection – some of the code is already present; it just needs to be finished/tested
  • Providing a list of supported resolutions
  • Flash mode on/off
  • Focus control

etc. Developers are welcome to contribute to these enhancements, and sponsorship of Delphi Worlds on Github helps make new features a reality.

Also be aware that the Android support requires Android 6.0 or greater, and  iOS support requires iOS 10.0 or greater.

Demo

The demo for camera support is here, and is dependent on the Kastri library. When you run the demo you may note that when it is in preview mode, there are controls that appear above the preview. These are image controls that use native APIs to display the images, which makes it possible for them to overlay the native preview control. At present, these controls are created at runtime, however the plan is to change them into components that can install into Delphi.

Switching the Include Location switch starts the location sensor, and will prompt for permissions. Tapping the Start button starts the camera preview. Tapping the Camera button in the middle at the bottom captures an image. Tapping the Swap Camera button in the bottom right changes between front and back cameras.

Once an image is captured, tapping the green Accept button in the top right takes you back to the start, and fills the image control with the captured image. Tapping the red Cancel button in the top right takes you back to the start without filling the image control.

Capturing an image, and Including location metadata

When capturing a still image, the image data is returned in a stream, rather than a bitmap. This is so that metadata can be included, because bitmaps do not have metadata. If you wish to include location data in the image, set the IncludeLocation property of the TCamera instance to True, and before the still is captured, set the Location property to the current coordinates.

You can use Delphi’s TLocationSensor to obtain the users location. Remember that it takes a few seconds for the first location event to fire, start the sensor well before the user is able to capture an image. Please use the demo as a guide.

Remember also that when assigning the image stream to a bitmap, the location data will be lost in the bitmap, as it does not store it.

Note: For Delphi 10.4 and 10.4.1 users, if you wish to use location services on iOS, you will need to patch the System.iOS.Sensors unit as per this report, in order for it to work properly.


Apple Patch for Delphi has been “re-patched”!

$
0
0

Last month Embarcadero released a patch for Delphi that fixes a few issues with support for Apple OS’s (iOS and macOS). Now there’s a new patch that addresses additional issues.

Marco Cantu from Embarcadero has written this article that describes the details. however there’s a couple of pertinent details to be aware of.

One is that the patch contains the old version of PAServer. The new PAServer (version 21.1.10.5) is available here.

Here’s some of the issues that the new patch addresses:

https://quality.embarcadero.com/browse/RSP-31795 – Linker fails with iOS 14.2 SDK when using TClientDataset
https://quality.embarcadero.com/browse/RSP-31766 – Weak symbols not recognized in macos 11/iOS14 SDK
https://quality.embarcadero.com/browse/RSP-31746 – Linker error after new iOS 14.2 update

More importantly, for any of these issues you’ll need to re-import the iOS SDK. Here’s the steps:

On the Mac, in the ~/PAServer/scratch-dir folder, delete any folders starting with cache-dir:

On the Windows machine, delete the existing iPhoneOS.14.x.sdk folder, e.g:

In SDK Manager in Delphi, click the Update Local File Cache button:

Now for the issues that this patch solves, your Delphi application should compile!

 

 

Codex 1.4 released

$
0
0

It’s been a while between posts.. let’s restart with a new version of Codex!

Codex 1.4 (Embarcadero Delphi IDE add-in)

This release has a couple of fairly substantial changes, namely:

  • Source Patch – Create and apply patch files for Delphi source, with just a couple of clicks
  • IDE Path Sets – allows quick changes to IDE search paths. Useful when working on multiple projects that use IDE paths, but where some may result in unit name collisions

It also has some enhancements and bug fixes – please check the history in the readme.

As usual, the installers are in the Bin folder of Codex. Unfortunately, due to my Delphi 10.3.3 install “dying” recently, this release is (at least for the time being) for Delphi 10.4.x only.

I have decided to retire the original documentation page in favour of the readme in the repo.

Delphi Patches

The Source Patch feature in Codex 1.4 coincides with the start of a Github repository called Delphi Patches.

Delphi Patches is a repository for patch files that solve particular issues with Delphi. Using the Codex Source Patch features, patches can be applied with ease.

Others are encouraged to contribute to the patch files by creating a pull request, or just send the patch to me, and I’ll consider including it!

Please refer to the Codex readme and the Delphi Patches readme for more information.

 

Pluses and pitfalls of cross-platform development with Delphi

$
0
0

Every now and then there’s a post (on Stack Overflow, Delphi Praxis, Facebook etc) asking about developing cross-platform (usually specifically mobile) apps with Delphi, for example the “current state” of the product and whether there’s anything they should be aware of. This article details some of the things to be aware of when choosing Delphi.

Why Delphi? (aka the “Pluses”)

This part of the topic has probably been “done to death”, so I’ll just summarize the main points:

  • Cross-platform support for macOS, iOS, Android, Windows and Linux
  • Implementation of functionality using a number of frameworks is done for you
  • Compiles to native code
  • Single source
  • The timeliness of support of platform changes is improving, over time

The 2nd point needs a little expansion:

In Delphi, in the RTL and FMX, Embarcadero has made a monumental effort to implement functionality that developers using Android Studio and Xcode (for example) would have to implement themselves, or find third party code that does it. For example (and these are just a few):

  • TAddressBook
  • TLocationSensor (and other sensor components)
  • TCameraComponent
  • TBannerAd
  • TBluetooth

Also bear in mind that many implementations are done for all platforms. Admittedly, they’re not perfect (is anything?), however this saves developers many, many hours in development time, and some tend to take this for granted.

For most developers, what is provided in Delphi out of the box most of the time is close to meeting their demands for cross-platform development.

Things to consider (aka the “Pitfalls”)

Issues

As I indicated above, the cross-platform implementations are not “perfect”, and there may be times when they need “tweaking”. Occasionally I will blog about a tweak, or I will publish code in the Kastri library, that fulfils the need. Other good sources for finding tweaks etc are on StackOverflow, Delphi Praxis, the Delphi Developer Facebook group, and Embarcadero’s Quality Portal.

Implementing frameworks or functionality that is not included in Delphi

There may also be times when you want to use a particular framework or functionality that is not implemented in Delphi. There may be an implementation done for you in Kastri, on Grijjy, in Loki’s Alcinoe project, or other sources. If there is yet to be an implementation for Delphi, perhaps you might seek my services? I have a Slack workspace that you can invite yourself to, so you can ask!

Implementing functionality that is yet to be possible in Delphi

A particular example of something that is yet to be possible in Delphi is implementation of descendants of Java classes. In some cases it is required that you to create a descendant of a particular class and override one or more of its methods, then pass an instance of that descendant to the method of a class that uses it. I’ll leave the discussion of how this can be done for another article, and/or you can leave a comment if you are curious.

Another example is the use of iOS app extensions. There is a way of using iOS app extensions from Delphi, however currently the extension itself must be developed in Objective-C using Xcode. If this takes your interest, there are articles here and here that cover the subject.

iOS simulator support

In the past, Delphi had support for compiling for iOS simulator. When Apple changed to having only 64-bit versions of the simulator, this all changed. There are plans to re-introduce simulator support in Delphi.

Conclusion

As indicated above, for most developers, pretty much all of their needs are catered for when developing cross-platform for Delphi. They can take comfort in the fact that Embarcadero are committed to expand the development of Delphi, and that there’s a thriving community to support them also. Developers are proving time and time again that Delphi is still an excellent choice. Here are some references that may help encourage you about what you can do with Delphi (particularly for mobile):

Memorizor (my own app!)

PushIt (also my own app) one you can modify yourself if you wish

Kiskis dating app (built using Alcinoe code) on the App Store and Google Play

Idle Western game

 

Travel app design (Indonesian)

Camera surveillance app (from 6 years ago!)

Nassau St – Stock Portfolio Management app

VRTool  – Sailing Charting

CamSextant – AR enabled celestial navigation

These are just a few mobile apps built with Delphi.. A more definitive list is being compiled that I’ll share in the future.

Taking it to 11…

$
0
0

Delphi 11 Alexandria has landed! In this article, I’ll highlight a couple of the new features, introduce some changes related to the Kastri library, and make a pre-announcement about Codex.

Introduction

As per the headline, I’ll be examining a couple of the new features of Delphi 11. For more complete information, please visit the Embarcadero Blogs, and Marco Cantu’s Blog

API level 30 support

A Google Play store requirement is that from August 1st, new apps must target API level 30. Delphi 11 now gives full support for API level 30.

Full AndroidX (aka JetPack) support

This is a major change for Delphi, which now makes possible (previously close to “impossible”, see the “A word..” section, below) implementation and/or updates of some key features. One of those features is Biometric support across all supported versions of Android. Yes, there are direct Biometric APIs, however these require an API level 29 (Android 10) device or higher. Another is Firebase Analytics, which requires a later version of the Play Services libraries (which Delphi 11 now uses) that depends on AndroidX.

In App Purchases supports the new Billing API

From August 1st this year, new apps that use Google Play Billing are required to support at least v3 of the Billing API. Some good news is that v4 is already supported “out of the box”. Even better: there is no need to change any of your code!

FMX TWebBrowser now supports Edge

Delphi 11 introduces long awaited support for Edge browser, and it is implemented similarly to the TEdgeBrowser component in the VCL, however of course you can use the FMX TWebBrowser on any platform; just that now: Edge is supported on Windows.

Important Breaking Change

There’s a couple of “breaking” changes to Delphi 11, however this one is going to be very visible if your applications request permissions at runtime using PermissionsService: The types of the parameters for permissions handling methods have been changed to better support C++Builder. Namely,

  • TRequestPermissionsResultEvent
  • TRequestPermissionsResultProc
  • TDisplayRationaleEvent
  • TDisplayRationaleProc

For the relevant type of methods/procedures, the APermissions parameter has changed from TArray<string> to TClassicStringDynArray (which is an array of string) and the AGrantResults parameter has changed from TArray<TPermissionStatus> to TClassicPermissionStatusDynArray (which is an array of TPermissionStatus).

Changes to Kastri

Supported versions

In line with the policy regarding supported versions of Delphi, Kastri now “officially” supports Delphi 11 and Delphi 10.4.2. That simply means that fixes are much less likely to be considered for earlier versions.

Change related to the “Important Breaking Change”, above

In order to support both Delphi 11 and Delphi 10.4.x, I have changed the DW.Permissions.Helpers unit to declare types that are compatible with each version. This means that you can use TPermissionArray and TPermissionStatusArray types and your code will compile for either version.

Updates to jars, demos

Due to the addition of full AndroidX support in Delphi 11, there were changes necessary for some of the existing jars that use the Android Support APIs. These have been updated to use AndroidX, and have a suffix of 2.0.0 (e.g dw-kastr-base-2.0.0.jar). Jars with this suffix can be used only in Delphi 11 (or higher). Demos that use these jars now have an additional project that has the name suffixed with D11, e.g. ConnectivityDemoD11.

Features coming soon

With the introduction of full support for AndroidX, it’s now possible to implement some key features, as mentioned above.

Firebase Analytics support will soon be added to Kastri. This means that events such as from Firebase Cloud Messaging will now be included automatically, as well as giving developers the opportunity to log custom events.

Previously Kastri had support for fingerprint only biometrics on Android. Coming soon is support for the Biometrics API, which includes any biometric feature implemented on the OS, such as Face ID.

Note that the above feature changes (aside from Firebase Analytics on iOS) apply to Delphi 11 only – the features are not available for Delphi 10.4.2

New imports

Some new features required imports for the relevant APIs, so they are now included, and are in the API folder.

More coming!

Working on the changes/features related to Delphi 11 means that some other upcoming features needed to take a back seat, e.g a simple implementation for Google SignIn, expansion of the Native Controls suite, and improvements to Camera support.

Codex update

Speaking of more coming: an update to Codex is close to ready. Version 1.5 will support Delphi 11 Alexandria and Delphi 10.4.x Sydney. A separate article announcing Codex 1.5 will follow this one.

Please consider sponsorship

All the changes/updates to Kastri (and other related projects) rely solely on sponsorship, so please consider becoming a Github sponsor of Delphi Worlds today!

A word about AndroidX and earlier versions of Delphi

As mentioned above, being able to take advantage of some features available in AndroidX in earlier versions of Delphi (e.g 10.4.2) would have been close to “impossible”.

It might seem simple: if you want to use a feature in a particular library, you just import the APIs, write your code, and add the library to the Libraries node in the Android platform target, or if the library is a later version of a package already used by Delphi, you disable the older one, and add the newer one. The problem is with dependencies, i.e. the new library may be dependent on newer versions of other libraries that Delphi already uses.

You might then think, OK.. I will just update those too. New problem: existing FMX code may rely on the older versions. The problem then shifts to having to update all the relevant code to comply with the newer version. Some of it may be Delphi code, some of it may be Java code, and the latter means needing to be competent enough with Java, making the changes, recompiling fmx.jar and replacing the old one.

Not exactly “impossible” (hence the quotation marks), however it could amount to a lot of work, which would need to be maintained with future changes.

How deep might the rabbit hole go?

Conclusion

It bears repeating: especially if you’re going to target cross-platform, it is essential that you stay current, so make sure you “take it to 11” with Delphi.

Announcing Codex 1.5 and Mosco 1.2

$
0
0

Corresponding with the release of Delphi 11 Alexandria, today also marks the release of Codex 1.5 and Mosco 1.2

Codex 1.5

Codex has been revamped a little in version 1.5, and introduces some new functionality:

Mosco Expert functions

The functionality that was present in the now discontinued Mosco Expert has now been merged into Codex – see the section below about Mosco 1.2

Option for enabling the Read Only editor popup menu item

Overcomes this long standing issue where the Read Only item cannot be changed because it is disabled when the source file itself is read only!

Suppress Build Events warning (Delphi 11 only)

Automatically marks your project as being “safe” for build events, preventing the warning that otherwise has no option to turn it off.

Single-click Welcome Page options (Delphi 11 only)

There is a known registry “hack” to enable all items in the Welcome Page to have links that are “single-click”, however the option in Codex does not rely on the “hack”, and gives you more granular control over which items can be single-click.

Other improvements

Please refer to the Codex readme for the above and other new items and changes to Codex 1.5

Mosco 1.2

Mosco is an app for macOS, which Codex can communicate with (rather like Delphi does with PAServer) to perform various tasks in Delphi, however Mosco also performs a number of other useful functions on its own. Note that Mosco 1.2 is the full version of Mosco, is yet to have integration with MonkeyBuilder.

Please refer to the documentation about how to install/use Mosco

 

Viewing all 80 articles
Browse latest View live