Предварительный просмотр встроенных ссылок в приложении iOS, как Facebook

Я пытаюсь встроить предварительный просмотр ссылки в приложение iOS так же, как это делает Facebook:

enter image description here

Я пытаюсь найти способ захватить наиболее подходящее изображение (и вернуть ему URL), заголовок страницы и, возможно, даже мета-описание и передать его обратно в приложение, но я не уверен лучший способ.

Есть API, которые делают это, в основном по цене, но похоже, что это не должно быть так сложно. Любые мысли?

Ответ 1

Вы можете сделать это на стороне сервера или на стороне клиента.

На стороне сервера вы можете использовать script (например, тот, который вы создали), чтобы захватить тег <head> на странице HTML.

На стороне клиента вы можете загрузить всю страницу как HTML (например, Mashable ~ 180KB) с NSURLConnection или библиотекой, такой как AFNetworking, и проанализировать ее с помощью синтаксического анализатора XML, чтобы найти тег <head>.

Я предлагаю вам создать сервер script, чтобы его можно было повторно использовать в других проектах или других платформах.

Ответ 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

Это заголовок для моего ответа. Сериализатор

#import <AFNetworking/AFNetworking.h>

@interface HTMLResponseSerializer : AFHTTPResponseSerializer

@end

и это реализация моего ответа. Сериализатор

#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 своим настраиваемым

Это сработало для меня очень хорошо