12

我正在尝试以与 Facebook 相同的方式在 iOS 应用程序中嵌入链接预览:

在此处输入图像描述

我试图找到一种方法来获取最合适的图像(并将 url 返回给它)、页面标题,甚至可能是元描述并将其传递回应用程序,但我不确定最好的方法.

有 API 可以做到这一点,大部分都是有代价的,但似乎不应该这么困难。有什么想法吗?

4

2 回答 2

4

您可以在服务器端或客户端执行此操作。

在服务器端,您可以使用脚本(如您构建的脚本)来获取<head>HTML 页面的标签。

在客户端,您可以使用 NSURLConnection 或 AFNetworking 之类的库将整个页面下载为 HTML(例如,Mashable 约为 180KB),并使用 XML 解析器对其进行解析以查找<head>标签。

我建议您创建一个服务器脚本,以便您可以在其他项目或其他平台中重用它。

于 2015-10-07T15:36:22.377 回答
2

我追求同一个目标,我在客户端做到了

我用了这些豆荚

pod 'HTMLReader'
pod 'AFNetworking'

然后我继承AFHTTPResponseSerializer并返回了一个包含链接详细信息的对象

#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

这是我的 responseSerializer 的标题

#import <AFNetworking/AFNetworking.h>

@interface HTMLResponseSerializer : AFHTTPResponseSerializer

@end

这是我的 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

不要忘记将 responseSerlializer 分配给您的自定义

这对我很有用

于 2016-07-14T11:13:43.463 回答