• Apfeltalk ändert einen Teil seiner Allgemeinen Geschäftsbedingungen (AGB), das Löschen von Useraccounts betreffend.
    Näheres könnt Ihr hier nachlesen: AGB-Änderung
  • Viele hassen ihn, manche schwören auf ihn, wir aber möchten unbedingt sehen, welche Bilder Ihr vor Eurem geistigen Auge bzw. vor der Linse Eures iPhone oder iPad sehen könnt, wenn Ihr dieses Wort hört oder lest. Macht mit und beteiligt Euch an unserem Frühjahrsputz ---> Klick

NSURLDownload abbrechen

julian_mac

Grahams Jubiläumsapfel
Registriert
30.05.14
Beiträge
107
Hallo zusammen, habe aus dieser Quelle einen Browser programmiert. Alles funktioniert excellent, jedoch wünsche ich mir eine Funktion, mit der ich aktive Downloads per Knopfdruck abbrechen kann. Stundenlange Probiererei und Recherche im Internet haben nichts geholfen. Hat jemand eine Idee?

Danke für Eure Hilfe!
 

MacApple

Schöner von Bath
Registriert
05.01.04
Beiträge
3.652
NSURLDownload hat eine Methode cancel. Einfacher geht es kaum, einen Download abzubrechen.
 
  • Like
Reaktionen: julian_mac

DubiDuh

Zwiebelapfel
Registriert
20.05.08
Beiträge
1.288
Stundenlange Probiererei und Recherche im Internet haben nichts geholfen. Hat jemand eine Idee?

Ja, APIs lesen lernen :) - Denn die API zum Interface NSURLDownload ist links in der Leiste und es wird "cancel" als Methode angezeigt, sogar mit der Überschrift "Cancel Download".
 
  • Like
Reaktionen: julian_mac

julian_mac

Grahams Jubiläumsapfel
Registriert
30.05.14
Beiträge
107
Hallo MacApple und DubiDuh!
Danke für Eure schnelle Antworten!

Ich bin noch ein Frischling und stoppe gerade hier, könnt Ihr mir nochmals helfen?

- (void)cancel{
setDeletesFileUponFailure: NO
}

Aber wie kann ich diese Aktion bei Knopfdruck ausführen?
Hätte mir das eher so vorgestellt:

- (IBAction)StoppeDownload:(id)sender {

//hier die Stopfunktion
setDeletesFileUponFailure: NO
}


DANKE!
 

MacApple

Schöner von Bath
Registriert
05.01.04
Beiträge
3.652
Hätte mir das eher so vorgestellt:

Code:
- (IBAction)StoppeDownload:(id)sender {

//hier die Stopfunktion
setDeletesFileUponFailure: NO
}
Das ist ja auch schon der richtige Ansatz. Du musst halt in dieser Action Methode cancel an deine NSURLDownload Instanz schicken.
 

Schniko

Reinette Coulon
Registriert
01.08.08
Beiträge
954
Vielleicht nochmal deutlicher:
Code:
//Irgendwo in deiner App sollte die Instanz mal erstellt worden sein. In etwa so:
NSURLDownload *deinName = [[NSURLDownload alloc] init];

...

//Zum Abbrechen dann entsprechend meiner Vorredner
[deinName cancel];
Du schickst die Cancel Methode direkt an deinen spezifischen Download.
 
  • Like
Reaktionen: julian_mac

julian_mac

Grahams Jubiläumsapfel
Registriert
30.05.14
Beiträge
107
Diese Instanz lässt sich finden:

NSURLDownload *down = [[NSURLDownload alloc] initWithRequest:request delegate:cellViewController];

[down setDestination:filePath allowOverwrite:NO];

Die Downloads werden jetzt zwar gestoppt beim Drücken des Buttons, aber die App gleich mit.
Xcode liefert eine Fehlermeldung, wie auf dem Screenshot zu sehen. Bildschirmfoto 2015-02-17 um 09.01.13.png
 

Schniko

Reinette Coulon
Registriert
01.08.08
Beiträge
954
Momentan legst du eine neue Instanz an, die "down" heißt, und willst diese dann direkt canceln. Das geht so nicht. Du darfst die nicht neu deklarieren, sondern die Instanz nehmen, die vorher den Download gestartet hat.
 

