Sorun Açıklaması:Delphi FireMonkey iOS arkaplan işleme
Şu anda geliştiriyorum ve Delphi XE7 FireMonkey sahip Android ve iOS uygulaması. Bu uygulamanın çevrimdışı çalışabilmesi için kullanıcı bununla çalışabilir ve telefon çevrimiçi olduğunda uygulama arka plandaysa veya telefon beklemede olsa bile uygulamanın tüm sunuculara gönderilmesini sağlar.
Android çalışma çözeltisi: öğrendim gibi
, uygulama arka planda çalışmaya başlar veya telefon stand by gider kez onlar yayından olarak TThread ve TTimer çalışmıyor nesneleri.
Bu kütüphaneyi bir TTimer nesnesi gibi çalışan android için bulmayı başardım ancak uygulama arka plana veya telefonun standında kaldığında çalışmaya devam ediyor. o TThread ve TTimer gibi davranır olarak
https://github.com/dkstar88/AsyncTask
Ne yazık ki iOS'ta çalışmaz ve uygulama arka planda çalışmaya başlar kez durur.
iOS Birkaç yaklaşımlar çalıştı çözümleri
çalıştı ama bir sürü insan Android hakkında bilgi ancak iOS için çok daha az bir yeri vardır bulundu.
Denediğim ilk şey, iOS'a arka planda bir şeyler yapmak istediğimi söylemek için gerekli izinleri plist dosyasına ekliyordu. "Getir" özelliğini denedim.
Yalnız bu, Android'de denenmiş TTimer, TThread veya AsyncTask ile çalışmaz.
Bu yüzden, iOS'a arka planda bir şeyler yapmak istediğinizi söylemelisiniz. IOS'ta ne zaman işlem yapılacağını veya kodun olmasını istediğinizi belirtin.
buldum en promsinig kodu bu bağlantıların (görünüm yorum) idi: Burada
http://qc.embarcadero.com/wc/qcmain.aspx?d=128968
önceki bağlantıdan uyarlanan kullandığım kod vardır. Test için bir not alanına sadece bir çizgi ekler.unit uBackgroundiOS_2;
interface
uses iOSapi.UIKit,Macapi.ObjCRuntime,Macapi.ObjectiveC,iOSapi.CocoaTypes,FMX.Platform.iOS,iOSapi.Foundation,Macapi.Helpers,
FMX.Memo, system.SysUtils;
const UIBackgroundFetchResultNewData:NSUInteger = 0;
UIBackgroundFetchResultNoData:NSUInteger = 1;
UIBackgroundFetchResultFailed:NSUInteger = 2;
UIApplicationBackgroundFetchIntervalMinimum:NSTimeInterval = 0;
UIApplicationBackgroundFetchIntervalNever:NSTimeInterval = -1;
type
id=Pointer;
IMP = function(self : id; cmd : SEL; Param1 : NSUInteger) : id; cdecl;
Var UIApp : UIApplication;
memo: TMemo;
function imp_implementationWithBlock(block :Pointer) : IMP; cdecl; external libobjc name _PU + 'imp_implementationWithBlock';
function imp_removeBlock(anImp : IMP) : integer; cdecl; external libobjc name _PU + 'imp_removeBlock';
function objc_addClass(Cls: Pointer): Integer; cdecl; external libobjc name _PU + 'objc_addClass';
procedure performFetchWithCompletionHandler(self:id; _cmd: SEL;application:id; handler:id);
procedure Init(p_memo: Tmemo);
implementation
procedure Init(p_memo: Tmemo);
var
Res: Integer;
begin
{
Info:
use .\plist\BackgroundOPs.info.plist from Project Main Pfad and copy to Info.plist
include the Keys:
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>remote-notification</string>
<string>newsstand-content</string>
</array>
}
UIApp := TUIApplication.Wrap(TUIApplication.OCClass.sharedApplication);
objc_msgSend((UIApp as ILocalObject).GetObjectId,sel_getUid('setMinimumBackgroundFetchInterval:'),UIApplicationBackgroundFetchIntervalMinimum);
Res := class_addMethod(objc_getClass('DelphiAppDelegate') , sel_getUid('application:performFetchWithCompletionHandler:'), @performFetchWithCompletionHandler,'[email protected]:@?');
memo := p_memo;
end;
procedure performFetchWithCompletionHandler(self:id; _cmd: SEL;application:id; handler:id);
{
Using your device you can fire application:performFetchWithCompletionHandler with the following steps:
Put your app in the Background state.
Lock your device and wait 5 minutes. (I know, it's a waste of time, get some coffee)
Unlock your device, this is will fire the method.
}
var
ahandlerimp: IMP;
begin
try
// here your code max. 30 Sec.
Memo.Lines.Add(FormatDateTime('hh:nn:ss', Now));
ahandlerimp := imp_implementationWithBlock(handler);
ahandlerimp(self,_cmd,UIBackgroundFetchResultNewData); // return the Do- code
imp_removeBlock(ahandlerimp);
except
end;
end;
end.
Bu, iphone 4'te iOS 8.4.1 ile çalışmıyor. Telefonu bir süre beklemede bıraktım ve uygulamayı kontrol ettiğimde not alanı boştu.
Neyin yanlış olabileceği hakkında bir fikriniz var mı? Burada biraz çıkmaz biriyim.
Çok teşekkürler!
Not: özgün yazımda daha fazla bağlantı ve kaynak ekledim (diğer stackoverflow yayınları dahil) ama maalesef en alakalı iki sayfayı bıraktım çünkü daha fazla yayınlamak için gereken 10 itibarı yok.
http://qc.embarcadero.com/wc/qcmain.aspx?d=128968 (bkz yorum) Bu kod çalışmıyor Calling objective C code block from delphi
unit uBackgroundiOS;
interface
uses fmx.platform.iOS,iOSapi.CocoaTypes, Macapi.ObjCRuntime, Macapi.ObjectiveC,
iOSapi.UIKit;
const
UIBackgroundFetchResultNewData:NSUInteger = 0;
UIBackgroundFetchResultNoData:NSUInteger = 1;
UIBackgroundFetchResultFailed:NSUInteger = 2;
UIApplicationBackgroundFetchIntervalMinimum:NSTimeInterval = 0;
UIApplicationBackgroundFetchIntervalNever:NSTimeInterval = -1;
type
// copied from fmx.platform.iOS as it's on private declaration
id = Pointer;
SEL = Pointer;
PUIApplication = Pointer;
IMP = function(self : id; cmd : SEL; Param1 : NSUInteger) : id; cdecl;
function imp_implementationWithBlock(block :id) : IMP; cdecl; external libobjc name _PU + 'imp_implementationWithBlock';
function imp_removeBlock(anImp : IMP) : integer; cdecl; external libobjc name _PU + 'imp_removeBlock';
procedure performFetchWithCompletionHandler(self : id; _cmd : SEL; application: PUIApplication; handler : id);
procedure initializeBackgroundFetch;
//to test if procedure is called in background
var fecth_string_test: string;
implementation
procedure performFetchWithCompletionHandler(self : id; _cmd : SEL; application: PUIApplication; handler : id);
var
ahandlerimp: IMP;
begin
//Code to perform fetch
fecth_string_test := 'entered background code!!';
ahandlerimp := imp_implementationWithBlock(handler); //Create c function for block
ahandlerimp(self,_cmd, UIBackgroundFetchResultNewData); //Call c function, _cmd is ignored
imp_removeBlock(ahandlerimp); //Remove the c function created two lines up
end;
procedure initializeBackgroundFetch;
Var
UIApp : UIApplication;
Interval: Pointer;
begin
UIApp := TUIApplication.Wrap(TUIApplication.OCClass.sharedApplication);
Interval := objc_msgSend((UIApp as ILocalObject).GetObjectId,
sel_getUid('setMinimumBackgroundFetchInterval:'));
// Interval);
class_addMethod(objc_getClass('DelphiAppDelegate') ,
sel_getUid('application:performFetchWithCompletionHandler:'),
@performFetchWithCompletionHandler,
'[email protected]:@?'
);
end;
end.
: Bu iki örnekte kod Karıştırma
i aşağıdaki birimi yaptı. Uygulama başladığında initializeBackgroundFetch çağrısı. Eminim yanlış bir şey yapıyorum ama ne olduğunu anlayamıyorum.
Ayrıca, uygulamanızın arka planda görünmemesine izin verdiğimi fark ettim. Aşağıdakileri info.plist dosyasında ekledim:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
[...]
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>remote-notification</string>
<string>newsstand-content</string>
</array>
</dict>
</plist>
Herhangi bir fikir var mı?
Ek kaynaklar: iOS arkaplan özellikleri: [link] (http://delphi.radsoft.com (ı Getirme kullanılan)
2- Bu kullandığım kodudur ihtiyaç UIBackgroundModes Kontrol .au/2013/10/sağlama-arka plan-hizmetler-destek-kendi-ios-apps-ile-delphi /) StackOverflow ilgili bağlantı: [link] (https://stackoverflow.com/questions/24168144/ delphi-firemonkey-ios-background-fetch) Amaç-C örnekleri: [bağlantı] (http://hayageek.com/ios-background-fetch/) [li nk] (https://possiblemobile.com/2013/09/ios-7-background-fetch/) –
Ayrıca bunu denedim [link] (http://codeverge.com/embarcadero.delphi.ios/does-delphi- for-ios-support-complete-b/1095555) Ancak "Harici istisna 0" yükseltir. –
, ana postayı yeni kod –