RACSignal的一些常用用法


NSData + RACSupport.h

@interface NSData (RACSupport)

// Read the data at the URL using -[NSData initWithContentsOfURL:options:error:].
// Sends the data or the error.
// 返回一個URL異步請求的信號量
// scheduler 不能為空
+ (RACSignal *)rac_readContentsOfURL:(NSURL *)URL options:(NSDataReadingOptions)options scheduler:(RACScheduler *)scheduler;

@end

 NSData

嘗試這個例子之前,請在Demo工程的info.plist文件中加入App Transport Security Settings鍵值,並加入Allow Arbitrary Loads:YES鍵值對,用來開啟iOS下的非安全連接。

 

可以這樣用

NSURL* url = [NSURL URLWithString:@"http://www.jianshu.com"];
RACSignal* getDataSignal = [NSData rac_readContentsOfURL:url options:NSDataReadingUncached
                                       scheduler:[RACScheduler mainThreadScheduler]];
[getDataSignal subscribeNext:^(id x) {
    NSLog(@"%@",x);  //這里的x就是NSData數據
}];

 

map函數

如果我們使用NSDatarac_readContentsOfURL:url方法下載的是一張圖片,我們肯定希望這個Signal最后輸出的是UIImage對象,這里就要用到非常常用的map函數。

map函數就像signal 管道上的中間處理器,從這里走過的signal都會經過一段處理后,變成新的signal繼續傳輸。而這個處理過程則在map函數中由開發者決定。

將輸出NSDatasignal轉換為輸出UIImage

NSURL* url = [NSURL URLWithString:@"http://img1.gtimg.com/gamezone/pics/24159/24159840.jpg"];
RACSignal* getDataSignal = [NSData rac_readContentsOfURL:url options:NSDataReadingUncached
                                       scheduler:[RACScheduler mainThreadScheduler]];
    
//map函數進行轉換
RACSignal* getImageSignal = [getDataSignal map:^id(id value) {
        if (value) {
            return [UIImage imageWithData:value];
        }
        return nil;
}];
    
[getImageSignal subscribeNext:^(id x) {
        NSLog(@"%@",x);
}];

 

merge方法

接着我們提出一個新需求,同時請求三張不同的圖片,並將它們發送的信號合並成一條信號量。這里就需要用到信號量的merge方法,如下

NSURL* url = [NSURL URLWithString:@"http://img1.gtimg.com/gamezone/pics/24159/24159840.jpg"];
NSURL* url2 = [NSURL URLWithString:@"http://i3.hoopchina.com.cn/blogfile/201306/29/137247593017986.jpg"];
NSURL* url3 = [NSURL URLWithString:@"http://img.youxile.com/pic/1301/25170237170.jpg"];
RACSignal* getImageSignal1 = [[NSData rac_readContentsOfURL:url
                                                       options:NSDataReadingUncached
                                                     scheduler:[RACScheduler mainThreadScheduler]]
                                 map:^id(id value) {
        if (value) {
            return [UIImage imageWithData:value];
        }
        return nil;
}];
    
RACSignal* getImageSignal2 = [[NSData rac_readContentsOfURL:url2
                                                        options:NSDataReadingUncached
                                                      scheduler:[RACScheduler mainThreadScheduler]]
                                  map:^id(id value) {
                                      if (value) {
                                          return [UIImage imageWithData:value];
                                      }
                                      return nil;
                                  }];
    
RACSignal* getImageSignal3 = [[NSData rac_readContentsOfURL:url3
                                                        options:NSDataReadingUncached
                                                      scheduler:[RACScheduler mainThreadScheduler]]
                                  map:^id(id value) {
                                      if (value) {
                                          return [UIImage imageWithData:value];
                                      }
                                      return nil;
                                  }];

                                 
//合並操作
RACSignal* mergeSignal = [RACSignal merge:@[getImageSignal1,getImageSignal2,getImageSignal3]];
    
    [mergeSignal subscribeNext:^(id x) {
        NSLog(@"%@",x);
}];```

輸出如下:
2015-12-30 10:19:08.776 Fahu[1354:39991] <UIImage: 0x7f9ce2ac3730>, {450, 600}
2015-12-30 10:19:08.891 Fahu[1354:39991] <UIImage: 0x7f9ce2b02600>, {500, 687}
2015-12-30 10:19:09.098 Fahu[1354:39991] <UIImage: 0x7f9ce29a4500>, {500, 346}

 

###filter函數

網絡也會有連不上的時候,三張圖片中如果有哪一張請求失敗,我們並不想讓`signal`發送`nil`值過來,可以使用filter函數對`signal`進行篩選。稍微改造一下上面的`mergeSignal`:
RACSignal* mergeSignal = [[RACSignal merge:@[getImageSignal1,getImageSignal2,getImageSignal3]] filter:^BOOL(id value) {

return @(!!value);
}];`

 

注意這里的filter函數返回的是NSNumber型的BOOL值,YES是通過,NO時拒絕通過。

NSURLConnection

有了RAC,一些簡單的網絡請求都可以不用AF框架了。

NSURLConnection+RACSupport.h

+ (RACSignal *)rac_sendAsynchronousRequest:(NSURLRequest *)request;```

舉個例子,還是請求圖片
NSURL* url = [NSURL URLWithString:@"http://img1.gtimg.com/gamezone/pics/24159/24159840.jpg"];

NSURLRequest* request = [NSURLRequest requestWithURL:url];
RACSignal* connectionSignal = [NSURLConnection rac_sendAsynchronousRequest:request];
[connectionSignal subscribeNext:^(id x) {
    NSLog(@"%@",x);
}];`

輸出

 <RACTuple: 0x7f826c071c00>  ...省略```

注意,這個`signal`發送的信號量是一個`RACTuple`對象。

###RACTuple

`RACTuple`(元組)類,是`RAC`中專門用來返回多個返回值的類,這個設計很像swift中的元組。

上面例子中的`RACTuple`有兩個返回值,`x[0]`是http response的頭部信息,`x[1]`是請求返回的數據,是一個`NSData`對象。元組類對象的讀取方法和數組相同。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM