iOS Question Trying to port RSAsyncDownloader to B4i class

henrywood

Active Member
Licensed User
Longtime User
Hey !

I am trying to port the excellent B4A library called "RSAsyncDownloader" to B4i.

Could someone please have a look at the Objective C code ? I would very much appreciate it :)

If someone is wondering why I am asking all these Objective C related questions over the last week or so, I am A) trying to learn a bit about Objective C and B) trying to "level" the playing field between B4A and B4i so that functionality on both platforms can be approximately the same (for the functionality/features that my app uses anyway) even if many libraries are simply not available to B4i at the moment. Also I am trying to ensure that interfaces/API are as identical as can be between the two platforms so that the most amount of code may be reused (or at least that's for I am aiming for :))

I hope that the code can be of use to others. Feel free to grab it.

B4X:
'Class module

Sub Class_Globals
 
   Private FileName As String = ""
   Private Directory As String = ""
   Private ev As String = ""
   Private t As Object
 
End Sub

#If OBJC
- (void)downloadURL:(NSURL *)url (NSString *)dir (NSString *)file completionBlock:(void (^)(BOOL succeeded, NSData *image))completionBlock
{
  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

  [NSURLConnection sendAsynchronousRequest:request
  queue:[NSOperationQueue mainQueue]
  completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
  if ( !error )
  {
     completionBlock(YES,data);
     //NSLog(@"downloaded FULL size %lu",(unsigned long)data.length);
                 
                     if (file.length == 0) {

                       NSArray *parts = [url componentsSeparatedByString:@"/"];
                     NSString *filename = [parts lastObject];
                 
                     } else {
                       NSString *filename = file;
                     }
                 
                   // Construct fullpath
                   NSString *fullpath = [dir stringByAppendingFormat:@"%@/%@", filename];
                 
                   // Save
                   [data writeToFile:fullpath atomically:YES];
                 
                     // Raise event
                   [self.bi raiseEvent:nil event:@"downloadDone:" params:@[url]];
                 
  } else{
     completionBlock(NO,nil);
                 
                     // Raise event
                   [self.bi raiseEvent:nil event:@"downloadFailed:" params:@[url]];                 
                 
  }
  }];
}
#End if


'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(eventName As String, Target As Object)

   ev = eventName
   t = Target
 
End Sub

Public Sub setFileName(name As String)

   FileName = name

End Sub

Public Sub setDirectory(dir As String)

   Directory = dir

End Sub

Public Sub getFileName

   Return FileName

End Sub

Public Sub getDirectory

   Return Directory

End Sub

Sub Download(theURL As String)

   If Directory = "" Then
 
     ' We ought to throw an exception here but that is not possible ??
     Dim h As HUD
     h.ToastMessageShow("No Directory given ???")
     Return
   End If

   Dim n As NativeObject = Me

   If FileName = "" Then

     If SubExists(t, ev & "_Started") = True Then
       CallSub2(t, ev & "_Started")   
     End If

     n.RunMethod("downloadURL:", Array As Object(theURL, Directory, ""))

   Else

     If SubExists(t, ev & "_Started") = True Then
       CallSub2(t, ev & "_Started")   
     End If

     n.RunMethod("downloadURL:", Array As Object(theURL, Directory, FileName))

   End If

End Sub

' PRIVATE EVENTS
Private Sub downloadDone( URL As String )

   CallSub3(t, ev & "_Finished", URL, True)

End Sub

Private Sub downloadFailed( URL As String )

   CallSub3(t, ev & "_Finished", URL, False )

End Sub
 
Last edited:

henrywood

Active Member
Licensed User
Longtime User
@Erel Well, I am not sure if it is. When I started out in B4A a month ago, it just felt simpler and I hadn't looked much into HttpUtils at the time (so I am using it in the Android version of my app)
Also, I perceived the downloads of HttpUtils to be synchronous/serial (but I am most certainly wrong about that...)

I wanted to be able to do

DownloadAsync(url1, localFile1, callbackObj)
DownloadAsync(url2, localFile2, callbackObj)
DownloadAsync(url3, localFile3, callbackObj)
...etc...

from the same sub.

and in my Android app, DownloadSync is just a wrapper around the B4A RSAsyncDownloader library....
The DownloadAsync sub also manages a global list to where it adds all URLs for download *BEFORE* downloading and then removes them again once they complete.

The list is then used by a separate service to automatically re-fetch the URLs still in the list if internet connectivity is lost and then returns

But as I said, I am not sure that there is much of a difference to HttpUtils....
 
Last edited:
Upvote 0
Top