AP102 2016/5/26 下午

AP102 2016/5/26 下午

RSS Reader on IOS

Master-Detail Application
Project-name:HelloMyRss

The view on iPad and iPhone is different.
On iPad view the TableViewController will at the left side.

And The iPhone 6 plus have other view !
when the monitor is straight the view is the same with iPhone.
But when you rotate the monitor the view is the same with iPad.

1.import SystemConfiguration.framework
2.copy Reachability.h
3.This log is show both the if and else condition!


2016-05-26 14:11:08.073 HelloMyRSS[2040:257955] Reachability Flag Status: -- ------- networkStatusForFlags
2016-05-26 14:11:08.074 HelloMyRSS[2040:257955] NetWork not available.

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.navigationItem.leftBarButtonItem = self.editButtonItem;

    UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)];
    self.navigationItem.rightBarButtonItem = addButton;
    self.detailViewController = (DetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];

    //-> Prepare serverReach
    serverReach = [Reachability reachabilityWithHostName:@"appledaily.com.tw""];
    [serverReach startNotifier];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkStatusChanged) name:kReachabilityChangedNotification object:nil];
}

//->
-(void) networkStatusChanged{
    //NetworkStatus 知道連得上連不上 還知道用什麼連
    NetworkStatus status =[serverReach currentReachabilityStatus];
    if (status == NotReachable) {
        //...
        NSLog(@"NetWork not available.");
    }else{
        [self downloadNewsList];
    };

}

-(void)downloadNewsList{

}

change button 1.edit and 2. +
which you see on the simulator
attach to viewDidiLoad inside

//    self.navigationItem.leftBarButtonItem = self.editButtonItem;
//
//    UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)];
//    self.navigationItem.rightBarButtonItem = addButton;


At this Time
The UI button is ” not “already show on the simulator.

    UIBarButtonItem *refreshBtn = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(downloadNewsList)];


     self.navigationItem.rightBarButtonItem = refreshBtn;

To finish the function downloadNewsList
This step will get the Rss From the sample Website Yahoo!


-(void)downloadNewsList{

    if([serverReach currentReachabilityStatus] == NotReachable){
        return;
    }

    NSString * targetURLString =@"https://tw.news.yahoo.com/sentiment/odd/rss/";

    NSURL * url = [NSURL URLWithString:targetURLString];
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession * session = [NSURLSession sessionWithConfiguration:config];

    NSURLSessionDataTask * task=[session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

    }];

}


Apple templetes in
viewControllers get an array

the array get two things
1.detail viewcontroller
2.Navigation Controller

which is outside
so you need to use topViewController get the inside.

and you could got the other Sample code to understand what the function do.

self.detailViewController = (DetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];


    //The code above is the same with the followings:
    NSArray * viewControllers = self.splitViewController.viewControllers;
    UINavigationController * navigationController = [viewControllers lastObject];
    self.detailViewController = (DetailViewController*)[navigationController topViewController];
  (void)downloadNewsList{

    if([serverReach currentReachabilityStatus] == NotReachable){
        return;
    }

    NSString * targetURLString =@"https://tw.news.yahoo.com/sentiment/odd/rss/";

    NSURL * url = [NSURL URLWithString:targetURLString];
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession * session = [NSURLSession sessionWithConfiguration:config];

    NSURLSessionDataTask * task=[session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

        if (error) {
            NSLog(@"Error:%@",error);
            return;

        }
        NSString *rssContent = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];

        NSLog(@"Rss content :%@",rssContent);

    }];

}

New Class

New file a class Named NewsItem

#import <UIKit/UIKit.h>

@interface NewsItem : UITableViewCell

@property (nonatomic,strong)NSString*title;
@property (nonatomic,strong)NSString*link;
@property (nonatomic,strong)NSString*pubDate;


@end


Atomic <–>Nonatomic


For Mutual exclusion : atomic
Effective is bad;

Non Mutual exclusion : nonatomic
Effective is Good;

MultiThread Concept 

To Create a Parse delegate
//Download doc –> XML —>Parse Delegate

New a Class RSSParserDelegate

1.import NewsItem.h
2.build framework
let the RSSParserDelegate to know
It’s a Protocol

//
//  RSSParserDelegate.h
//  HelloMyRSS
//
//  Created by Financialbrain on 2016/5/26.
//  Copyright © 2016年 DarisCode. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "NewsItem.h"
@interface RSSParserDelegate : UITableViewCell<NSXMLParserDelegate>

@end


u need to create the last three protocol methods

