Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: performFetchWithCompletionHandler


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 2 - Last Post: Feb 17, 2016 6:36 AM Last Post By: Robert Björkman
Jonas Dandanell

Posts: 4
Registered: 7/12/15
performFetchWithCompletionHandler  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 10, 2016 1:55 AM
Could anyone give me a heads-up of how to start working with background processes (UIBackgroundModes) and performFetchWithCompletionHandler in Delphi? I have an app; I'm trying to get the app to make an external REST-call on an event that are triggered even in suspended mode. I can make stuff happen in event f.e. send local notification but the app are not allowing external data fetch.

I have set UIBackgroundModes to "fetch" but are pretty clueless about how to proceed. Have seen very few examples of working code for solving this. There are some examples in XCode (with performFetchWithCompletionHandler) but not for Delphi.
Dave Nottage

Posts: 1,850
Registered: 1/7/00
Re: performFetchWithCompletionHandler  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 13, 2016 12:56 AM   in response to: Jonas Dandanell in response to: Jonas Dandanell
Jonas Dandanell wrote:

Could anyone give me a heads-up of how to start working with background processes (UIBackgroundModes) and
performFetchWithCompletionHandler in Delphi? I have an app; I'm trying to get the app to make an external REST-call
on an event that are triggered even in suspended mode. I can make stuff happen in event f.e. send local notification
but the app are not allowing external data fetch.

I have set UIBackgroundModes to "fetch" but are pretty clueless about how to proceed. Have seen very few examples of
working code for solving this. There are some examples in XCode (with performFetchWithCompletionHandler) but not for
Delphi.

Have you come across this stackoverflow post?

http://stackoverflow.com/questions/23130639/calling-objective-c-code-block-from-delphi

They seem to have had some with success with it.

--
Dave Nottage [TeamB]
Delphi Worlds blog: http://delphi.radsoft.com.au/blog
Robert Björkman

Posts: 7
Registered: 10/1/11
Re: performFetchWithCompletionHandler  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 17, 2016 6:36 AM   in response to: Jonas Dandanell in response to: Jonas Dandanell
Jonas Dandanell wrote:
Could anyone give me a heads-up of how to start working with background processes (UIBackgroundModes) and performFetchWithCompletionHandler in Delphi? I have an app; I'm trying to get the app to make an external REST-call on an event that are triggered even in suspended mode. I can make stuff happen in event f.e. send local notification but the app are not allowing external data fetch.

I have set UIBackgroundModes to "fetch" but are pretty clueless about how to proceed. Have seen very few examples of working code for solving this. There are some examples in XCode (with performFetchWithCompletionHandler) but not for Delphi.

We're using it in our app.

interface
 
  uses     
    System.Classes,
    System.SysUtils,
    System.StrUTils,
    System.IOUtils,
    Macapi.ObjectiveC,
    Macapi.ObjCRuntime,
    iOSApi.Foundation,
    iOSApi.UIKit,
    iOSApi.QuartzCore,
    iOSApi.CocoaTypes,
    MacApi.Helpers,
    iOSapi.CoreGraphics;
 
 
 
type
  dispatch_object_t = IntPtr;
  dispatch_queue_t = dispatch_object_t;
  IMP = function( self : id; cmd : SEL; Param1 : NSUInteger ) : id; cdecl;
 
const
  libobjc = '/usr/lib/libobjc.dylib';
{$IF NOT DECLARED(_PU)}
const
  {$IFDEF UNDERSCOREIMPORTNAME}
  _PU = '_';
  {$ELSE}
  _PU = '';
  {$ENDIF}
  {$EXTERNALSYM _PU}
{$ENDIF}
 
  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 setUIBackgroundFetchInterval( const Interval : double );
 procedure performFetchWithCompletionHandler(self : id; _cmd : SEL; application: PUIApplication; handler : id );
 procedure BackgroundThreadTerminated( AResult : NSUInteger );
 
var
  Fetching : integer;
  FetchResult : NSUinteger;
  BackgroundRefresh : TRefreshProc;
 
 
implementation
 
procedure BackgroundThreadTerminated( AResult : NSUInteger );
begin
  FetchResult := AResult;
  Fetching := 0;
end;
 
procedure setUIBackgroundFetchInterval( const Interval : double );
 var UIApp : UIApplication;
begin
  UIApp := TUIApplication.Wrap(TUIApplication.OCClass.sharedApplication );
  if Assigned(UIApp) then
  begin
    if TOSVersion.Check(7,0) then
    begin
      _ConsoleLog(Format('Setting background fetch interval to %f',[Interval] ));
      objc_msgSendP((UIApp as ILocalObject).GetObjectId,
                 sel_getUid('setMinimumBackgroundFetchInterval:'),
                 @Interval);
      class_addMethod( objc_getClass('DelphiAppDelegate') ,
                    sel_getUid('application:performFetchWithCompletionHandler:'),
                    @performFetchWithCompletionHandler,
                    'v@:@?'
      );
      _ConsoleLog(Format('Background fetch interval set',[Interval] ));
    end;
    //class_addMethod( UIApp.delegate ,''
  end;
end;
 
procedure performFetchWithCompletionHandler(self : id; _cmd : SEL; application: PUIApplication; handler : id );
var t : TThread;
  context : TRttiContext;
  ahandlerimp : IMP;
begin
  //Begin Fetch
  Fetching := 1;
  FetchResult := 0;
  //Start Fetch Thread 
  BackgroundRefresh(BackGroundThreadTerminated);
  //Wait for fetch completed
  while Fetching = 1 do
  begin
    sleep(1000);
    _ConsoleLog(Format('performFetchWithCompletionHandler:waiting...',[]));
  end;
  Fetching := -1;
  _ConsoleLog(Format('performFetchWithCompletionHandler:done, result %d',[ FetchResult ]) );
 
  ahandlerimp := imp_implementationWithBlock( handler );
  ahandlerimp(self,_cmd,FetchResult );
  imp_removeBlock(ahandlerimp);
 
end;


Something like that
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02