当使用此新的 Camera service 进行单元测试时,我们希望确保 AVCaptureSession 没有被真的创建。我们仅仅希望确认 camera service 被测试系统(SUT)正确的调用了,而不是去测试 camera service 本身。 因此,创建一个协议的 mock 实现,使用空方法和一组变量来帮助我们进行单元测试,并断言(asset)进行了正确的调用是有意义的。这是软件开发中非常常见的一个场景,如果你曾维护过一个包含大量单元测试的大型代码库,这么做也可能有点乏味。 好吧~不用担心!Sourcery 会帮助你!⭐️ 它有一个叫做 AutoMockable[2] 的模板,此模板会为任意输入文件中遵守 AutoMockable 协议的协议生成 mock 实现。
let listOfArticles = ArticlesList() var searchKeyword: NSAttributedString? = NSAttributedString(string: "keyword") let filteredArticles = await listOfArticles.filteredArticles { article in
// Error: Reference to captured var 'searchKeyword' in concurrently-executing code guard let searchKeyword = searchKeyword else { return false } return article.title == searchKeyword.string }
我们建立Reader和Book之间的联系的时候,发现他们的联系逻辑之间还漏了一个环节。假设一本书被一个读者借走了,它就不能被另一个读者借走,而当一个读者借书时,却可以借很多本书。也就是说,一本书只能对应一个读者,而一个读者却可以对应多本书。这就是 一对一→to one 和 一对多→to many 。Core Data允许我们配置这种联系,具体做法就是在RelationShip栏点击对应的关系栏,它将会出现在右侧的栏目中。(栏目如果没出现可以在xcode右上角的按钮调出,如果点击后栏目没出现Relationship配置项,可以多点击几下,这是xcode的小bug)。在Relationship的配置项里,有一项项名为Type,点击后有两个选项,一个是To One(默认值),另一个就是To Many了。
private func readBooks(container: NSPersistentContainer) { let context = container.viewContext let fetchBooks = NSFetchRequest<Book>(entityName: "Book") do { let books = try context.fetch(fetchBooks) print("Books count = \(books.count)") for book in books { print("Book name = \(book.name!)") } } catch {
let context = container.viewContext let fetchBooks = NSFetchRequest<Book>(entityName: "Book") fetchBooks.predicate = NSPredicate(format: "isbm = \"9787115293800\"") do { let books = try context.fetch(fetchBooks) for book in books { context.delete(books[0]) } if context.hasChanges { try context.save() } } catch { print("\(error)") }
for (id subview in subviews) { if ([subview isKindOfClass:NSClassFromString(@"_UIStatusBarWifiSignalView")]) { network = @"WIFI"; }else if ([subview isKindOfClass:NSClassFromString(@"_UIStatusBarStringView")]) { network = [subview valueForKeyPath:@"originalText"]; } } }
#pragma mark 获取Wifi信息 + (id)fetchSSIDInfo { NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces(); id info = nil; for (NSString *ifnam in ifs) { info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
问题描述为:can't open order file: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/AppleInternal/OrderFiles/libobjc.order
选择 target -> objc -> Build Settings
在工程的 Order File 中添加搜索路径 $(SRCROOT)/libobjc.order
【14】Xcode 脚本编译问题 问题描述为:/xcodebuild:1:1: SDK "macosx.internal" cannot be located.
在 iOS 和 macOS 开发中, Swift 包现在变得越来越重要。Apple 已经努力推动桥接那些缝隙,并且修复那些阻碍开发者的问题,例如阻碍开发者将他们的库和依赖由其他诸如 Carthage 或 CocoaPods依赖管理工具迁移到 Swift 包依赖管理工具的问题,例如没有能力添加构建步骤的问题。这对任何依赖一些代码生成的库来说都是破坏者,比如,协议和 Swift 生成。
1、理解二进制在 Swift 中的演变
为了充分理解 Apple 的 Swift 团队在二进制目标和他们引入的一些新 API 方面采取的一些步骤,我们需要理解它们从何而来。在后续的部分中,我们将调研 Apple 架构的演变,以及为什么二进制目标的 API 在过去几年中逐渐形成的,特别是自 Apple 发布了自己的硅芯片之后。
胖二进制和 Frameworks 框架
如果你曾必须处理二进制依赖,或者你曾创建一个属于你自己的可执行文件,你将会对 胖二进制 这个术语感到熟悉。这些被扩展(或增大)的可执行文件,是包含了为多个不同架构原生构建的切片。这允许库的所有者分发一个运行在所有预期的目标架构上的单独的二进制。 当源码不能被暴露或当处理非常庞大的代码仓库时,预编译库成为可执行文件非常有意义,因为预编译源码以及以二进制文件分发他们,将节省构建程序在他们的应用上的构建时间。 Pods 是一个非常好的例子,当开发者发现他们自己没必要构建那些非常少改动的依赖。这是一个很共通的问题,它激发了诸如 cocoapods-binary之类的项目,该项目预编译了 pod 依赖项以减少客户端的构建时间。
"schemaVersion": "1.0", "artifacts": { "swiftlint": { "version": "0.47.0", # The version of SwiftLint being used "type": "executable", "variants": [ ] }, } }
/** This category adds methods to the UIKit framework's `UIProgressView` class. The methods in this category provide support for binding the progress to the upload and download progress of a session task. */ @interface UIProgressView (AFNetworking)
/** Binds the progress to the upload progress of the specified session task.
@param task The session task. @param animated `YES` if the change should be animated, `NO` if the change should happen immediately. */ - (void)setProgressWithUploadProgressOfTask:(NSURLSessionUploadTask *)task animated:(BOOL)animated;
/** Binds the progress to the download progress of the specified session task.
@param task The session task. @param animated `YES` if the change should be animated, `NO` if the change should happen immediately. */ - (void)setProgressWithDownloadProgressOfTask:(NSURLSessionDownloadTask *)task animated:(BOOL)animated;
/** This category adds methods to the UIKit framework's `UIProgressView` class. The methods in this category provide support for binding the progress to the upload and download progress of a session task. */ @interface UIProgressView (AFNetworking)
/** Binds the progress to the upload progress of the specified session task.
@param task The session task. @param animated `YES` if the change should be animated, `NO` if the change should happen immediately. */ - (void)setProgressWithUploadProgressOfTask:(NSURLSessionUploadTask *)task animated:(BOOL)animated;
/** Binds the progress to the download progress of the specified session task.
@param task The session task. @param animated `YES` if the change should be animated, `NO` if the change should happen immediately. */ - (void)setProgressWithDownloadProgressOfTask:(NSURLSessionDownloadTask *)task animated:(BOOL)animated;
/** Adds the image to the cache with the given identifier.
@param image The image to cache. @param identifier The unique identifier for the image in the cache. */ - (void)addImage:(UIImage *)image withIdentifier:(NSString *)identifier;
/** Removes the image from the cache matching the given identifier.
@param identifier The unique identifier for the image in the cache.
@return A BOOL indicating whether or not the image was removed from the cache. */ - (BOOL)removeImageWithIdentifier:(NSString *)identifier;
/** Removes all images from the cache.
@return A BOOL indicating whether or not all images were removed from the cache. */ - (BOOL)removeAllImages;
/** Returns the image in the cache associated with the given identifier.
@param identifier The unique identifier for the image in the cache.
@return An image for the matching identifier, or nil. */ - (nullable UIImage *)imageWithIdentifier:(NSString *)identifier;
该协议定义了包括加入、移除、获取缓存中的图片。
2. AFImageRequestCache
该协议包含下面几个方法,这里注意这个协议继承自协议AFImageCache
@protocol AFImageRequestCache <AFImageCache>
/** Asks if the image should be cached using an identifier created from the request and additional identifier.
@param image The image to be cached. @param request The unique URL request identifing the image asset. @param identifier The additional identifier to apply to the URL request to identify the image.
@return A BOOL indicating whether or not the image should be added to the cache. YES will cache, NO will prevent caching. */ - (BOOL)shouldCacheImage:(UIImage *)image forRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier;
/** Adds the image to the cache using an identifier created from the request and additional identifier.
@param image The image to cache. @param request The unique URL request identifing the image asset. @param identifier The additional identifier to apply to the URL request to identify the image. */ - (void)addImage:(UIImage *)image forRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier;
/** Removes the image from the cache using an identifier created from the request and additional identifier.
@param request The unique URL request identifing the image asset. @param identifier The additional identifier to apply to the URL request to identify the image.
@return A BOOL indicating whether or not all images were removed from the cache. */ - (BOOL)removeImageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier;
/** Returns the image from the cache associated with an identifier created from the request and additional identifier.
@param request The unique URL request identifing the image asset. @param identifier The additional identifier to apply to the URL request to identify the image.
@return An image for the matching request and identifier, or nil. */ - (nullable UIImage *)imageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier;
@end
根据请求和标识对图像进行是否需要缓存、加入到缓存或者移除缓存等进行操作。
3. AFAutoPurgingImageCache
这个是这个类的接口,大家注意下这个类遵循协议AFImageRequestCache。
/** The `AutoPurgingImageCache` in an in-memory image cache used to store images up to a given memory capacity. When the memory capacity is reached, the image cache is sorted by last access date, then the oldest image is continuously purged until the preferred memory usage after purge is met. Each time an image is accessed through the cache, the internal access date of the image is updated. */ @interface AFAutoPurgingImageCache : NSObject <AFImageRequestCache>
/** The total memory capacity of the cache in bytes. */ // 内存缓存总的字节数 @property (nonatomic, assign) UInt64 memoryCapacity;
/** The preferred memory usage after purge in bytes. During a purge, images will be purged until the memory capacity drops below this limit. */ // 以字节为单位清除后的首选内存使用情况。 在清除过程中,图像将被清除,直到内存容量降至此限制以下。 @property (nonatomic, assign) UInt64 preferredMemoryUsageAfterPurge;
/** The current total memory usage in bytes of all images stored within the cache. */ // 当前所有图像内存缓存使用的总的字节数 @property (nonatomic, assign, readonly) UInt64 memoryUsage;
/** Initialies the `AutoPurgingImageCache` instance with default values for memory capacity and preferred memory usage after purge limit. `memoryCapcity` defaults to `100 MB`. `preferredMemoryUsageAfterPurge` defaults to `60 MB`. // 初始化,memoryCapcity为100M,preferredMemoryUsageAfterPurge为60M
@return The new `AutoPurgingImageCache` instance. */ - (instancetype)init;
/** Initialies the `AutoPurgingImageCache` instance with the given memory capacity and preferred memory usage after purge limit.
@param memoryCapacity The total memory capacity of the cache in bytes. @param preferredMemoryCapacity The preferred memory usage after purge in bytes.
@return The new `AutoPurgingImageCache` instance. */ - (instancetype)initWithMemoryCapacity:(UInt64)memoryCapacity preferredMemoryCapacity:(UInt64)preferredMemoryCapacity;
if #available(iOS 13.0, *) { /**
- 点击 苹果登录的按钮跳出苹果登录的界面
- 跳转出系统界面
*/ let appleIDProvider =ASAuthorizationAppleIDProvider() let request = appleIDProvider.createRequest()
request.requestedScopes = [.fullName, .email]
let authorizationController =ASAuthorizationController(authorizationRequests: [request])
authorizationController.delegate =self
authorizationController.presentationContextProvider =selfas?ASAuthorizationControllerPresentationContextProviding
authorizationController.performRequests()
} else { // Fallback on earlier versions
}
}
//MARK: - 授权成功 @available(iOS 13.0, *) funcauthorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) { if #available(iOS 13.0, *) { switch authorization.credential { caselet appleIDCredential asASAuthorizationAppleIDCredential: /**
- 首次注册 能够那去到的参数分别是:
1. user
2.state
3.authorizedScopes
4.authorizationCode
5.identityToken
6.email
7.fullName
8.realUserStatus
*/ // Create an account in your system. let userIdentifier = appleIDCredential.user let fullName = appleIDCredential.fullName let email = appleIDCredential.email let code = appleIDCredential.authorizationCode // For the purpose of this demo app, store the `userIdentifier` in the keychain. self.saveUserInKeychain(userIdentifier)
// For the purpose of this demo app, show the Apple ID credential information in the `ResultViewController`. self.showResultViewController(userIdentifier: userIdentifier, fullName: fullName, email: email) BPLog.lmhInfo("userID:\(userIdentifier),fullName:\(fullName),userEmail:\(email),code:\(code)") caselet passwordCredential asASPasswordCredential:
// Sign in using an existing iCloud Keychain credential. let username = passwordCredential.user let password = passwordCredential.password
// For the purpose of this demo app, show the password credential as an alert. DispatchQueue.main.async { self.showPasswordCredentialAlert(username: username, password: password)
}
@main structSwiftUIAppLifeCycleApp: App { @Environment(\.scenePhase) var scenePhase
var body: someScene { WindowGroup { ContentView()
}
.onChange(of: scenePhase) { newScenePhase in switch newScenePhase { case .active: print("App is active") case .inactive: print("App is inactive") case .background: print("App is in background") @unknowndefault: print("Oh - interesting: I received an unexpected new value.")
}
}
}
}
SE-0281 explicitly states that one of the design goals was “to offer a more general purpose and lightweight mechanism for delegating a program’s entry point to a designated type.”
let n = Notification.Name("event") Task { forawait value inNotificationCenter.default.notifications(named: n, object: nil) { iflet str = value.object as?String { await asyncPrint(value: str)
}
}
}
NotificationCenter.default.post(name: n, object: "event1") NotificationCenter.default.post(name: n, object: "event2") NotificationCenter.default.post(name: n, object: "event3")
: The Legacy Build System will be removed in a future release. You can configure the selected build system and this deprecation message in File > Workspace Settings.
解决方案:
菜单栏 File->Workspace Settings-> BuildSystem
选择使用 New Buile System(Default)
问题, 文件引入问题(Xcode12之前没有问题)
Multiple commands produce '/Users/imac/Library/Developer/Xcode/DerivedData/dudu-awglbcqfapsmfngrajrwibtvgoph/Build/Products/Debug-iphoneos/dudu.app/PEDat_wb.bundle':
1) Target 'dudu' (project 'dudu') has copy command from '/Users/imac/Desktop/dudu_dev/dudu/WBCloudReflectionFaceVerify_framework/Resources/PEDat_wb.bundle' to '/Users/imac/Library/Developer/Xcode/DerivedData/dudu-awglbcqfapsmfngrajrwibtvgoph/Build/Products/Debug-iphoneos/dudu.app/PEDat_wb.bundle'
2) That command depends on command in Target 'dudu' (project 'dudu'): script phase “[CP] Copy Pods Resources”
Multiple commands produce '/Users/imac/Library/Developer/Xcode/DerivedData/dudu-awglbcqfapsmfngrajrwibtvgoph/Build/Products/Debug-iphoneos/dudu.app/WBCloudReflectionFaceVerify.bundle':
1) Target 'dudu' (project 'dudu') has copy command from '/Users/imac/Desktop/dudu_dev/dudu/WBCloudReflectionFaceVerify_framework/Resources/WBCloudReflectionFaceVerify.bundle' to '/Users/imac/Library/Developer/Xcode/DerivedData/dudu-awglbcqfapsmfngrajrwibtvgoph/Build/Products/Debug-iphoneos/dudu.app/WBCloudReflectionFaceVerify.bundle'
2) That command depends on command in Target 'dudu' (project 'dudu'): script phase “[CP] Copy Pods Resources”
Multiple commands produce '/Users/imac/Library/Developer/Xcode/DerivedData/dudu-awglbcqfapsmfngrajrwibtvgoph/Build/Products/Debug-iphoneos/dudu.app/detector_wb.bundle':
1) Target 'dudu' (project 'dudu') has copy command from '/Users/imac/Desktop/dudu_dev/dudu/WBCloudReflectionFaceVerify_framework/Resources/detector_wb.bundle' to '/Users/imac/Library/Developer/Xcode/DerivedData/dudu-awglbcqfapsmfngrajrwibtvgoph/Build/Products/Debug-iphoneos/dudu.app/detector_wb.bundle'
2) That command depends on command in Target 'dudu' (project 'dudu'): script phase “[CP] Copy Pods Resources”
Multiple commands produce '/Users/imac/Library/Developer/Xcode/DerivedData/dudu-awglbcqfapsmfngrajrwibtvgoph/Build/Products/Debug-iphoneos/dudu.app/ufa_wb.bundle':
1) Target 'dudu' (project 'dudu') has copy command from '/Users/imac/Desktop/dudu_dev/dudu/WBCloudReflectionFaceVerify_framework/Resources/ufa_wb.bundle' to '/Users/imac/Library/Developer/Xcode/DerivedData/dudu-awglbcqfapsmfngrajrwibtvgoph/Build/Products/Debug-iphoneos/dudu.app/ufa_wb.bundle'
2) That command depends on command in Target 'dudu' (project 'dudu'): script phase “[CP] Copy Pods Resources”
解决方案:
target->Build Phases
具体如图, 报错的文件就行了
问题: info.plist 文件问题, 由于项目中使用的库手动拉进来的,
Multiple commands produce '/Users/imac/Library/Developer/Xcode/DerivedData/dudu-awglbcqfapsmfngrajrwibtvgoph/Build/Products/Debug-iphoneos/dudu.app/Info.plist':
1) Target 'dudu' (project 'dudu') has copy command from '/Users/imac/Desktop/dudu_dev/dudu/dudu/Libs/AliyunOSSiOS/Info.plist' to '/Users/imac/Library/Developer/Xcode/DerivedData/dudu-awglbcqfapsmfngrajrwibtvgoph/Build/Products/Debug-iphoneos/dudu.app/Info.plist'
2) Target 'dudu' (project 'dudu') has copy command from '/Users/imac/Desktop/dudu_dev/dudu/dudu/SupportingFiles/Info.plist' to '/Users/imac/Library/Developer/Xcode/DerivedData/dudu-awglbcqfapsmfngrajrwibtvgoph/Build/Products/Debug-iphoneos/dudu.app/Info.plist'
3) Target 'dudu' (project 'dudu') has process command with output '/Users/imac/Library/Developer/Xcode/DerivedData/dudu-awglbcqfapsmfngrajrwibtvgoph/Build/Products/Debug-iphoneos/dudu.app/Info.plist'
解决方案:
直接删除手动拉进来的库里面的 `info.plist` 文件
项目里面有个 VERSION 的文件, 想不明白这个为啥
Multiple commands produce '/Users/imac/Library/Developer/Xcode/DerivedData/dudu-awglbcqfapsmfngrajrwibtvgoph/Build/Products/Debug-iphoneos/dudu.app/VERSION':
1) Target 'dudu' (project 'dudu') has copy command from '/Users/imac/Desktop/dudu_dev/dudu/dudu/Libs/ST_Mobile/SenseArSourceService/VERSION' to '/Users/imac/Library/Developer/Xcode/DerivedData/dudu-awglbcqfapsmfngrajrwibtvgoph/Build/Products/Debug-iphoneos/dudu.app/VERSION'
2) Target 'dudu' (project 'dudu') has copy command from '/Users/imac/Desktop/dudu_dev/dudu/dudu/Libs/ST_Mobile/VERSION' to '/Users/imac/Library/Developer/Xcode/DerivedData/dudu-awglbcqfapsmfngrajrwibtvgoph/Build/Products/Debug-iphoneos/dudu.app/VERSION'
解决方案:
修改一下 `VERSION` 的文件名称: 或者删除文件
处理了上面的问题, 依旧还是有问题, 接着修改
Multiple commands produce '/Users/imac/Library/Developer/Xcode/DerivedData/dudu-awglbcqfapsmfngrajrwibtvgoph/Build/Products/Debug-iphoneos/dudu.app/Info.plist':
1) Target 'dudu' (project 'dudu') has copy command from '/Users/imac/Desktop/dudu_dev/dudu/dudu/SupportingFiles/Info.plist' to '/Users/imac/Library/Developer/Xcode/DerivedData/dudu-awglbcqfapsmfngrajrwibtvgoph/Build/Products/Debug-iphoneos/dudu.app/Info.plist'
2) Target 'dudu' (project 'dudu') has process command with output '/Users/imac/Library/Developer/Xcode/DerivedData/dudu-awglbcqfapsmfngrajrwibtvgoph/Build/Products/Debug-iphoneos/dudu.app/Info.plist'
解决方案:
1. 找到 Products 文件夹下的 项目, 邮件 show in finder, 然后向上找, 找到 DerivedData 文件下, 删除对用的文件
使用C++容器类访问成员时由于使用问题可能会遇到"terminate called after throwing an instance of 'std::out_of_range'"或者"Abort message: 'terminating with uncaught exception of type std::out_of_range"。问题的大概意思是:访问越界了。没有捕获std::out_of_range类型的异常终止。
mapped_type& at (const key_type& k); const mapped_type& at (const key_type& k)const;
对于std::map::at使用有如下说明: Access element 访问元素
Returns a reference to the mapped value of the element identified with key k. 返回元素键为k的映射值的引用,即Key为k的元素的对应value值。 If k does not match the key of any element in the container, the function throws an out_of_range exception. 如果容器中没有匹配的k键,该函数将抛出一个out_of_range异常
std::map::at的使用
正确使用
错误使用
1.std::map::at的正确使用
#include<iostream> #include<string> #include<map>
std::map<int,int> g_mapIsDestroyedRefCount;
int main() { int cameraId =1;
cout <<"Let's try"<< endl;
- (void)startMonitor
{
SCNetworkReachabilityContext context = {0, (__bridge void *)self, NULL, NULL, NULL};
if (SCNetworkReachabilitySetCallback(_reachability, ReachabilityCallback, &context)) {
// Schedules the given target with the given run loop and mode.
// SCNetworkReachabilityScheduleWithRunLoop(_reachability, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
// Schedule or unschedule callbacks for the given target on the given dispatch queue.
SCNetworkReachabilitySetDispatchQueue(_reachability, _serialQueue);
}
}
// Unschedules the given target from the given run loop and mode.
// SCNetworkReachabilityUnscheduleFromRunLoop(_reachability, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
SCNetworkReachabilitySetDispatchQueue(_reachability, NULL);
}
苹果的Reachability有如下说明,告诉我们其能力受限于此: The SCNetworkReachability programming interface allows an application to determine the status of a system's current network configuration and the reachability of a target host. A remote host is considered reachable when a data packet, sent by an application into the network stack, can leave the local device. Reachability does not guarantee that the data packet will actually be received by the host. 当应用程序发送到网络堆栈的数据包可以离开本地设备时,就可以认为远程主机是可访问的,不能保证主机是否实际接收到数据包。
let hostName = "www.baidu.com" var pinger: SimplePing? var sendTimer: NSTimer?
/// Called by the table view selection delegate callback to start the ping. funcstart(forceIPv4 forceIPv4: Bool, forceIPv6: Bool) { let pinger = SimplePing(hostName: self.hostName) self.pinger = pinger
// By default we use the first IP address we get back from host resolution (.Any) // but these flags let the user override that. if (forceIPv4 && !forceIPv6) {
pinger.addressStyle = .ICMPv4
} elseif (forceIPv6 && !forceIPv4) {
pinger.addressStyle = .ICMPv6
}
pinger.delegate = self
pinger.start()
}
/// Called by the table view selection delegate callback to stop the ping. funcstop() { self.pinger?.stop() self.pinger = nil
self.sendTimer?.invalidate() self.sendTimer = nil
self.pingerDidStop()
}
/// Sends a ping. /// Called to send a ping, both directly (as soon as the SimplePing object starts up) and /// via a timer (to continue sending pings periodically). funcsendPing() { self.pinger!.sendPingWithData(nil)
}
Media Layer:媒体层提供应用中视听方面的技术,如图形图像相关的CoreGraphics,CoreImage,GLKit,OpenGL ES,CoreText,ImageIO等等。声音技术相关的CoreAudio,OpenAL,AVFoundation,视频相关的CoreMedia,Media Player框架,音视频传输的AirPlay框架等等
Core OS Layer:系统核心层包含大多数低级别接近硬件的功能,它所包含的框架常常被其它框架所使用。Accelerate框架包含数字信号,线性代数,图像处理的接口。针对所有的iOS设备硬件之间的差异做优化,保证写一次代码在所有iOS设备上高效运行。CoreBluetooth框架利用蓝牙和外设交互,包括扫描连接蓝牙设备,保存连接状态,断开连接,获取外设的数据或者给外设传输数据等等。Security框架提供管理证书,公钥和私钥信任策略,keychain,hash认证数字签名等等与安全相关的解决方案。