//
//  RSSParserDelegate.m
//  HelloMyRSS
//
//  Created by Financialbrain on 2016/5/26.
//  Copyright © 2016年 DarisCode. All rights reserved.
//

#import "RSSParserDelegate.h"

@implementation RSSParserDelegate

///Start tag and End tag
///Control With ElementName(tag)
///foundCharacters to return not a tag text

-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict{}

-(void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{}

-(void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
}

- (void)awakeFromNib {
    [super awakeFromNib];
    // Initialization code
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

@end


Attach Variables below code @@implementation

@interface RSSParserDelegate()
{

    NSMutableArray * results;
    NSMutableString * valueOfCurrentElement;
    NewsItem*currentNewItem;<--U Created!

}

@end


Add below method @@implementation
To build you init

instancetype –> Automatic Type Check !

To Avoid Typed is Wrong !

Especially inherit Class !

-(instancetype*) init{

    self = [super init];

    results = [NSMutableArray new];

    return self;
}
-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict{

    if([elementName isEqualToString:@"item"]){

    }else if ([elementName isEqualToString:@"title"]){

    }else if ([elementName isEqualToString:@"link"]){

    }else if ([elementName isEqualToString:@"pubDate"]){

    }


}
-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict{

    if([elementName isEqualToString:@"item"]){

        currentNewItem=[NewsItem new];

    }else if ([elementName isEqualToString:@"title"]){

        valueOfCurrentElement = nil;//碰到所關心的標頭時就清空

    }else if ([elementName isEqualToString:@"link"]){

        valueOfCurrentElement = nil;

    }else if ([elementName isEqualToString:@"pubDate"]){

        valueOfCurrentElement = nil;

    }


}
-(void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
    if([elementName isEqualToString:@"item"]){

        [results addObject:currentNewItem];//放進result
        currentNewItem = nil;//清掉

    }else if ([elementName isEqualToString:@"title"]){

        currentNewItem.title = valueOfCurrentElement;

    }else if ([elementName isEqualToString:@"link"]){

         currentNewItem.link = valueOfCurrentElement;

    }else if ([elementName isEqualToString:@"pubDate"]){

         currentNewItem.pubDate = valueOfCurrentElement;

    }
    valueOfCurrentElement=nil;

}

    if(valueOfCurrentElement == nil){
        valueOfCurrentElement = [[NSMutableString alloc]
                                 initWithString:string];//需要逐漸收內容
    }else{

        [valueOfCurrentElement appendString:string];

    }
}
//
//  RSSParserDelegate.h
//  HelloMyRSS
//
//  Created by Financialbrain on 2016/5/26.
//  Copyright © 2016年 DarisCode. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "NewsItem.h"
@interface RSSParserDelegate : UITableViewCell<NSXMLParserDelegate>

-(NSArray*) getResults;

@end


Back to .m

-(NSArray*) getResults{

    return results;

}


Go to MasterViewController.m

#import "RSSParserDelegate.h"
// delegate management. The delegate is not retained.
@property (nullable, assign) id <NSXMLParserDelegate> delegate;

所以protocol當初要放在.h


Beginning
//Parse the XML Content

parser.delegate = parserDelegate;

-(void)downloadNewsList{

    if([serverReach currentReachabilityStatus] == NotReachable){
        return;
    }

    NSString * targetURLString =@"http://www.appledaily.com.tw/rss/newcreate/kind/rnews/type/new";

    NSURL * url = [NSURL URLWithString:targetURLString];
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession * session = [NSURLSession sessionWithConfiguration:config];

    NSURLSessionDataTask * task=[session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

        if (error) {
            NSLog(@"Error:%@",error);
            return;

        }


        NSString *rssContent = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];

        NSLog(@"Rss content :%@",rssContent);


        //Parse the XML Content

        NSXMLParser * parser = [[NSXMLParser alloc]initWithData:data];
        RSSParserDelegate * parserDelegate =[RSSParserDelegate new];
        parser.delegate = parserDelegate;

        BOOL success = [parser parse];

        if(success) {
            NSLog(@"Parse OK.");
        }else{
            NSLog(@"Parse Fail.");
        }


    }];
    [task resume];
}
//
//  MasterViewController.m
//  HelloMyRSS
//
//  Created by Financialbrain on 2016/5/26.
//  Copyright © 2016年 DarisCode. All rights reserved.
//

#import "MasterViewController.h"
#import "DetailViewController.h"
#import "Reachability.h"
#import "RSSParserDelegate.h"


@interface MasterViewController ()
{
    Reachability * serverReach ;

}
@property NSMutableArray *objects;
@end