julian_mac

Grahams Jubiläumsapfel
Registriert
30.05.14
Beiträge
107
Aber wenn ich die Instanz nicht noch einmal festlege, dann sagt mir xcode, dass down nicht bekannt sei.

Hier meine Downlaod Delegate

Code:
//Download Delegate

- (void)webView:(WebView *)sender decidePolicyForMIMEType:(NSString *)type request:(NSURLRequest *)request frame:(WebFrame *)frame

decisionListener:(id < WebPolicyDecisionListener >)listener

{


    if ([type isNotEqualTo:mad:"text/html"]) {

        [listener use];

    

        NSURL *url = [request URL];

    

        NSArray *parts = [[[url absoluteString] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] componentsSeparatedByString:mad:"/"];

        NSString *filename = [parts objectAtIndex:[parts count]-1];

    

        if([filename rangeOfString:mad:"?"].location != NSNotFound)

        {

            NSArray *names = [filename componentsSeparatedByString:mad:"?"];

            filename = [names objectAtIndex:0];

        }

    

        NSString *homePath = [self homeDirectory];

        NSString *filePath = [NSString stringWithFormat:mad:"%@/Downloads/%@", homePath, filename];

    

        DownloadData *downloadData = [[DownloadData alloc] init];

        downloadData.fileName = filename;

        downloadData.fileSize = 0;

    

        [listDownloadDatas addObject:downloadData];

    

        upDownCellViewController * cellViewController = [[upDownCellViewControlleralloc] init];

        [cellViewController initWithData:downloadData];

    

        [cellViewControllers addObject:cellViewController];

    

        NSURLDownload *down = [[NSURLDownload alloc] initWithRequest:request delegate:cellViewController];

        [down setDestination:filePath allowOverwrite:NO];

    

        [self.downloadTableViewreloadData];

        [AppDelegatesetArrayForKey:listDownloadDatasforKey:mad:"DownloadData"];

        NSLog(@"Download did start");

    

        return;

    }


    [listener use];

    NSLog(@"%@", type);

}
 
Zuletzt bearbeitet:

nomos

Borowinka
Registriert
22.12.03
Beiträge
7.721
Und jetzt verpack deine Antwort noch in Code-tags, damit wir keine Smileys sehen.
 

Schniko

Reinette Coulon
Registriert
01.08.08
Beiträge
954
Ja, du legst down innerhalb dieser Methode als lokales Objekt an. Wenn du später da noch ran willst, kommst du so nicht mehr an den Pointer. Am einfachsten ist es, wenn du ganz zu Beginn dieser Klasse down als property anlegst, also so, dass du es als _down benutzen kannst. Dann kannst du später auch darauf zugreifen.
 

julian_mac

Grahams Jubiläumsapfel
Registriert
30.05.14
Beiträge
107
Ah das Prinzip habe ich verstanden, aber wie mache ich das konkret?

Also erstmal hier mein Button:
Code:
//DownloadsAbbrechen
- (IBAction)stopDownload:(id)sender {

    [_down cancel];

    setDeletesFileUponFailure: NO;

}

Und dann die Property:
Code:
@property (weak) ... *down;

Als was für einen Typ lege ich diese Property an?
 

julian_mac

Grahams Jubiläumsapfel
Registriert
30.05.14
Beiträge
107
Nach langem recherchieren bin ich immer noch nicht voran gekommen.
Kann mir jemand verraten, wie man die property hier anlegt?
 

martinv2

Doppelter Prinzenapfel
Registriert
14.04.12
Beiträge
437
Warum sollte sich der Typ durch die Deklaration als Property ändern?
Benutze NSURLDownload*
 
  • Like
Reaktionen: julian_mac

julian_mac

Grahams Jubiläumsapfel
Registriert
30.05.14
Beiträge
107
Warum sollte sich der Typ durch die Deklaration als Property ändern?
Benutze NSURLDownload*

Danke für deine Antwort martinv2,
nachdem ich die property angelegt habe und mein Code folgendermaßen ausschaut, wird immer noch nicht der gewünschte Effekt erreicht den Download abzubrechen. Wenn ich nun den Button gedrückt halte, der den Download abbrechen sollte, dann stoppt der Download. Beim loslassen des Buttons wird er wieder fortgesetzt. Was nun?

