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

Fedor K

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

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

  • Посещение

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

    17

Активность репутации

  1. Like
    Fedor K получил реакцию от enatechno в IdTCPClient-IdTCPServer управление соединением   
    Можете мне сделать тестовый сервер и клиент, чтобы я смог у себя проверить? Тогда мой ответ будет более детальным. А пока:
    Какой вы объем данных шлете по соединению? Чем вызвана потребность использовать именно сокеты? TimeOut  никогда не ставьте большими. Indy работает по принципу блокировки сокета и всего потока в целом. Поэтому большое значение = зависание всего приложения = нежелательные результаты и зависание. Я ставил 100 мс для работы с маленькими пакетами. С такой задержкой доп. поток не обязателен. Если значения более 500 мс - нужно создавать отдельный поток и работать с сокетами в ней + синхронизация при обработке / отправке данных. TIdTCPClient на Andoid любит спать и не проверять входящий буфер. Поэтому вручную нужно вызывать по таймеру проверку типа: procedure T<какое-то имя класа>.Read; var sz : integer; lMsg : string; begin try TMonitor.Enter(Self); try if not Assigned(Client.IOHandler) then Exit; //Client = TIdTCPClient if Client.IOHandler.InputBufferIsEmpty then begin if not Client.IOHandler.CheckForDataOnSource() then exit; end; sz := Client.IOHandler.InputBuffer.Size; if sz <= 0 then exit; lMsg := Client.IOHandler.InputBuffer.ExtractToString(-1, IndyTextEncoding_UTF8); Client.IOHandler.InputBuffer.Clear; <какой-то обработчик входящего сообщения>; except on e : Exception do <какой-то обработчик ошибки>; end; finally TMonitor.Exit(Self); end; end; AntiFreeze - это мягко говоря "костыль" от Indy, использование его плохая практика. На мобильной платформе вряд ли он появится, хотя и реализуется не сложно.
  2. Like
    Fedor K получил реакцию от Anatoliy в IdTCPClient-IdTCPServer управление соединением   
    Можете мне сделать тестовый сервер и клиент, чтобы я смог у себя проверить? Тогда мой ответ будет более детальным. А пока:
    Какой вы объем данных шлете по соединению? Чем вызвана потребность использовать именно сокеты? TimeOut  никогда не ставьте большими. Indy работает по принципу блокировки сокета и всего потока в целом. Поэтому большое значение = зависание всего приложения = нежелательные результаты и зависание. Я ставил 100 мс для работы с маленькими пакетами. С такой задержкой доп. поток не обязателен. Если значения более 500 мс - нужно создавать отдельный поток и работать с сокетами в ней + синхронизация при обработке / отправке данных. TIdTCPClient на Andoid любит спать и не проверять входящий буфер. Поэтому вручную нужно вызывать по таймеру проверку типа: procedure T<какое-то имя класа>.Read; var sz : integer; lMsg : string; begin try TMonitor.Enter(Self); try if not Assigned(Client.IOHandler) then Exit; //Client = TIdTCPClient if Client.IOHandler.InputBufferIsEmpty then begin if not Client.IOHandler.CheckForDataOnSource() then exit; end; sz := Client.IOHandler.InputBuffer.Size; if sz <= 0 then exit; lMsg := Client.IOHandler.InputBuffer.ExtractToString(-1, IndyTextEncoding_UTF8); Client.IOHandler.InputBuffer.Clear; <какой-то обработчик входящего сообщения>; except on e : Exception do <какой-то обработчик ошибки>; end; finally TMonitor.Exit(Self); end; end; AntiFreeze - это мягко говоря "костыль" от Indy, использование его плохая практика. На мобильной платформе вряд ли он появится, хотя и реализуется не сложно.
  3. Like
    Fedor K получил реакцию от enatechno в TWebBrowser и неверный ssl сертификат на сайте.   
    Objective-C конечно весьма специфический... Попробовал несколько методов, но решение действительно очень простое:
    1. Меняем iOSapi.Foundation.pas:
    unit iOSapi.Foundation; //~3855 строка, добавляем 2 метода NSURLRequestClass = interface(NSObjectClass) ['{A93A4D14-529E-41F0-86EC-B570715512BB}'] {class} function requestWithURL(URL: NSURL): Pointer; cdecl; overload; {class} function requestWithURL(URL: NSURL; cachePolicy: NSURLRequestCachePolicy; timeoutInterval: NSTimeInterval): Pointer; cdecl; overload; //метод раз {class} function allowsAnyHTTPSCertificateForHost(host: NSString): Boolean; cdecl; overload; //метод два {class} procedure setAllowsAnyHTTPSCertificate(allow: Boolean; forHost: NSString); cdecl; overload; end; 2. В своем коде для требуемых сайтов пишем следующее:
    TNSURLRequest.OCClass.setAllowsAnyHTTPSCertificate(true, StrToNSStr(<требуемый сайт>)); Проверял на сайте expired.badssl.com, XCode 7 + SDK 9.3, Simulator, также на реальном устройстве с iOS 11.
    п.с. Если нужно доверять абсолютно всем сайтам, думаю можно п. 2 вставить в FMX.WebBrowser.Cocoa.pas в методе:
    procedure TCommonWebBrowserService.DoNavigate(const URL: string);  
  4. Like
    Fedor K отреагировална Rusland в TWebBrowser и неверный ssl сертификат на сайте.   
    Проверил - отлично работает! Спасибо
    PS. XCode 7.3.1, iPhoneSimulator9.3.sdk
  5. Like
    Fedor K получил реакцию от #WAMACO в Через NetHTTPClient передать фотографию на сервер   
    Не совсем верно. При использовании Indy нужно к проекту подключать библиотеки (libcrypto.so, libssl.so) для Android и  (libcrypto.a, libssl.a)iOS. Пример для A есть на форуме. Для iOS такие же телодвижения, библиотеки например здесь. 
    После всего это приложения прекрасно проходят проверки маркетов. Но все это добавляют лишнее телодвижения, размер приложения раздувается. И я бы рекомендовал использовать нативные компоненты, где это возможно. 
  6. Like
    Fedor K получил реакцию от #WAMACO в TWebBrowser и неверный ssl сертификат на сайте.   
    Objective-C конечно весьма специфический... Попробовал несколько методов, но решение действительно очень простое:
    1. Меняем iOSapi.Foundation.pas:
    unit iOSapi.Foundation; //~3855 строка, добавляем 2 метода NSURLRequestClass = interface(NSObjectClass) ['{A93A4D14-529E-41F0-86EC-B570715512BB}'] {class} function requestWithURL(URL: NSURL): Pointer; cdecl; overload; {class} function requestWithURL(URL: NSURL; cachePolicy: NSURLRequestCachePolicy; timeoutInterval: NSTimeInterval): Pointer; cdecl; overload; //метод раз {class} function allowsAnyHTTPSCertificateForHost(host: NSString): Boolean; cdecl; overload; //метод два {class} procedure setAllowsAnyHTTPSCertificate(allow: Boolean; forHost: NSString); cdecl; overload; end; 2. В своем коде для требуемых сайтов пишем следующее:
    TNSURLRequest.OCClass.setAllowsAnyHTTPSCertificate(true, StrToNSStr(<требуемый сайт>)); Проверял на сайте expired.badssl.com, XCode 7 + SDK 9.3, Simulator, также на реальном устройстве с iOS 11.
    п.с. Если нужно доверять абсолютно всем сайтам, думаю можно п. 2 вставить в FMX.WebBrowser.Cocoa.pas в методе:
    procedure TCommonWebBrowserService.DoNavigate(const URL: string);  
  7. Like
    Fedor K получил реакцию от Anatoliy в [ANDROID] Смена USER-AGENT компонента Webbrowser   
    Если я правильно понимаю, это запись значения в справочник. Для работы с этим хранилищем есть такой враппер:
    https://www.dropbox.com/s/5q17zki83t1ivjq/AppProperties.pas?dl=0
    Попробуйте сделать так:
    TAppProperties.SaveStr(['UserAgent'], ['My User Agent 1.0']);  
  8. Like
    Fedor K получил реакцию от Anatoliy в Через NetHTTPClient передать фотографию на сервер   
    Не совсем верно. При использовании Indy нужно к проекту подключать библиотеки (libcrypto.so, libssl.so) для Android и  (libcrypto.a, libssl.a)iOS. Пример для A есть на форуме. Для iOS такие же телодвижения, библиотеки например здесь. 
    После всего это приложения прекрасно проходят проверки маркетов. Но все это добавляют лишнее телодвижения, размер приложения раздувается. И я бы рекомендовал использовать нативные компоненты, где это возможно. 
  9. Like
    Fedor K получил реакцию от Rusland в [ANDROID] Смена USER-AGENT компонента Webbrowser   
    Если я правильно понимаю, это запись значения в справочник. Для работы с этим хранилищем есть такой враппер:
    https://www.dropbox.com/s/5q17zki83t1ivjq/AppProperties.pas?dl=0
    Попробуйте сделать так:
    TAppProperties.SaveStr(['UserAgent'], ['My User Agent 1.0']);  
  10. Like
    Fedor K получил реакцию от Rusland в Через NetHTTPClient передать фотографию на сервер   
    Не совсем верно. При использовании Indy нужно к проекту подключать библиотеки (libcrypto.so, libssl.so) для Android и  (libcrypto.a, libssl.a)iOS. Пример для A есть на форуме. Для iOS такие же телодвижения, библиотеки например здесь. 
    После всего это приложения прекрасно проходят проверки маркетов. Но все это добавляют лишнее телодвижения, размер приложения раздувается. И я бы рекомендовал использовать нативные компоненты, где это возможно. 
  11. Like
    Fedor K получил реакцию от Rusland в TWebBrowser и неверный ssl сертификат на сайте.   
    Objective-C конечно весьма специфический... Попробовал несколько методов, но решение действительно очень простое:
    1. Меняем iOSapi.Foundation.pas:
    unit iOSapi.Foundation; //~3855 строка, добавляем 2 метода NSURLRequestClass = interface(NSObjectClass) ['{A93A4D14-529E-41F0-86EC-B570715512BB}'] {class} function requestWithURL(URL: NSURL): Pointer; cdecl; overload; {class} function requestWithURL(URL: NSURL; cachePolicy: NSURLRequestCachePolicy; timeoutInterval: NSTimeInterval): Pointer; cdecl; overload; //метод раз {class} function allowsAnyHTTPSCertificateForHost(host: NSString): Boolean; cdecl; overload; //метод два {class} procedure setAllowsAnyHTTPSCertificate(allow: Boolean; forHost: NSString); cdecl; overload; end; 2. В своем коде для требуемых сайтов пишем следующее:
    TNSURLRequest.OCClass.setAllowsAnyHTTPSCertificate(true, StrToNSStr(<требуемый сайт>)); Проверял на сайте expired.badssl.com, XCode 7 + SDK 9.3, Simulator, также на реальном устройстве с iOS 11.
    п.с. Если нужно доверять абсолютно всем сайтам, думаю можно п. 2 вставить в FMX.WebBrowser.Cocoa.pas в методе:
    procedure TCommonWebBrowserService.DoNavigate(const URL: string);  
  12. Like
    Fedor K получил реакцию от Anatoliy в TWebBrowser и неверный ssl сертификат на сайте.   
    Objective-C конечно весьма специфический... Попробовал несколько методов, но решение действительно очень простое:
    1. Меняем iOSapi.Foundation.pas:
    unit iOSapi.Foundation; //~3855 строка, добавляем 2 метода NSURLRequestClass = interface(NSObjectClass) ['{A93A4D14-529E-41F0-86EC-B570715512BB}'] {class} function requestWithURL(URL: NSURL): Pointer; cdecl; overload; {class} function requestWithURL(URL: NSURL; cachePolicy: NSURLRequestCachePolicy; timeoutInterval: NSTimeInterval): Pointer; cdecl; overload; //метод раз {class} function allowsAnyHTTPSCertificateForHost(host: NSString): Boolean; cdecl; overload; //метод два {class} procedure setAllowsAnyHTTPSCertificate(allow: Boolean; forHost: NSString); cdecl; overload; end; 2. В своем коде для требуемых сайтов пишем следующее:
    TNSURLRequest.OCClass.setAllowsAnyHTTPSCertificate(true, StrToNSStr(<требуемый сайт>)); Проверял на сайте expired.badssl.com, XCode 7 + SDK 9.3, Simulator, также на реальном устройстве с iOS 11.
    п.с. Если нужно доверять абсолютно всем сайтам, думаю можно п. 2 вставить в FMX.WebBrowser.Cocoa.pas в методе:
    procedure TCommonWebBrowserService.DoNavigate(const URL: string);  
  13. Like
    Fedor K получил реакцию от Rusland в TWebBrowser и неверный ssl сертификат на сайте.   
    Я проверю свою догадку и отпишусь чуть позже. Есть шанс, что все также легко.
  14. Like
    Fedor K получил реакцию от Anatoliy в TWebBrowser и неверный ssl сертификат на сайте.   
    Причина такого поведения довольно простая - java библиотеки FMX часто передают в Delphi только уведомление о событии, без непосредственного влияния на процесс. Открываем библиотеку fmx.jar и смотрим код класса WebClient (package com.embarcadero.firemonkey.webbrowser;):
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { super.onReceivedSslError(view, handler, error);// обработка ошибки происходит здесь по дефолту if (this.mListener != null) { this.mListener.onReceivedSslError(view, handler, error);//передача в Delphi лишь уведомления, что событие произошло } } Одно из решений*:
    1. Заменяем** код на:
    public void onReceivedSslError(WebView paramWebView, SslErrorHandler paramSslErrorHandler, SslError paramSslError) { if (this.mListener != null) { this.mListener.onReceivedSslError(paramWebView, paramSslErrorHandler, paramSslError);//Delphi обработчик } else { super.onReceivedSslError(paramWebView, paramSslErrorHandler, paramSslError);//обработчик по умолчанию } } После манипуляций получаем свою версию библиотеки, мой пример здесь (Delphi Berlin).
    2. Подключаем библиотеку к проекту (скриншот ниже).
    3. Копируем unit FMX.WebBrowser.Android в папку своего проекта и меняем следующие строки:
    procedure TAndroidWebBrowserService.TWebBrowserListener.onReceivedSslError( P1: JWebView; P2: JSslErrorHandler; P3: JSslError); begin P2.proceed;//добавляем разрешение для истекших сертификатов FWBService.FailLoadingWithError;//стандартный обработчик OnDidFailLoadWithError end; *Если вариант изменения кода java библиотек совсем не подходит, можно реализовать все средствами Delphi. Для этого создаем свою реализация класса WebViewClient (или WebClient) и задаем его для JWebBrowser:
    //все тот же unit FMX.WebBrowser.Android; procedure TAndroidWebBrowserService.InitUIThread; var lClient : TWebBrowserCLientFix;//наш класс begin FJWebBrowser := TJWebBrowser.JavaClass.init(TAndroidHelper.Activity); FJWebBrowser.getSettings.setJavaScriptEnabled(True); lClient := TWebBrowserCLientFix.Create(Self); FJWebBrowser.setWebViewClient(lClient);//меняем на наш класс FListener := TWebBrowserListener.Create(Self); lClient.SetWebViewListener(FListener); //комментируем //FJWebBrowser.SetWebViewListener(FListener); **Замена кода происходит по тому же сценарию, как и создание своих собственных классов на java. Если кому потребуется помощь - пишите, я помогу ответами и примером.

  15. Like
    Fedor K получил реакцию от Rusland в TWebBrowser и неверный ssl сертификат на сайте.   
    Думаю вполне реально. Пример обхода этой проблемы есть  ссылка #1 и ссылка #2. Методика следующая:
    Добавляем в .plist из комментария разрешения. Открываем FMX.WebBrowser.Delegate.iOS и правим TWebViewDelegate.shouldStartLoadWithRequest, запрещая загрузку при получении invalid сертификата. Создаем экземпляр NSURLConnection и выполняем тот же запрос. В методе didReceiveAuthenticationChallenge доверяем сертификату. Выполняем загрузку страницы в webView заново. Is the issue still actual? If yes, please send to me the fmx.jar file (by default path: "C:\Program Files (x86)\Embarcadero\Studio\18.0\lib\android\release"). Thanks.
  16. Like
    Fedor K получил реакцию от A. Sharif в Получение acess-token от VK/FB/IG/Gle приложений   
    Таким образом получал access_token лишь из Facebook, остальные приложения не требовались. Пример написан в далеком 2015 году, сейчас возможно нужны небольшие доработки. Насколько я помню, у приложения VK тоже была похожая активность для авторизации, как и у Facebook:
    FacebookAppName = 'com.facebook.katana'; FacebookActivityName = 'com.facebook.katana.ProxyAuth'; Схема следующая:
    Сканируем установленное приложение и находим активность для авторизации. Из своего приложения запускаем эту активность и передаем требуемые данные. Получаем ответ от приложения и вытаскиваем access_token. Делаем HTTP запрос к API и получаем требуемую информацию о пользователе.
  17. Like
    Fedor K получил реакцию от #WAMACO в TWebBrowser и неверный ssl сертификат на сайте.   
    Думаю вполне реально. Пример обхода этой проблемы есть  ссылка #1 и ссылка #2. Методика следующая:
    Добавляем в .plist из комментария разрешения. Открываем FMX.WebBrowser.Delegate.iOS и правим TWebViewDelegate.shouldStartLoadWithRequest, запрещая загрузку при получении invalid сертификата. Создаем экземпляр NSURLConnection и выполняем тот же запрос. В методе didReceiveAuthenticationChallenge доверяем сертификату. Выполняем загрузку страницы в webView заново. Is the issue still actual? If yes, please send to me the fmx.jar file (by default path: "C:\Program Files (x86)\Embarcadero\Studio\18.0\lib\android\release"). Thanks.
  18. Like
    Fedor K получил реакцию от Anatoliy в TWebBrowser и неверный ssl сертификат на сайте.   
    Думаю вполне реально. Пример обхода этой проблемы есть  ссылка #1 и ссылка #2. Методика следующая:
    Добавляем в .plist из комментария разрешения. Открываем FMX.WebBrowser.Delegate.iOS и правим TWebViewDelegate.shouldStartLoadWithRequest, запрещая загрузку при получении invalid сертификата. Создаем экземпляр NSURLConnection и выполняем тот же запрос. В методе didReceiveAuthenticationChallenge доверяем сертификату. Выполняем загрузку страницы в webView заново. Is the issue still actual? If yes, please send to me the fmx.jar file (by default path: "C:\Program Files (x86)\Embarcadero\Studio\18.0\lib\android\release"). Thanks.
  19. Like
    Fedor K получил реакцию от Rusland в Как прочитать ВСЕ свои push из шторки, при старте программы   
    ENERGY Для получения всех активных уведомлений в Android существует метод:
    getActiveNotifications added in API level 23 StatusBarNotification[] getActiveNotifications () FMX (Berlin и ниже точно, Tokyo не смотрел) не предоставляет доступ к этому методу, в исходниках (Androidapi.JNI.App.pas) он закомментирован. Возможно при использовании своего wrapper для класса JNotificationManager или отсюда можно получить доступ к требуемому функционалу.
  20. Like
    Fedor K получил реакцию от enatechno в Удаление Item'ов из ListBox c помощью цикла while   
    Небольшое уточнение: они не удаляются только на мобильных платформах, т.к. идет вызов DisposeOf:
    //смотрим код в unit FMX.Types; procedure TFmxObject.DoDeleteChildren; ... Child := FChildren[I]; FChildren.Delete(I); Child.FParent := nil; Child.SetRoot(nil); Child.DisposeOf; // вот причина ошибки с именем на мобильных платформ, удалене контрола идет не сразу, а при обнулении ссылок ... Для RunTime компонентов лучше в качестве Owner указывать nil и задавать лишь Parent, чтобы уменьшить кол-во ссылок и путаницы.
  21. Like
    Fedor K получил реакцию от Ingalime в Не могу поменять стиль TabControl (disable)   
    Как вариант в стиле вынести картинку с текстом в отдельный TLayout и добавить TFloatAnimation с триггером на IsSelected на свойство Opacity :
     


  22. Like
    Fedor K получил реакцию от Ingalime в Удаление Item'ов из ListBox c помощью цикла while   
    Из приведенного выше кода ничего вручную удалять не нужно, кроме самого TListBoxItem, как и выполняется в примере выше (listbox1.Items.Delete(indexclick) или Form1.listbox1.Items.Delete(0)) . Все создаваемые дополнительные контролы (TGridPanelLayout, TRectangle, TText) создаются здесь с AOwner = TListBoxItem + задается Parent, который мы и удаляем, а при удалении родительского все дочерние удаляются вместе с ним. Можете убедиться в этом проверив утечку памяти: 
    ReportMemoryLeaksOnShutdown := True; Sashar333 не используйте никогда .Name в качестве хранилища или идентификатора, это плохая практика. Для этих целей отлично подходят тэги (TagString или TagFloat), которые имеют все TFmxObject.
     
  23. Like
    Fedor K получил реакцию от Andrey Efimov в Удаление Item'ов из ListBox c помощью цикла while   
    Из приведенного выше кода ничего вручную удалять не нужно, кроме самого TListBoxItem, как и выполняется в примере выше (listbox1.Items.Delete(indexclick) или Form1.listbox1.Items.Delete(0)) . Все создаваемые дополнительные контролы (TGridPanelLayout, TRectangle, TText) создаются здесь с AOwner = TListBoxItem + задается Parent, который мы и удаляем, а при удалении родительского все дочерние удаляются вместе с ним. Можете убедиться в этом проверив утечку памяти: 
    ReportMemoryLeaksOnShutdown := True; Sashar333 не используйте никогда .Name в качестве хранилища или идентификатора, это плохая практика. Для этих целей отлично подходят тэги (TagString или TagFloat), которые имеют все TFmxObject.
     
  24. Like
    Fedor K получил реакцию от Равиль Зарипов (ZuBy) в Как отключить TLang на форме/компоненте?   
    Пожалуйста, внимательно посмотрите пример выше: cbbFiles: TComboBox;
    TComboBox содержит внутри себя TComboListBox с элементами списка, которые у вас автопереводятся. При помощи предоставленного выше примера автоперевод отключается. Если у Вас множество TComboBox, которым нужно запретить перевод, то можно воспользоваться таким способом:
    //Создаем helper для TComboBox type TComboBoxHelper = class helper for TComboBox public procedure SetAutoTranslate(AEnabled: Boolean = false); end; ... implementation ... { TComboBoxHelper } //Согласно примеру выше procedure TComboBoxHelper.SetAutoTranslate(AEnabled: Boolean); var i, count : integer; begin count := Self.Count - 1; for i := 0 to count do Self.ListBox.ListItems[i].AutoTranslate := AEnabled; end; ... //Пример использования helper в Вашем коде <Ваш TComboBox 1>.SetAutoTranslate; ... <Ваш TComboBox N>.SetAutoTranslate;  
  25. Like
    Fedor K получил реакцию от rareMax в Как отключить TLang на форме/компоненте?   
    Дело в том, что TComboBox лишь контейнер, вам нужно обращаться именно к списку элементов в ListBox. Чтобы запретить перевод можно поступить так:
    var i, count : integer; begin count := cbbFiles.Count - 1; for i := 0 to count do cbbFiles.ListBox.ListItems[i].AutoTranslate := False; end;  
×
×
  • Создать...