@implementation MasterViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
//    self.navigationItem.leftBarButtonItem = self.editButtonItem;
//
//    UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)];
//    self.navigationItem.rightBarButtonItem = addButton;
    UIBarButtonItem *refreshBtn = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(downloadNewsList)];

     self.navigationItem.rightBarButtonItem = refreshBtn;


    self.detailViewController = (DetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];

    //The code above is the same with the followings:
    NSArray * viewControllers = self.splitViewController.viewControllers;
    UINavigationController * navigationController = [viewControllers lastObject];
    self.detailViewController = (DetailViewController*)[navigationController topViewController];

    //-> Prepare serverReach
    serverReach = [Reachability reachabilityWithHostName:@"appledaily.com.tw"];
    [serverReach startNotifier];

    //tw.new.yahoo.com
    //->主動通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkStatusChanged) name:kReachabilityChangedNotification object:nil];
}

//->
-(void) networkStatusChanged{
    //NetworkStatus 知道連得上連不上 還知道用什麼連
    //以下判斷是否接收
    NetworkStatus status =[serverReach currentReachabilityStatus];
    if (status == NotReachable) {
        //...
        NSLog(@"NetWork not available.");
    }else{
        [self downloadNewsList];
    };

}

-(void)downloadNewsList{

    if([serverReach currentReachabilityStatus] == NotReachable){
        return;
    }

    NSString * targetURLString =@"http://www.appledaily.com.tw/rss/newcreate/kind/rnews/type/new";

    NSURL * url = [NSURL URLWithString:targetURLString];
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession * session = [NSURLSession sessionWithConfiguration:config];

    NSURLSessionDataTask * task=[session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

        if (error) {
            NSLog(@"Error:%@",error);
            return;

        }


        NSString *rssContent = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];

        NSLog(@"Rss content :%@",rssContent);


        //Parse the XML Content

        NSXMLParser * parser = [[NSXMLParser alloc]initWithData:data];
        RSSParserDelegate * parserDelegate =[RSSParserDelegate new];
        parser.delegate = parserDelegate;

        BOOL success = [parser parse];

        if(success) {
            NSLog(@"Parse OK.");
            NSArray * results = [parserDelegate getResults];
            _objects = [NSMutableArray arrayWithArray:results];

            //Ask TableView to reload
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.tableView reloadData];
            });

        }else{
            NSLog(@"Parse Fail.");
        }



    }];
    [task resume];
}


- (void)viewWillAppear:(BOOL)animated {
    self.clearsSelectionOnViewWillAppear = self.splitViewController.isCollapsed;
    [super viewWillAppear:animated];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)insertNewObject:(id)sender {
    if (!self.objects) {
        self.objects = [[NSMutableArray alloc] init];
    }
    [self.objects insertObject:[NSDate date] atIndex:0];
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}

#pragma mark - Segues

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([[segue identifier] isEqualToString:@"showDetail"]) {
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        NSDate *object = self.objects[indexPath.row];
        DetailViewController *controller = (DetailViewController *)[[segue destinationViewController] topViewController];
        [controller setDetailItem:object];
        controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem;
        controller.navigationItem.leftItemsSupplementBackButton = YES;
    }
}

#pragma mark - Table View

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.objects.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

    NewsItem *object = self.objects[indexPath.row];
    cell.textLabel.text = object.title;
    return cell;
}

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the specified item to be editable.
    return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [self.objects removeObjectAtIndex:indexPath.row];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    } else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
    }
}

@end

cell 改 subtitle

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([[segue identifier] isEqualToString:@"showDetail"]) {
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        ->NewsItem *object = self.objects[indexPath.row];
        DetailViewController *controller = (DetailViewController *)[[segue destinationViewController] topViewController];
        [controller setDetailItem:object];
        controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem;
        controller.navigationItem.leftItemsSupplementBackButton = YES;
    }
}

砍掉detail的label
放入webview佔滿Navigation Bar 下方

DetailViewController.m

@property (weak, nonatomic) IBOutlet UIWebView *fullContentWebView;
#import "NewsItem.h"
- (void)configureView {
    // Update the user interface for the detail item.
    if (self.detailItem) {

        NewsItem * targetItem = self.detailItem;

        self.title = targetItem.title;

        NSURL * url = [NSURL URLWithString:targetItem.link];
        NSURLRequest *request = [NSURLRequest requestWithURL:url];

        [_fullContentWebView loadRequest:request];

    }
}

WSDL

AES128 加密

Comments

Popular posts from this blog

MEGA 暫存檔案刪除

XAMPP 使用多PORT來執行不同網頁

IOS GCD多執行緒