iOS 私有API调用

最近自己在做一个小程序,想实现一个一键设置手机壁纸的功能。但在iOS公开的API里找不到相关的方法,只能从私有API入手。

网上有不少教程,不过都不是很详细。从google和https://stackoverflow.com能找到比较详细的描述。

想要使用私有API首先需要知道相关API的声明,可以知己搜索,也可以使用class-dump自己搞定。下面说下详细过程。

首先下载class-dump。直接放到usr/local/bin文件夹中就可以使用。

xcode 8.3.2下私有API路径在

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator10.3.sdk/System/Library/PrivateFrameworks

直接使用class-dump导出 

sudo class-dump -H /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator10.3.sdk/System/Library/PrivateFrameworks/UIFoundation.framework -o /Users/xxxx/Desktop/Frameworks

导出后是一堆.h文件。

导出后就是怎么使用的问题了。搜索到不少都说将这些.h封装成framework来使用,然后设置search path 为  /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator10.3.sdk/System/Library/PrivateFrameworks。

试过之后并不太好用,因为有些类的声明定义在公开的API都是没有的,也可能是我用的不对,有了解的朋友请多指教。

有些头文件可以直接拖入到工程就可以使用了,一般来说是一些category. 更通用的方法是直接自己写一个,然后声明私有API的方法。

具体如下:

#import <UIKit/UIKit.h>

@interface UIFont (Private)

- (_Bool)isVertical;
- (double)_bodyLeading;

@end

 这样可以直接用UIFont来调用这两个方法了。

还有一种是使用runtime的方式,应该说这是一个更加通用的方法。

下面以设置手机壁纸的例子来讲解(iOS 10以下有效)

直接class-dump photoKit的framework。查看相关的头文件,可以看到 PLWallpaperImageViewController.h 和 PLStaticWallpaperImageViewController.h。

查看相关的方法,可以猜到和设置壁纸有关的几个方法。

- (id)initWithUIImage:(id)arg1;
- (void)setImageAsHomeScreenAndLockScreenClicked:(id)arg1;
- (void)setImageAsLockScreenClicked:(id)arg1;
- (void)setImageAsHomeScreenClicked:(id)arg1;

使用runtime初始化并调用方法

_image = [UIImage imageNamed:@"1.jpg"];

Class class = NSClassFromString(@"PLStaticWallpaperImageViewController");

_wallPaper = [[class alloc] performSelector:NSSelectorFromString(@"initWithUIImage:") withObject:_image];

[_wallPaper setValue:@(YES) forKeyPath:@"allowsEditing"];

[_wallPaper  setValue:@(YES) forKeyPath:@"saveWallpaperData"]; //

[_wallPaper performSelector:NSSelectorFromString(@"setImageAsHomeScreenClicked:") withObject:nil];

//也可以使用
//[_wallPaper performSelector:@selector(setImageAsHomeScreenClicked:) withObject:nil];

 这样就完成了壁纸的设置 。

原文地址:https://www.cnblogs.com/bigly/p/7070218.html