Sharing Data with Remote Applications Using App Tethering

From RAD Studio
Jump to: navigation, search

Go Up to Using App Tethering


The app tethering implementation of the RTL provides support for sharing data between connected applications.

Sending Data to Connected Applications

You can use any of the following approaches to send data using app tethering:

  • Define shared resources. A resource wraps a value. Connected applications can read the value of a shared resource, and subscribe to a shared resource to receive updates when the value of the shared resource changes.
  • Send data as a temporary resource. You can send strings and streams at run time that connected applications receive as temporary resources. Connected applications cannot subscribe to temporary resources for updates, as your application only sends temporary resources once.

Sharing Resources

A TLocalResource is a wrapper around either a standard data type (Boolean, Integer, Int64, Single, Double, String) or a TStream. You can share resources with connected applications using app tethering.

To create and share a resource:

  1. Select your TTetheringAppProfile component on the Form Designer and double-click its Resources property on the Object Inspector.
  2. On the list editor that opens, click New to add a new TLocalResource to the list.
  3. With your new TLocalResource selected on the list editor, give a unique value to its Name property on the Object Inspector.
TLocalResource Editing.png

Your resource is now shared using app tethering. Connected applications can read the value of this resource and subscribe to the resource for updates, so that when the resource value changes in your applications, connected applications are notified of the change and can read the new value.

After you define your resource at design time, you must give your resource a value at run time:

  • In Delphi:
    • TetheringAppProfile1.Resources.FindByName('ResourceName').Value := 'SomeValue';
    • TetheringAppProfile1.Resources.Items[ResourceNumber].Value := 'SomeValue';
  • In C++:
    • TetheringAppProfile1->Resources->FindByName("ResourceName")->Value = "SomeValue";
    • TetheringAppProfile1->Resources->Items[ResourceNumber]->Value = "SomeValue";
Where:
  • ResourceName is the name that you enter in the Name property of the resource when you create it at design time.
  • SomeValue is the value that you want to give to the resource. This value can be of any of the standard data types listed above.
  • ResourceNumber is the number of the item in the Items property of the TResourceCollection when you create it at design time.

To work with streams as resources:

  • TetheringAppProfile1.Resources.Items[1].Value := LMemoryStream;
  • LMemoryStream.Free;

The code immediately makes a full copy of the source stream. The original stream (i.e. LMemoryStream) can be therefore immediately destroyed.

Connected applications may request the value of your shared resource at any time and subscribe to your shared resource for updates, so that when you change the value of the resource, subscribed remote application profiles receive the updated resource.

Sending Data as a Temporary Resource

Instead of sharing resources, you can use the SendString and SendStream methods of your TTetheringAppProfile component to send strings or streams to connected applications.

Remote application profiles receive the value wrapped in a temporary resource. A temporary resource is a resource that your application profile sends to connected applications only once. This temporary resource is deleted afterwards; connected applications cannot subscribe to this resource for updates.

These method expects the following parameters:

  • AProfile is a remote application profile as an instance of TTetheringProfileInfo. The RemoteProfiles property of your TTetheringManager component provides a list of remote application profiles that are connected to your profile; you can browse this list to find the remote application profile that you want.
  • Description is a string that describes the content of the value that you send.
  • AString or AStream is the value to send.

If you want to send standard data types other than String using temporary resources, you must convert them to strings before you send them, and convert them back to their original type on the connected application that receives the string. See JSON.

Receiving Data from Connected Applications

Your application may receive a resource either because the remote application profile sends it or because you request it. You can handle any incoming remote resource using your TTetheringAppProfile component.

You can also subscribe to a remote resource for updates. When the value of the remote resource changes, your application is notified about the change and receives the new value of the remote resource. Alternatively, if you use groups to connect to remote applications, you can use local resources to subscribe to remote resources and define separate methods to handle updates to each one of the subscribed remote resources.

Requesting Remote Resources

Your TTetheringAppProfile component provides a method, GetRemoteResourceValue, that you can use to request a remote resource.

You can specify a remote resource to request with either of the following sets of parameters:

  • Provide the remote application profile that contains the remote resource as an instance of TTetheringProfileInfo and the name of the remote resource.
The RemoteProfiles property of your TTetheringManager component provides a list of remote application profiles that are connected to your profile.
Your TTetheringAppProfile component provides a method, GetRemoteProfileResources, that returns a list of remote resources shared by a given remote application profile specified as an instance of TTetheringProfileInfo.

Handling Incoming Remote Resources

Your TTetheringAppProfile component may receive remote resources for any of the following reasons:

  • A remote application profile sends a temporary resource.
  • You request a remote resource.

