Jump to content

Erro de compilação - Delphi Sydney 10.4.2 - iOS Push Notification (Firebase Cloud Messaging)


zidra
Go to solution Solved by zidra,

Recommended Posts

Boa tarde a todos 🙂

Recentemente começamos a migrar as nossas apps (Android / iOS) do Delphi Rio 10.3.3 para a mais recente Delphi Sydney 10.4.2.  Em android correu tudo bem, basicamente foi compilar e ficou feita a migração. No iOS, estou com bastantes problemas para conseguir que as notificações push funcionem, sendo que na versão anterior estava tudo a funcionar.
Uma das novidades na versão 10.4.2 é, precisamente, o suporte para Firebase Push Notification para iOS. 

Segui os passos apresentados neste webinar https://blogs.embarcadero.com/pt/webinar-amanha-mao-na-massa-com-rad-studio-10-4-2/ (no video, começa no minuto 1:08:30), atualizei o mac para o mais Big Sur (vs 11.4), instalei a partir do GetIt Package Manager o Firebase SDK for iOS 6.28.

Depois de configurar nas opções do projeto a opção  "Framework search path" com o caminho para as pastas FirebaseAnalytics e FirebaseMessaging e colocar a opção -ObjC em "Options passed to de LD linker" estou a receber o seguinte erro:

[DCC Error] E2597 ld: file not found: PromisesObjC
[DCC Fatal Error] F2588 Linker error code: 1 ($00000001)

Descarreguei o exemplo apresentado no webinar https://github.com/flrizzato/WEBINARS/tree/master/10.4.2-HandsOn e tenho exatamente o mesmo erro...

Talvez esteja a faltar alguma configuração no delphi ou no mac (não sei se é necessário instalar alguma coisa)..

Alguém tem ideia do que será?

Agradeço qualquer ajuda, se não houver ajudas, pelo menos desabafei 😅

Link to comment
Share on other sites

  • Solution

Bom dia, já consegui resolver o problema, mas tive de abrir um ticket... Apesar de ter colocado os caminhos na opção "Framework search path" estava a escapar-me um pormenor 🙂Deixo-vos a resposta, caso venham a precisar. 
 

"If you look at the directory structure of what is downloaded from Getit, there are .xcframework directories. If you drill into those directories, you will find ios-armv7_arm64 directories. In there are ios-armv7_arm64, which contains libraries that we can link to. iOS projects have a Framework search path option, but they cannot search in an .xcframework - only .framework. This is what I suggest that you do:

1. Create a Firebase directory in your project directory structure

2. Copy C:\Users\stevea\Documents\Embarcadero\Studio\21.0\CatalogRepository\FirebaseSDKforiOS-6.28\Firebase\FirebaseAnalytics and C:\Users\stevea\Documents\Embarcadero\Studio\21.0\CatalogRepository\FirebaseSDKforiOS-6.28\Firebase\FirebaseMessaging to that FireBase directory.

3. Go to the FireBaseAnalytics directory.

4. For each .xcframeworkdirectory, go to ios-armv7_arm64 and copy the .framework directory that you will find there and copy it to the FireBaseAnalytics folder.

5. Repeat for the FirebaseMessaging folder." by Embarcadero Support

  • Vote 1
Link to comment
Share on other sites

  • 2 months later...

Amigo poderia me ajudar estou tentando fazer esse procedimento de receber push pelo Firebase com o Delphi 10.4.2 e não encontro material eu ja fiz esse procedimento acima que você falou, porem quando tento acessar o Firebase eu pego o status da conexão pelo seguinte codigo:

if PushService.Status = TPushService.TStatus.Started then
             begin

             end
          else if PushService.Status = TPushService.TStatus.Starting then
             begin

             end
          else if PushService.Status = TPushService.TStatus.Stopped then
             begin

             end
          else if PushService.Status = TPushService.TStatus.StartupError then
             begin
                ShowMessage(PushService.StartupError);
             end;

Porem ele nunca Starta fica somente em Starting, você sabe como corrigir?

 
Link to comment
Share on other sites

Em 23/08/2021 às 18:43, Rodolfo Tomaz Viccari disse:

Amigo poderia me ajudar estou tentando fazer esse procedimento de receber push pelo Firebase com o Delphi 10.4.2 e não encontro material eu ja fiz esse procedimento acima que você falou, porem quando tento acessar o Firebase eu pego o status da conexão pelo seguinte codigo:

