将MKMapSnapshotter作为NSData保留在内存中-Swift [英] Keep MKMapSnapshotter as NSData in memory - Swift

查看:116
本文介绍了将MKMapSnapshotter作为NSData保留在内存中-Swift的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试拍摄我的MKMapView的屏幕截图.我通常使用目标C中的以下代码来实现这一点.

I'm trying to take a screenshot of my MKMapView. I usually achieved this using the below code in Objective C.

我想知道如何将NSData对象保留在内存中,而不是保存图像,然后立即读取它.

I'm wondering how I would keep the NSData object in memory, rather than saving the image, and then reading from it straight away.

我还想知道如何用Swift编写它-特别是完成处理程序部分.我看过文档-但不确定语法:

I'm also wondering how this could be written in Swift - In particular, the completion handler part. I've looked at the docs - but unsure of syntax:https://developer.apple.com/library/prerelease/iOS/documentation/MapKit/Reference/MKMapSnapshotter_class/index.html#//apple_ref/c/tdef/MKMapSnapshotCompletionHandler

MKMapSnapshotOptions *options = [[MKMapSnapshotOptions alloc] init];
options.region = self.mapView.region;
options.size = self.mapView.frame.size;
options.scale = [[UIScreen mainScreen] scale];

NSURL *fileURL = [NSURL fileURLWithPath:@"path/to/snapshot.png"];

MKMapSnapshotter *snapshotter = [[MKMapSnapshotter alloc] initWithOptions:options];
[snapshotter startWithCompletionHandler:^(MKMapSnapshot *snapshot, NSError *error) {
    if (error) {
        NSLog(@"[Error] %@", error);
        return;
    }

    UIImage *image = snapshot.image;
    NSData *data = UIImagePNGRepresentation(image);
    [data writeToURL:fileURL atomically:YES];
}];

推荐答案

就将其保留"在内存中而言,您可以通过Objective-C完成块(或Swift闭包)返回NSData.从那里,您可以将NSData传递给另一个方法,或将其保存在class属性中.

In terms of "keeping" it in memory, you could return the NSData via an Objective-C completion block (or Swift closure). From there, you can pass the NSData to another method or save it in a class property.

例如,在Objective-C中:

For example, in Objective-C:

/** Request NSData of PNG representation of map snapshot.
 *
 * @param mapView The MKMapView for which we're capturing the snapshot
 * @param completion The completion block that will be called when the asynchronous snapshot is done. This takes two parameters, the resulting NSData upon success and an NSError if there was an error.
 */

- (void)requestSnapshotDataForMapView:(MKMapView *)mapView completion:(void (^)(NSData *data, NSError *error))completion
{
    MKMapSnapshotOptions *options = [[MKMapSnapshotOptions alloc] init];
    options.region = mapView.region;
    options.size = mapView.frame.size;
    options.scale = [[UIScreen mainScreen] scale];

    MKMapSnapshotter *snapshotter = [[MKMapSnapshotter alloc] initWithOptions:options];
    [snapshotter startWithCompletionHandler:^(MKMapSnapshot *snapshot, NSError *error) {
        if (error) {
            if (completion) {
                completion(nil, error);
            }
            return;
        }

        UIImage *image = snapshot.image;
        NSData *data = UIImagePNGRepresentation(image);
        if (completion) {
            completion(data, nil);
        }
    }];
}

- (IBAction)didTouchUpInsideButton:(id)sender
{
    [self requestSnapshotDataForMapView:self.mapView completion:^(NSData *data, NSError *error) {
        if (error) {
            NSLog(@"requestSnapshotDataForMapView error: %@", error);
            return;
        }

        // do whatever you want with the `data` parameter here, for example,
        // if you had some `@property (nonatomic, strong) NSData *snapshotData;`,
        // you might do:
        //
        // self.snapshotData = data

        // now initiate the next step of the process in which you're presumably
        // going to use the `data` provided by this block.
    }];
}

Swift等效项是:

The Swift equivalent is:

/// Request NSData of PNG representation of map snapshot.
///
/// - parameter mapView:     The MKMapView for which we're capturing the snapshot
/// - parameter completion:  The closure that will be called when the asynchronous snapshot is done. This takes two parameters, the resulting NSData upon success and an NSError if there was an error.

func requestSnapshotData(mapView: MKMapView, completion: (NSData?, NSError?) -> ()) {
    let options = MKMapSnapshotOptions()
    options.region = mapView.region
    options.size = mapView.frame.size
    options.scale = UIScreen.mainScreen().scale

    let snapshotter = MKMapSnapshotter(options: options)
    snapshotter.startWithCompletionHandler() { snapshot, error in
        guard snapshot != nil else {
            completion(nil, error)
            return
        }

        let image = snapshot!.image
        let data = UIImagePNGRepresentation(image)
        completion(data, nil)
    }
}

@IBAction func didTouchUpInsideButton(sender: AnyObject) {
    requestSnapshotData(mapView) { data, error in
        guard data != nil else  {
            print("requestSnapshotData error: \(error)")
            return
        }

        // do whatever you want with the `data` parameter here, for example,
        // if you had some `var snapshotData: NSData?` class property, you might do:
        //
        // self.snapshotData = data

        // now initiate the next step of the process in which you're presumably
        // going to use the `data` provided by this closure.
    }
}

坦率地说,如果您尝试在其他地方使用UIImage,我可能会更改这些块/闭包参数以使用UIImage而不是NSData,但是希望这可以说明这个想法.

Frankly, if you're trying to use the UIImage somewhere else, I might change these block/closure parameters to use the UIImage rather than the NSData, but hopefully this illustrates the idea.

这篇关于将MKMapSnapshotter作为NSData保留在内存中-Swift的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