When your TTetheringAppProfile component receives a resource, two events of the TTetheringAppProfile component occur in the following order: OnAcceptResource and OnResourceReceived. To handle incoming resources you must handle these events.

OnAcceptResource Image.png

Accepting or Rejecting an Incoming Remote Resource

You can handle OnAcceptResource to determine whether or not you accept a given incoming resource. This event provides the following parameters:

  • Sender is your TTetheringAppProfile component that is about to receive the incoming resource.
  • AProfileId is the ProfileIdentifier of the remote application profile that sends the resource. The RemoteProfiles property of your TTetheringManager component provides a list of remote application profiles that are connected to your profile; you can browse this list to find the remote application profile that matches the specified profile ID.
  • AResource is an instance of TCustomRemoteItem that contains properties that you can read to determine whether or not you accept the incoming remote resource, such as the Name of the resource or a Hint that describes its content.
  • AcceptResource is a boolean value that is True by default. You can change this value to False if you do not want to receive the incoming resource.

Reading an Incoming Remote Resource

If you do not handle the OnAcceptResource event or if you do not change the value of AcceptResource to False in your event handler, the OnResourceReceived event occurs. You can handle this event to read the data from the resource. This event provides the following parameters:

  • Sender is your TTetheringAppProfile component that is about to receive the incoming resource.
  • AResource is an instance of TRemoteResource. TRemoteResource extends TCustomRemoteItem with two properties that give you access to the actual value of the resource:
    • TRemoteResource.ResType indicates whether the resource contains a standard data type (TRemoteResourceType.Data) or a TStream (TRemoteResourceType.Stream).
    • TRemoteResource.Value provides access to the value. To obtain the value:
      • If the value is a standard data type, check TRemoteResource.Value.DataType to determine the type of the data, and read the matching TRemoteResource.Value property: AsBoolean, AsInteger, AsInt64, AsSingle, AsDouble, AsString.
      • If the value is a stream, read the stream from TRemoteResource.Value.AsStream.

Subscribing to Remote Resources for Updates

When your application is connected to an application that is sharing resources, you can subscribe to those shared resources for updates, so that your application receives those shared resources when their value changes in the connected application.

If you are using groups to connect to other applications, you can associate the remote resources with local resources at design time. These local resources provide an event that you can use to handle changes to the value of the remote resource.

Alternatively, you can subscribe to remote resources at run time using their resource name.

Note: You must not subscribe to a remote resource using both a local resource and SubscribeToRemoteItem. Use only one of these subscription methods for each remote resource.

Subscribing to Remote Resources Using Local Resources on Applications Connected Using Groups

To associate a local resource with a remote resource at design time:

  1. Follow the steps above to create and share a resource using app tethering.
  2. With your new TLocalResource selected on the resource list editor, change its Kind property on the Object Inspector to Mirror.
TLocalResource Kind Property.png

When you change the Kind of your TLocalResource to Mirror, your TLocalResource is not shared with remote applications. Instead, every time that the value of a remote resource with the same Name as the name that you specified in your TLocalResource changes, the value of your local resource is updated, and the TLocalResource.OnResourceReceived event occurs.

Subscribing to Remote Resources Using SubscribeToRemoteItem

Your TTetheringAppProfile component provides a method, SubscribeToRemoteItem, that you can use to subscribe to remote resources for updates.

You can specify a remote resource to subscribe with either of the following sets of parameters:

  • Provide the remote application profile that contains the remote resource as an instance of TTetheringProfileInfo and the name of the remote resource.
The RemoteProfiles property of your TTetheringManager component provides a list of remote application profiles that are connected to your profile.
  • Provide the remote application profile that contains the remote resource as an instance of TTetheringProfileInfo and an instance of TCustomRemoteItem.
Your TTetheringAppProfile component provides a method, GetRemoteProfileActions, that returns a list of remote resources shared by a given remote application profile specified as an instance of TTetheringProfileInfo.

When the value of a remote resource with the same name as the instance of TCustomRemoteItem that you subscribed changes, the value of the subscribed instance of TCustomRemoteItem is updated, and the OnResourceUpdated event occurs.

Note:
  • To read the value from the subscribed instance of TCustomRemoteItem, you must cast this instance as TRemoteResource and read its data. See Reading an Incoming Remote Resource.
  • When a remote resource that wraps a stream changes, the OnResourceUpdated event occurs, but the value of the subscribed instance of TCustomRemoteItem is not updated. You must request the new resource value manually. See Requesting Remote Resources.
  • The OnResourceUpdated event does not occur if you subscribe to the same remote resource using a local resource.

See Also