Code:
- (IBAction)CancelActiveDownload:(id)sender {
    [self DownloadAbbrechen];

}
- (void)DownloadAbbrechen{
    NSLog(@"Downlaod was successfully stopped");
    [_down cancel];
    setDeletesFileUponFailure: NO;
}
 

Schniko

Reinette Coulon
Registriert
01.08.08
Beiträge
954
Wo legst du denn _down an?
Und was soll die Zeile
Code:
 setDeletesFileUponFailure: NO;
bedeuten? Die ergibt schon vom Syntax her keinen Sinn.
 

julian_mac

Grahams Jubiläumsapfel
Registriert
30.05.14
Beiträge
107
Das
setDeletesFileUponFailure: NO;
sorgt dafür, dass die Dateien nach dem Abbrechen des Downloads nicht gelöscht werden.

AppDelegate.h


Code:
@interface AppDelegate : NSViewController <NSApplicationDelegate, NSPopoverDelegate, NSTableViewDataSource, NSTableViewDelegate, NSApplicationDelegate, NSUserNotificationCenterDelegate, NSURLDownloadDelegate>
{
    NSMutableArray *cellViewControllers;
    NSMutableArray *listDownloadDatas;
    IBOutlet NSProgressIndicator *progressIndicator;
    NSURLConnection *_urlConnection;
    NSURLRequest *_request;
    NSURLDownload*_down;
   
   
}


AppDelegate.m
Code:
//Download Delegate

- (void)webView:(WebView *)sender decidePolicyForMIMEType:(NSString *)type request:(NSURLRequest *)request frame:(WebFrame *)frame

decisionListener:(id < WebPolicyDecisionListener >)listener

{


    if ([type isNotEqualTo:mad:"text/html"]) {

        [listener use];

  

        NSURL *url = [request URL];

  

        NSArray *parts = [[[url absoluteString] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] componentsSeparatedByString:mad:"/"];

        NSString *filename = [parts objectAtIndex:[parts count]-1];

  

        if([filename rangeOfString:mad:"?"].location != NSNotFound)

        {

            NSArray *names = [filename componentsSeparatedByString:mad:"?"];

            filename = [names objectAtIndex:0];

        }

  

        NSString *homePath = [self homeDirectory];

        NSString *filePath = [NSString stringWithFormat:mad:"%@/Downloads/%@", homePath, filename];

  

        DownloadData *downloadData = [[DownloadData alloc] init];

        downloadData.fileName = filename;

        downloadData.fileSize = 0;

  

        [listDownloadDatas addObject:downloadData];

  

        upDownCellViewController * cellViewController = [[upDownCellViewControlleralloc] init];

        [cellViewController initWithData:downloadData];

  

        [cellViewControllers addObject:cellViewController];

  

        NSURLDownload *down = [[NSURLDownload alloc] initWithRequest:request delegate:cellViewController];

        [down setDestination:filePath allowOverwrite:NO];

  

        [self.downloadTableViewreloadData];

        [AppDelegatesetArrayForKey:listDownloadDatasforKey:mad:"DownloadData"];

        NSLog(@"Download did start");

  

        return;

    }


    [listener use];

    NSLog(@"%@", type);

}


DownloadController.m

Code:
- (IBAction)CancelActiveDownload:(id)sender {
    [self DownloadAbbrechen];

}
- (void)DownloadAbbrechen{
    NSLog(@"Downlaod was successfully stopped");
    [_down cancel];
    setDeletesFileUponFailure: NO;
}
 

Schniko

Reinette Coulon
Registriert
01.08.08
Beiträge
954
Du legst hier
Code:
NSURLDownload *down = [[NSURLDownload alloc] initWithRequest:request delegate:cellViewController];

        [down setDestination:filePath allowOverwrite:NO];
down an, nicht aber _down. Folglich existiert down nur innerhalb dieser Methode und du kannst später nicht darauf zugreifen. Mach also in den beiden oberen Zeilen ein _down daraus und es wird Wunder wirken.

Zu "setDeletesFileUponFailure": Kompiliert er denn mit dieser Zeile überhaupt? Denn so, wie es da steht, darf es eigentlich nicht gehen.