iOS Tutorial Background Fetch (Downloads)

Background fetch feature allows applications to run for a short period of time (up to 30 seconds) while in the background.

The steps required to use this service are:
1. Add the fetch mode declaration:
B4X:
#PlistExtra: <key>UIBackgroundModes</key><array><string>fetch</string></array>
2. Download the attached zip file and copy main.m to <project>\Files\Special.
3. Set the minimum interval (measured in seconds) with this code:
B4X:
Dim no As NativeObject = App
no.RunMethod("setMinimumBackgroundFetchInterval:", Array(0)) '0 = minimum interval

4. Handle the Application_FetchDownload event. It will be raised whenever your app is waked by this service:
B4X:
Private Sub Application_FetchDownload
   Log("FetchDownload")
   Dim ln As Notification
   ln.Initialize(DateTime.Now)
   ln.AlertBody = "Fetch download..."
   ln.PlaySound = True
   ln.Register
End Sub

5. When you completed the task you should run this code:
B4X:
Dim no As NativeObject = App
   no = no.GetField("delegate")
   no.RunMethod("completeFetch:", Array(0))
Note that you can run this code from any sub you like (JobDone for example).
The number (0 in the code above) is the UIBackgroundFetchResult. 0 means NewData.
The other values are listed here: https://developer.apple.com/library...ml#//apple_ref/c/tdef/UIBackgroundFetchResult

From my tests, with the minimum interval set to 0, the OS wakes the app every 10 - 15 minutes (when the screen is on).

B4X:
#Region  Project Attributes
   #ApplicationLabel: Background Fetch
   #Version: 1.0.0
   #iPhoneOrientations: Portrait, LandscapeLeft, LandscapeRight
   #iPadOrientations: Portrait, LandscapeLeft, LandscapeRight, PortraitUpsideDown
   #PlistExtra: <key>UIBackgroundModes</key><array><string>fetch</string></array>
#End Region

Sub Process_Globals
   Public App As Application
   Public NavControl As NavigationController
   Private Page1 As Page

End Sub

Private Sub Application_Start (Nav As NavigationController)
   NavControl = Nav
   Page1.Initialize("Page1")
   Page1.Title = "Page 1"
   Page1.RootPanel.Color = Colors.White
   NavControl.ShowPage(Page1)
   Dim no As NativeObject = App
   no.RunMethod("setMinimumBackgroundFetchInterval:", Array(0))
End Sub

Private Sub Application_FetchDownload
   Log("FetchDownload")
   Dim ln As Notification
   ln.Initialize(DateTime.Now)
   ln.AlertBody = "Fetch download..."
   ln.PlaySound = True
   ln.Register

   Dim no As NativeObject = App
   no = no.GetField("delegate")
   no.RunMethod("completeFetch:", Array(0))
End Sub
 

Attachments

  • main.zip
    516 bytes · Views: 775
Last edited:

MarcoRome

Expert
Licensed User
Longtime User
if you @Erel or your team or other colleagues can try the attached code in post #38 and tell me if they work.
He doesnt work here. Tested on 2 iphone ( iphone 6s with 11.4 and xPhone )
Perhaps because it is compiled with the B4i 5.0 version ?
Maybe because some part of the code is wrong ?
I dont know but anyway it doesnt work.
Thank you again all
Marco
 

MarcoRome

Expert
Licensed User
Longtime User
I'm checking it. If you have a local Mac then you can monitor the logs and you will see that the OS mostly doesn't allow any app to start in the background. I'm still monitoring it to see if it will eventually run.

Hi @Erel thank you for your time

I tried with B4iLogger, but as you can see from the movie, after almost an hour no event ( Application_FetchDownload ) is Raised
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
After testing it for 24 hours I can say that it works properly.

I've created a simple app that counts the number of times FetchDownload is called:

B4X:
'app start
If File.Exists(File.DirDocuments, "1.txt") = False Then
       File.WriteString(File.DirDocuments, "1.txt", 0)
   End If

Sub Application_Active
   Page1.Title = "Value: " & File.ReadString(File.DirDocuments, "1.txt")
  
End Sub

Private Sub Application_FetchDownload
   Log("FetchDownload")
   File.WriteString(File.DirDocuments, "1.txt", File.ReadString(File.DirDocuments, "1.txt") + 1)
   Dim no As NativeObject = App
   no = no.GetField("delegate")
   no.RunMethod("completeFetch:", Array(0))
End Sub

Monitoring the system logs shows that many apps try to start in the background and the OS gives a score to each one. Only Apple knows how the score is calculated. I assumed that the app should be used from time to time so I started every couple of hours.
The first FetchDownload event happened after about 12 hours. It was raised another 11 times in the following 12 hours.

System logs:
SS-2018-06-12_13.27.44.png


Don't use iReleaseLogger with fetch download as it can cause the process to fail to start.
Don't show a notification. Maybe the OS doesn't like.

It is probably not relevant however I used an app that also implements push notifications.
 

MarcoRome

Expert
Licensed User
Longtime User
The first FetchDownload event happened after about 12 hours. It was raised another 11 times in the following 12 hours.

I would say to forget it is not very reliable.
@Erel thank you for your support and your time it's really exceptional.
Marco
 

Sasuke Sama

Active Member
Licensed User
Using this can i download larg files ( about 150 MB ) in the background ? And start the download from within the app
In other words can i make a download manager app with it?
 
Top