Перейти к содержанию
Fire Monkey от А до Я

FeLDMARShaL

Пользователи
  • Постов

    144
  • Зарегистрирован

  • Посещение

  • Победитель дней

    5

Сообщения, опубликованные FeLDMARShaL

  1. По поводу скриншотов тут все просто, там есть спец инструмент для загрузки скриншотов, а вот последний пункт про значек с разрешением 1024*1024 вот инструкция взятая с форума абракадабры (я проверил, все работает, отправил новое приложение на публикацию): 

    https://quality.embarcadero.com/browse/RSP-29692?focusedCommentId=85036&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-85036

     

    В идеале бы ее конечно сюда перенести, но она такая большая, с картинками и со сложными вставками, что страшно ее переносить, вдруг что то не докопируется. В архиве есть пример приложения для публикации, всегда можно сделать по образу и подобию. Для компиляции надо использовать строчку:

    actool --output-format human-readable-text --notices --warnings --app-icon AppIcon --output-partial-info-plist compilation_results/partial_Info.plist --target-device iphone --target-device ipad --minimum-deployment-target 11.0 --platform iphoneos --product-type com.apple.product-type.application --compile "compilation_results" "Assets.xcassets"

     

    sample_app.zip compiled_storyboard.zip asset_catalog.zip

  2. 1 минуту назад, Anatoliy сказал:

    Спасибо! А нужны ли какие то магические дополнительные действия если речь идет о C++Builder?

    В душе не знаю :), ниразу не пользовал и даже не устанавливал. Предполагаю проверить камунибуть и отписаться о результате. Вдруг что то забыл рассказать, но вроде все упомянул.

  3. Расскажу о том как я добился нормальной фоновой работы приложения. В моем понимании нормальная фоновая работа приложения - это сохранять геокоординаты и систематически (по мере их накопления передавать на сервер). По сути у нас получился трекер. Те кто считают что iOS такое не умеет делать, и все что будет написано ниже это фейк лучше закройти эту тему. Итак начнем, по пунктам:

    1) Добавляем к проекту ключ NSLocationAlwaysAndWhenInUseUsageDescription - для новых иОС это обязательно, начиная с 11 или 12 версии уже не помню

    image.thumb.png.ce59552eb04af61dd0f6b4b81d17cf13.png

    2) Сообщаем приложению о намерении что мы будем использовать геокоординаты в фоне (редактируем ключ UIBackgroundModes выставляя галочку напротив location)

    image.thumb.png.35332c025c2e8f1c3a891a2b44a67c9e.png

    3) Далее  для того чтобы не поломать другие приложения которые используют геолокацию создаем специальную дерективу, которая будет сообщать о том что наше приложение будет использовать геолокацию в фоне, я ее назвал iOS_RequestAlwaysAuthorization

    image.thumb.png.9e93b2b7f7cb4116a704401255f9368c.png

    4) Дальше намного сложнее, нам нужно исправить исходники самой Delphi, а именно System.iOS.Sensors. Изменять будем процедуру TiOSLocationSensor.DoStart, все что отличается от стандартного у меня в рамках описания моей директивы:

    function TiOSLocationSensor.DoStart: Boolean;
    var
      I: Integer;
    begin
      {$ifdef iOS_RequestAlwaysAuthorization}
      if TOSVersion.Check(8) and (FLocater <> nil) then
        FLocater.requestAlwaysAuthorization;
      {$else iOS_RequestAlwaysAuthorization}
      if TOSVersion.Check(8) and (FLocater <> nil) then
        FLocater.requestWhenInUseAuthorization;
      {$endif iOS_RequestAlwaysAuthorization}
    
      // check authorization
      if Authorized = TAuthorizationType.atUnauthorized then
        SensorError(SLocationServiceUnauthorized);
      // check if location sensor is enabled
      if not FLocater.locationServicesEnabled then
        SensorError(SLocationServiceDisabled);
    
      // start location updates
      if (LocationChange = TLocationChangeType.lctLarge) and CanUseSignifChangeNotifs then
        FLocater.startMonitoringSignificantLocationChanges
      else
        FLocater.startUpdatingLocation;
    
      // start heading updates
      if CanUseHeading then
      begin
        FLocater.startUpdatingHeading;
      end;
    
      // start monitoring regions
      if CanMonitorRegions then
        for I := 0 to Regions.Count - 1 do
          FLocater.startMonitoringForRegion(ConvLocationRegion(Regions[I]));
      Result := FLocater.locationServicesEnabled;
      if Result then
        Result := Authorized = TAuthorizationType.atAuthorized;
    
      {$ifdef iOS_RequestAlwaysAuthorization}
      FLocater.setAllowsBackgroundLocationUpdates(True);
      FLocater.setPausesLocationUpdatesAutomatically(False);
      {$endif iOS_RequestAlwaysAuthorization}
    
    end;

    Собственно усе, можно наслаждаться фоновой работой. Все это работает под Delphi 10.2.3. На телефоне iPhone 6s под управлением iOS 11. Как было сказано выше, работает как геолокация так и инет и вообще все остальные процессы внтури приложения, такие как TTimer :)

    Собственно вот результат данного трекера:

    image.png.a910ead1221d6478c7b0cc3ff85899da.png

     

    Если приблизить то можно увидеть насколько точно и часто он обновляет координаты:

    image.thumb.png.270127a3903a7302175ad151b47af48d.png

     

    И да, огромное спасибо человеку с ником Artyom Karapetyan, именно он натолкнул на мысль того как надо правильно все сделать :)

  4. Думаю тема стилизации этого индикатора раскрыта не полностью, но на текущий момент мне этого хватит. Было бы круто если значение переменной  UndefinedThemeID=-1 перекочевало в основную ветку (т.к. тема со ид равным 0 - это именно штатная тема приложения, которая многими меняется)

  5. После упорных попыток, не получилось подружить компонент с созданной темой, возможно ее ид как то не так получаю и ниже приведенный код возвращает что то не то :(

    themId := TAndroidHelper.Context.getResources.getIdentifier(StringToJString('styles_dialog'),
            StringToJString('layout'), TAndroidHelper.Context.getPackageName)

    Но реализовать нужно было пришлось пофиксить немного стандартные компоненты, и именно в части 

    const UndefinedThemeID = -1;

    Теперь компоненты считаю что ThemeID=0 - это кастомная тема.

    После чего, вот такой код (и измненная стандартная тема приложения):

      if not Assigned(fg_my) then
      begin
        fg_my := TfgActivityDialog.Create(nil);
        fg_my.Theme := TfgDialogTheme.Custom;
        fg_my.ThemeID := 0;
      end;
    
      fg_my.Show;
      sleep(3000);
      fg_my.Hide;
    

    Приводят вот к такому результату (разумеется индикатор крутится как надо):

    device-2017-12-19-141722.thumb.png.dcdd2d99807a6a1a130bde278811316b.png

  6. Коллеги. Я верю в коллективный разум. Требуется изменить визуально индикатор прогресса. Для этого к проекту необходимо подгружать стили. За основу я взял тему http://manjunath4android.blogspot.ru/2015/12/display-progress-dialog-without-text.html

    Будем менять индикатор на тот который указан в теме. Что было сделано с моей стороны:

    1) Прилинковал все необходимые фалы к нашему проекту

     5a30e6433a4eb_.thumb.PNG.22aecb3f3b6a5bd60be229070f34c4ff.PNG

    2) Проконсультировался с разработчиком компонентов :) Полазил по исходникам, в результате чего понял что поменять стиль в текущей реализации уже должно получится. Для этого есть 2 свойства у класса TfgActivityDialog: Theme и ThemeID.

    Если со свойством Theme все понятно, его необходимо задать как TfgDialogTheme.Custom, то с ThemeID не так все просто. На просторах интернета нашел что это такое (R.layout.my_progress) и вроде бы  даже перевел на Pascal: TAndroidHelper.Context.getResources.getIdentifier(StringToJString('my_progress'), StringToJString('layout'), TAndroidHelper.Context.getPackageName), но в конечном итоге имеем вот это:

    device-2017-12-13-154622.thumb.png.a4d7f52d729ce455908538ac9ad86308.png

    А ожидается вот это:

    Screenshot_2015-12-18-12-18-23-053.thumb.jpeg.349d7969cfe2d5ca2496f5d9cbb9d89e.jpeg

     

    На кнопку которая должна отобразить индикатор активности повесил вот такой код:

    procedure TmainForm.Button1Click(Sender: TObject);
    var
      fg: TfgActivityDialog;
      themId: Integer;
    begin
    
      themId := TAndroidHelper.Context.getResources.getIdentifier(StringToJString('my_progress'),
            StringToJString('layout'), TAndroidHelper.Context.getPackageName);
    
      fg := TfgActivityDialog.Create(Self);
    
      try
    
        if themId<>0 then
        begin
          fg.Theme := TfgDialogTheme.Custom;
          fg.ThemeID := themId;
          fg.Title := 'Title';
          fg.Message := 'Message';
          Button1.Text := 'TfgDialogTheme.Custom'
        end
        else
          Button1.Text := 'TfgDialogTheme.Auto';
    
        fg.Show;
        sleep(3000);
        fg.Hide;
    
      finally
        FreeAndNil(fg);
      end;
    
    end;

     

  7. когдато мне Ярослав помог с этим вопросом, вот его ответ (актуально для режима слайдинга):

    Цитата

     

    procedure TfgFlipViewSlidingPresentation.ApplyStyle;
    Нужно задать WrapMode для ImageContainer и FNextImageAnimator

    FGX.FlipView.Sliding.pas

     

    Мне помогла, если у Вас дургой режим, там по аналогии другой модуль поправить придется

  8. Немного изменил подход. Создал свой класс

    Цитата

      TMyViewDelegate = class(TOCLocal, PKPaymentAuthorizationViewControllerDelegate)
      private

      public
        [MethodName
          ('paymentAuthorizationViewController:didAuthorizePayment:completion:')]
        procedure paymentAuthorizationViewControllerDidAuthorizePaymentCompletion
          (controller: PKPaymentAuthorizationViewController;
          didAuthorizePayment: PKPayment; completion: TPassKitCompletion1); cdecl;
        procedure paymentAuthorizationViewControllerDidFinish
          (controller: PKPaymentAuthorizationViewController); cdecl;
        procedure paymentAuthorizationViewControllerWillAuthorizePayment
          (controller: PKPaymentAuthorizationViewController); cdecl;
        [MethodName
          ('paymentAuthorizationViewController:didSelectShippingMethod:completion:')
          ]
        procedure paymentAuthorizationViewControllerDidSelectShippingMethodCompletion
          (controller: PKPaymentAuthorizationViewController;
          didSelectShippingMethod: PKShippingMethod;
          completion: TPassKitCompletion2); cdecl;
        [MethodName
          ('paymentAuthorizationViewController:didSelectShippingAddress:completion:')
          ]
        procedure paymentAuthorizationViewControllerDidSelectShippingAddressCompletion
          (controller: PKPaymentAuthorizationViewController;
          didSelectShippingAddress: ABRecordRef;
          completion: TPassKitCompletion3); cdecl;
        [MethodName
          ('paymentAuthorizationViewController:didSelectShippingContact:completion:')
          ]
        procedure paymentAuthorizationViewControllerDidSelectShippingContactCompletion
          (controller: PKPaymentAuthorizationViewController;
          didSelectShippingContact: PKContact;
          completion: TPassKitCompletion3); cdecl;
        [MethodName
          ('paymentAuthorizationViewController:didSelectPaymentMethod:completion:')]
        procedure paymentAuthorizationViewControllerDidSelectPaymentMethodCompletion
          (controller: PKPaymentAuthorizationViewController;
          didSelectPaymentMethod: PKPaymentMethod;
          completion: TPassKitCompletion4); cdecl;
      end;

    Класс интерфейс PKPaymentAuthorizationViewControllerDelegate полученный посредством SdkTransform.exe:

    Скрытый текст

      PKPaymentAuthorizationViewControllerDelegate = interface(IObjectiveC)
        ['{85490555-3B8A-4850-8A8D-2F51032A531F}']
        [MethodName
          ('paymentAuthorizationViewController:didAuthorizePayment:completion:')]
        procedure paymentAuthorizationViewControllerDidAuthorizePaymentCompletion
          (controller: PKPaymentAuthorizationViewController;
          didAuthorizePayment: PKPayment; completion: TPassKitCompletion1); cdecl;
        procedure paymentAuthorizationViewControllerDidFinish
          (controller: PKPaymentAuthorizationViewController); cdecl;
        procedure paymentAuthorizationViewControllerWillAuthorizePayment
          (controller: PKPaymentAuthorizationViewController); cdecl;
        [MethodName
          ('paymentAuthorizationViewController:didSelectShippingMethod:completion:')
          ]
        procedure paymentAuthorizationViewControllerDidSelectShippingMethodCompletion
          (controller: PKPaymentAuthorizationViewController;
          didSelectShippingMethod: PKShippingMethod;
          completion: TPassKitCompletion2); cdecl;
        [MethodName
          ('paymentAuthorizationViewController:didSelectShippingAddress:completion:')
          ]
        procedure paymentAuthorizationViewControllerDidSelectShippingAddressCompletion
          (controller: PKPaymentAuthorizationViewController;
          didSelectShippingAddress: ABRecordRef;
          completion: TPassKitCompletion3); cdecl;
        [MethodName
          ('paymentAuthorizationViewController:didSelectShippingContact:completion:')
          ]
        procedure paymentAuthorizationViewControllerDidSelectShippingContactCompletion
          (controller: PKPaymentAuthorizationViewController;
          didSelectShippingContact: PKContact;
          completion: TPassKitCompletion3); cdecl;
        [MethodName
          ('paymentAuthorizationViewController:didSelectPaymentMethod:completion:')]
        procedure paymentAuthorizationViewControllerDidSelectPaymentMethodCompletion
          (controller: PKPaymentAuthorizationViewController;
          didSelectPaymentMethod: PKPaymentMethod;
          completion: TPassKitCompletion4); cdecl;
      end;

    Процедура (одна из):

    Цитата

    TPassKitCompletion1 = procedure(param1: PKPaymentAuthorizationStatus) of object;

    При попытке создать экземпляр класса LDelegate := TMyViewDelegate.Create; выскакивает ошибка

    Цитата

    TPassKitCompletion1=procedure (param1: Integer) is not a valid ObjectiveC type

    Я так понимаю что SdkTransform.exe неправильно создал заголовки нативных функций, и надо вручную их поправить. Есть идеи как это сделать?

    В инете нашел решение изменить объявление процедур на TPassKitCompletion1 = procedure(param1: PKPaymentAuthorizationStatus); cdecl; но мне это не помогло, ошибка остается

  9. Требуется реализовать поддержу Apple Pay. Договор с процессинговым центром уже есть. Ему необходимо передать Token запроса, который можно получить используя SDK PassKit

    Штатных заголовков нет, поэтому я выгрузил iOSapi.PassKit.pas с самого SDK, в итоге получил вот следующий файл.

    Что было выяснено:

    1) Необходимо сгенерировать запрос на платеж PKPaymentRequest (ГОТОВО, правда почему то пока не получается добавить потдерживаемые платежные системы (setSupportedNetworks) и строки позиций (setPaymentSummaryItems) но на текущем этапе это не так важно и может подождать)

    2) Необходимо создать PKPaymentAuthorizationViewController и обрабатывать результат его работы в PKPaymentAuthorizationViewControllerDelegate. А вот с этим возникли трудности из за отсутствия опыта. Может быть есть у кого нибуlь опыт по работе с SDK iOS.

    т.е. у нас есть

    PKPaymentAuthorizationViewControllerClass = interface(UIViewControllerClass)

    PKPaymentAuthorizationViewController = interface(UIViewController)

    TPKPaymentAuthorizationViewController = class

    PKPaymentAuthorizationViewControllerDelegate = interface(IObjectiveC)

    и их надо как то вместе соединить.

    На текущий момент у меня получилось примерно следующее:

    Цитата

    procedure TApplePay.test;
    var
      LocalPKPaymentRequest: PKPaymentRequest;
      LocalPKPaymentAuthorizationViewController: PKPaymentAuthorizationViewController;
      LocalPKPaymentSummaryItem: PKPaymentSummaryItem;

      LocalPKPaymentAuthorizationControllerDelegate: PKPaymentAuthorizationControllerDelegate;

      FMainWindow: UIWindow;

      supportedNetworks: NSMutableArray;
      paymentSummaryItems: NSMutableArray;
    begin
      LocalPKPaymentRequest := TPKPaymentRequest.Wrap(TPKPaymentRequest.Alloc.init);
      LocalPKPaymentAuthorizationViewController := TPKPaymentAuthorizationViewController.Wrap(TPKPaymentAuthorizationViewController.Alloc.init);
      LocalPKPaymentAuthorizationControllerDelegate := TPKPaymentAuthorizationControllerDelegate.Wrap(TPKPaymentAuthorizationControllerDelegate.Alloc.init);

      if not Assigned(LocalPKPaymentRequest) or not Assigned(LocalPKPaymentAuthorizationViewController) then
        Exit;

      LocalPKPaymentRequest.setMerchantIdentifier(NSStr('merchant.ru.ХХХ.ХХХХХХХ'));

      {//нехатит добавляться типы платежных систем
      supportedNetworks := TNSMutableArray.Create;
      supportedNetworks.addObject(PKPaymentNetworkMasterCard);
      supportedNetworks.addObject(PKPaymentNetworkMasterCard);
      supportedNetworks.addObject(PKPaymentNetworkAmex);
      LocalPKPaymentRequest.setSupportedNetworks(supportedNetworks);}

      LocalPKPaymentRequest.setMerchantCapabilities(PKMerchantCapability3DS);
      LocalPKPaymentRequest.setCountryCode(NSStr('RU'));
      LocalPKPaymentRequest.setCurrencyCode(NSStr('RUB'));

      {//нехатит добавляться позиции
      LocalPKPaymentSummaryItem := TPKPaymentSummaryItem.Wrap(TPKPaymentSummaryItem.Alloc.init);
      LocalPKPaymentSummaryItem.setLabel(NSStr('qwe'));
      LocalPKPaymentSummaryItem.setAmount(TNSDecimalNumber.Wrap(TNSDecimalNumber.OCClass.numberWithFloat(10.2)));
      LocalPKPaymentSummaryItem.setType(1);
      paymentSummaryItems := TNSMutableArray.Create;
      paymentSummaryItems.addObject(LocalPKPaymentSummaryItem);
      LocalPKPaymentRequest.setPaymentSummaryItems(paymentSummaryItems);}

      LocalPKPaymentAuthorizationViewController.initWithPaymentRequest(LocalPKPaymentRequest);
      FMainWindow := TUIApplication.Wrap(TUIApplication.OCClass.sharedApplication).keyWindow;
      if Assigned( FMainWindow ) and Assigned(FMainWindow.rootViewController) then
        FMainWindow.rootViewController.presentViewController(LocalPKPaymentAuthorizationViewController, True, ViewControllerCompletion);

    end;

    Валится на строчке FMainWindow.rootViewController.presentViewController(LocalPKPaymentAuthorizationViewController, True, ViewControllerCompletion);

     

    Буду рад любой помощи, даже ссылкам на документы которые позволят мне в этом разобраться.

    iOSapi.PassKit.rar

  10. 15 часов назад, Andrey Efimov сказал:

    Скорее всего, проблема в том (это предположение!), что в студии нельзя добавить картинки для:

    • xxhdpi (extra-extra-high) ~480dpi (scale 3)
    • xxxhdpi (extra-extra-extra-high) ~640dpi (scale 4)

    Вы говорите про иконки, а я про сплеш. Сплеша всего 4 типа же (сам гугл так говорит)

    Если сделать как Вы сказали (подогнать границы непосредственно под картинку, тогда пикселизация еще больше усилится

  11. 17 часов назад, ENERGY сказал:

    А вы установили все размеры SplashScreen'a в свойствах проекта?

    А вы правильно сделали 9 patch png? Т.е. если загрузить вашу 9.png картинку в этот редактор, то он не должен растягивать саму картинку, а только черные края, отмеченные в этой проге.

     

    Да, все. Да, все правильно (чтобы откинуть такие предположения и скинул пример своих картинок (все 4 кстати)

  12. 1 час назад, Равиль Зарипов (ZuBy) сказал:

    у меня тоже нексус 5, проблем не было. хотя там был не текст, но все же

    А можете скинуть картинки которые использовал или скриншот сделать сплеш скрина на телефоне или ссылку на приложение в маркете, я установлю и посмотрю как оно выглядит? Может просто на конкретной картинке не заметно как она растягивается

  13. У меня девайс нексус 5, и там довольно большое разрешение и картинка на самом деле без растяжении должна выглядеть примерно так как на рисунке ниже (сверху). Непонятно почему на сплеше он его растягивает, причем всегда в независимости от типа сплеша.

    Скрытый текст

    device-2017-06-14-184836.png

     

×
×
  • Создать...