if PushService.Status = TPushService.TStatus.Started then
             begin

             end
          else if PushService.Status = TPushService.TStatus.Starting then
             begin

             end
          else if PushService.Status = TPushService.TStatus.Stopped then
             begin

             end
          else if PushService.Status = TPushService.TStatus.StartupError then
             begin
                ShowMessage(PushService.StartupError);
             end;

Porem ele nunca Starta fica somente em Starting, você sabe como corrigir?

 

Bom dia Rodolfo,

Segui alguns exemplos que encontrei na net, por exemplo nos vídeos do canal 99 {coders} (https://www.youtube.com/c/99Coders/featured)

É necessário trabalhar com os eventos DoServiceConnectionChange e DoReceiveNotificationEvent. Vou colocar uma parte do código que tenho implementado. 
 

 public
    FPushService: TPushService;
    FServiceConnection: TPushServiceConnection;
    
    
....


procedure TForm1.FormCreate(Sender: TObject);
begin
  inherited;

  TSysPushNotification.InitPushNotificationService(FPushService, FServiceConnection); //TSysPushNotification classe criada para isolar o código de iniciação

  FServiceConnection.OnChange := DoServiceConnectionChange;
  FServiceConnection.OnReceiveNotification := DoReceiveNotificationEvent;
  FServiceConnection.Active := True;
    
end;


procedure TForm1.DoServiceConnectionChange(Sender: TObject; PushChanges: TPushService.TChanges);
begin
  if TPushService.TChange.Status in PushChanges then
  begin
    if FPushService.Status = TPushService.TStatus.Started then
    begin
    end
    else if FPushService.Status = TPushService.TStatus.StartupError then
    begin
      FServiceConnection.Active := False;
    end;
  end;
  if TPushService.TChange.DeviceToken in PushChanges then
  begin
    ReloadTokenAndDeviceID;
  end;
end;

procedure TForm1.ReloadTokenAndDeviceID;
var
  device_token, device_id : string;
begin
    device_token := TSysPushNotification.GetToken(FPushService);
    TSysVarSettings.GetInstance.DeviceToken := device_token;

    device_id := TSysPushNotification.GetDeviceID(FPushService);
    TSysVarSettings.GetInstance.DeviceID := device_id;
end;

procedure TForm1.DoReceiveNotificationEvent(Sender: TObject; const ServiceNotification: TPushServiceNotification);
var
  x: Integer;
  fobj: TJSONObject;
  fIdSourceStr, fPushNotificationTypeStr : string;
  fIdSource, fPushNotificationType : integer;
begin
  fIdSourceStr := '';
  fPushNotificationTypeStr := '';
  try
    for x := 0 to ServiceNotification.DataObject.Count - 1 do
    begin
      //iOS...
      if ServiceNotification.DataKey = 'aps' then
      begin
        fobj := TJSONObject.ParseJSONValue(ServiceNotification.Json.ToString) as TJSONObject;
        try
          fPushNotificationTypeStr := fobj.Values['pushtypeid'].Value;
          fIdSourceStr := fobj.Values['idsource'].Value;
        finally
          FreeAndNil(fobj);
        end;
      end
      else
      begin
        // Android...
        if ServiceNotification.DataKey = 'fcm' then
        begin
          // Firebase console... disable
          //if ServiceNotification.DataObject.Pairs[x].JsonString.Value = 'gcm.notification.body' then
            //MessageText := ServiceNotification.DataObject.Pairs[x].JsonValue.Value;

          //our service
          if ServiceNotification.DataObject.Pairs[x].JsonString.Value = 'pushtypeid' then
          begin
            fPushNotificationTypeStr := ServiceNotification.DataObject.Pairs[x].JsonValue.Value;
          end
          else
          begin
            if ServiceNotification.DataObject.Pairs[x].JsonString.Value = 'idsource' then
            begin
              fIdSourceStr := ServiceNotification.DataObject.Pairs[x].JsonValue.Value;
            end
          end;
        end;
      end;
    end;
  except on e:exception do
    SetErrorMessage(TSysAppException.GetInstance.GetError(e.Message));
  end;

  try
    if (not fIdSourceStr.IsEmpty) and (not fPushNotificationTypeStr.IsEmpty)  then
    begin
       fIdSource := strToInt(fIdSourceStr);
       fPushNotificationType := strToInt(fPushNotificationTypeStr);
       case TNotifTp(fPushNotificationType) of
          ntChatMessage:
          begin
            OpenChatMessageById(fIdSource);
          end;
          ntEvent:
          begin
            RefreshNotifyCount;
          end;
          ntGym, ntClassComment:
          begin
            ConfigBtnOptionHeaderForNotity;
          end;
       end;
    end;
  except
  end;
end;

Espero que ajude :)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.