Preview Embedded Links in iOS App Like Facebook

后端 未结 2 1339
萌比男神i
萌比男神i 2021-02-05 18:48

I\'m trying to embed a link preview in an iOS application in the same way that Facebook does:

\"enter

相关标签:
2条回答
  • 2021-02-05 19:04

    I was going for the same target and I did it on the client side

    I used these pods

    pod 'HTMLReader'
    pod 'AFNetworking'
    

    Then I inherited from AFHTTPResponseSerializer and returned an object that contains link details

    #import <UIKit/UIKit.h>
    
    @interface LinkDetails : NSObject
    
    @property (nonatomic,strong) NSString *linkURL;
    
    @property (nonatomic,strong) NSString *linkHOST;
    
    @property (nonatomic,strong) NSString *linkTitle;
    
    @property (nonatomic,strong) NSString *linkDescription;
    
    @property (nonatomic,strong) NSString *linkWebSiteName;
    
    @property (nonatomic,strong) NSString *linkImageUrl;
    
    @property (nonatomic,strong) UIImage *linkImage;
    
    @end
    

    This is the header for my responseSerializer

    #import <AFNetworking/AFNetworking.h>
    
    @interface HTMLResponseSerializer : AFHTTPResponseSerializer
    
    @end
    

    and this is the implementation for my responseSerializer

    #import "HTMLResponseSerializer.h"
    #import <HTMLReader/HTMLReader.h>
    #import "LinkDetails.h"
    
    @implementation HTMLResponseSerializer
    
    -(id)responseObjectForResponse:(NSURLResponse *)response data:(NSData *)data error:(NSError *__autoreleasing  _Nullable *)error{
    
        NSString *responseStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    
        LinkDetails *details = [[LinkDetails alloc] init];
    
        HTMLDocument *document = [HTMLDocument documentWithString:responseStr];
    
        NSArray *metaTags = [document nodesMatchingSelector:@"meta"];
    
        for (HTMLElement *metaTag in metaTags) {
    
            if ([[[metaTag attributes] objectForKey:@"property"] isEqualToString:@"og:url"] || [[[metaTag attributes] objectForKey:@"property"] isEqualToString:@"twitter:url"]) {
                NSLog(@"%@",[[metaTag attributes] objectForKey:@"content"]);
                details.linkURL = [[metaTag attributes] objectForKey:@"content"];
            }
    
            if ([[[metaTag attributes] objectForKey:@"property"] isEqualToString:@"og:title"]  || [[[metaTag attributes] objectForKey:@"property"] isEqualToString:@"twitter:title"]) {
                NSLog(@"%@",[[metaTag attributes] objectForKey:@"content"]);
                details.linkTitle = [[metaTag attributes] objectForKey:@"content"];
            }
    
            if ([[[metaTag attributes] objectForKey:@"property"] isEqualToString:@"og:description"] || [[[metaTag attributes] objectForKey:@"property"] isEqualToString:@"twitter:description"]) {
                NSLog(@"%@",[[metaTag attributes] objectForKey:@"content"]);
                details.linkDescription = [[metaTag attributes] objectForKey:@"content"];
            }
    
            if ([[[metaTag attributes] objectForKey:@"property"] isEqualToString:@"og:image"] || [[[metaTag attributes] objectForKey:@"property"] isEqualToString:@"twitter:image"]) {
                NSLog(@"%@",[[metaTag attributes] objectForKey:@"content"]);
                details.linkImageUrl = [[metaTag attributes] objectForKey:@"content"];
            }
    
            if ([[[metaTag attributes] objectForKey:@"property"] isEqualToString:@"og:site_name"] || [[[metaTag attributes] objectForKey:@"property"] isEqualToString:@"twitter:site_name"]) {
                NSLog(@"%@",[[metaTag attributes] objectForKey:@"content"]);
                details.linkWebSiteName = [[metaTag attributes] objectForKey:@"content"];
            }
        }
    
        if(!details.linkTitle){
            details.linkTitle = [document firstNodeMatchingSelector:@"title"].textContent;
        }
    
        if(!details.linkDescription){
            details.linkTitle = [document firstNodeMatchingSelector:@"description"].textContent;
        }
    
        if (!details.linkHOST) {
            details.linkHOST = [response.URL host];
        }
    
        if (!details.linkURL) {
            details.linkURL = [response.URL absoluteString];
        }
    
        return details;
    }
    
    @end
    

    Don't forget to assign responseSerlializer to your custom one

    This worked for me very well

    0 讨论(0)
  • 2021-02-05 19:22

    You can do this server-side or client-side.

    Server-side, you can use a script (like the one you've built) to grab the <head> tag of the HTML page.

    Client-side you can download the whole page as HTML (as an example, Mashable is ~180KB) with NSURLConnection or a library like AFNetworking and parse it with a XML parser to find the <head> tag.

    I suggest you to create a server script, so you can reuse it in other projects or other platforms.

    0 讨论(0)
提交回复
热议问题