PhotoKit
- 相册权限获取
if PHPhotoLibrary.authorizationStatus() == .NotDetermined{
PHPhotoLibrary.requestAuthorization({ [weak self](status) in
if self == nil{
return
}
if status == .Authorized{
phFetchResult = PHAsset.fetchAssetsWithMediaType(.Image, options: allPhotosOptions)
}
})
}else{
phFetchResult = PHAsset.fetchAssetsWithMediaType(.Image, options: allPhotosOptions)
}```
- 判断日期是否在现在往前推N天范围内
```Swift
func isInDateRange(date:NSDate) -> Bool{
let currentDate = NSDate.init()
let numberOfDay = -100 // 设置扫描前多少天
let calculatedDate:NSDate = NSCalendar.currentCalendar().dateByAddingUnit(NSCalendarUnit.Day, value: numberOfDay, toDate: currentDate, options: NSCalendarOptions.init(rawValue: 0))!
// Comparing dates - Method #2
if date.compare(calculatedDate) == NSComparisonResult.OrderedDescending && date.compare(currentDate) == NSComparisonResult.OrderedAscending {
return true
}else{
return false
}
}```
- 判断日期是否距离现在7天
```Swift
func isRangeFromNowOverSevenDays(lastDate:NSDate) -> Bool{
let currentDate = NSDate.init()
let numberOfDay = -7
let calculatedDate:NSDate = NSCalendar.currentCalendar().dateByAddingUnit(NSCalendarUnit.Day, value: numberOfDay, toDate: currentDate, options: NSCalendarOptions.init(rawValue: 0))!
// Comparing dates - Method #2
let newDate:NSDate = lastDate.earlierDate(calculatedDate)
if newDate == lastDate{
return true
}else{
return false
}
}```
- 判断两天是否为同一天
```Swift
extension NSDate {
func isSameDay(another: NSDate) -> Bool {
let calendarUnit: NSCalendarUnit = [.Year, .Month, .Day]
let calendar = NSCalendar.currentCalendar()
let selfComponent:NSDateComponents = calendar.components(calendarUnit, fromDate: self)
let anotherComponent:NSDateComponents = calendar.components(calendarUnit, fromDate: another)
return selfComponent.isSameDay(anotherComponent)
}
}
extension NSDateComponents {
func isSameDay(another:NSDateComponents)->Bool{
return self.year == another.year && self.month == another.month && self.day == another.day
}
}```
- 图片Base64编码过程中Image To Data 返回nil的问题
```Swift
PHImageManager.defaultManager().requestImageForAsset(asset, targetSize: CGSize.init(width: 200, height: 200), contentMode: PHImageContentMode.Default, options: options, resultHandler: { (image, _: [NSObject : AnyObject]?) in
// ===把获取到的图片 重新绘制即可===
UIGraphicsBeginImageContext((image?.size)!)
image?.drawInRect(CGRect.init(x: 0, y: 0, width: (image?.size.width)!, height: (image?.size.height)!))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
model.memoryThubnailImageStr = XYH5ContainerTool.imageEncodeBase64DataURL(newImage)
print("model memoryThubnailImageStr is \(model.memoryThubnailImageStr)")
if index == memoryModelArray.count - 1{
result(memoryModelArray)
}
})```
- PHAsset不能遵守NSCoding协议 故不能格式化缓存到内存中问题
- 我们可以保存它的identifier属性 取的时候通过系统方法fetchAssetsWithLocalIdentifiers来取即可
![Paste_Image.png](https://img.haomeiwen.com/i189984/773f809dd5ff4a1d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 获取PHAsset的方法
```Swift
func loadAssetWithLocalIdentifier(identifierArray:[String]) -> [PHAsset]{
var assetArray:[PHAsset] = []
let options = PHFetchOptions()
options.predicate = NSPredicate(format: "mediaType = %d",
PHAssetMediaType.Image.rawValue)
let fetchResult:PHFetchResult = PHAsset.fetchAssetsWithLocalIdentifiers(identifierArray, options:options)
fetchResult.enumerateObjectsUsingBlock { (asset, index, stop) in
guard let phAsset = asset as? PHAsset else{ return}
assetArray.append(phAsset)
}
return assetArray
}```
- 数组过滤
```Swift
memoryModelArray = memoryModelArray.filter({$0.memoryAssetArray.count > 5})```
- 数组排序
```Swift
let newArray = studioDicArray.sort { (s1, s2) -> Bool in
let dateFromatter:NSDateFormatter = NSDateFormatter.init()
dateFromatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let s1Date:NSDate = dateFromatter.dateFromString(s1["createTime"] as! String)!
let s2Date:NSDate = dateFromatter.dateFromString(s2["createTime"] as! String)!
return s1Date.timeIntervalSince1970 > s2Date.timeIntervalSince1970
}```
- 异步依次执行的串行队列的一种方式
- 队列单例
- (NSOperationQueue *)sharedAEOpQueue{
static NSOperationQueue *sharedAEOpQueue;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedAEOpQueue = [[NSOperationQueue alloc] init];
sharedAEOpQueue.name = @"simpleOneOperationQueue";
sharedAEOpQueue.maxConcurrentOperationCount = 1;
});
return sharedAEOpQueue;
}```
- Extension
typedef void(^AsyncOperationBlock)(__weak AsyncOperation *operation);```
import "NSOperationQueue+AsyncOperation.h"
import "AEOperation.h"
@implementation NSOperationQueue (AsyncOperation)
-
(void)addXYAsyncOperationWithBlock:(AsyncOperationBlock)block{
AsyncOperation *operation = [[AsyncOperation alloc] initWithOperationBlock:block];
[self addOperation:operation];
}
@end``` -
Use
AEOpQueueHelper.sharedAEOpQueue().addAsyncOperationWithBlock { (op) -> Void in
// Deal done finish operation
op.finishOperation()
}```
- .Tar格式 iOS应用内解压缩
- 使用如下库
![Paste_Image.png](https://img.haomeiwen.com/i189984/83029ef9671a38d0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 创建路径
```Swift
// MARK: -- Get document direstory
func getDocumentDirectory() -> String{
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentDirectionary = paths.first
return documentDirectionary!
}
// MARK: -- Get file path
func h5FilePath() -> String{
return self.getDocumentDirectory().stringByAppendingString("/h5Data.tar")
}```
- 下载.tar格式包
```Swift
let request = NSURLRequest.init(URL: NSURL.init(string: tarUrl)!)
let session = NSURLSession.sharedSession()
let tarDownloadTask = session.downloadTaskWithRequest(request, completionHandler: { (location, response, error) in
print("location:\(location)")
if location == nil{
return
}
let locationPath = location!.path
// to user path
let userPath = self!.h5FilePath()
let fileManager = NSFileManager.defaultManager()
try! fileManager.moveItemAtPath(locationPath!, toPath: userPath)
print("new location is \(userPath)")
// Parse tar data
self!.parseTarData()
})
tarDownloadTask.resume()```
- 解压到当前路径下
// MARK: -- Parse tar data
func parseTarData(){
let path = h5FilePath()
let defaultManager = NSFileManager()
if defaultManager.fileExistsAtPath(path){
// Un tar
NVHTarGzip.sharedInstance().unTarFileAtPath(path, toPath: parsedFilePath(), completion: {(tarError) in
if tarError != nil {
print("Error untarring \(tarError)")
}else{
// Send notification for untar success
asyncMain(block: {
let enumeratorAtPath = defaultManager.enumeratorAtPath(self.parsedFilePath())
//enumeratorAtPath:Optional([fold1, fold1/test2.txt, test1.txt])
print("enumeratorAtPath: \(enumeratorAtPath?.allObjects)")
NSNotificationCenter.defaultCenter().postNotificationName(self.H5DataDownloadSuccessNotification, object: nil)
})
}
})
}
}```
-
enumerateObjectsUsingBlock方法中 top return使用
-
return 相当于 break 只是跳出了一个当前正在遍历的对象
if !self.isInDateRange(phasset.creationDate!){
print(phasset.creationDate)
return
}```
- stop + return 才能真正停止遍历
if self.checkIsSatisfyCondition(memoryModelArray){
stop.memory = true
return
}```
- 边遍历边操作数组的一种小技巧
func deleteMemoryWithModel(model:MyMemoryModel){
let path = MyPhotoMemoryManager.memoryArchivePath
var dataArray = NSKeyedUnarchiver.unarchiveObjectWithFile(path) as? [MyMemoryModel]
// 创建一个不可变的数组用来遍历
let sequenceArray = dataArray
for (index, value) in (sequenceArray?.enumerate())! {
let sequenceModel:MyMemoryModel = value
if sequenceModel.photoCreateDate == model.photoCreateDate{
// 便利过程中原数组操作无影响
dataArray?.removeAtIndex(index)
break
}
}
if NSKeyedArchiver.archiveRootObject(dataArray!, toFile: MyPhotoMemoryManager.memoryArchivePath){
print("Archive successful")
}
}```
- 3D Touch Cell查看详情
- 注册
```Swift
// Register 3D Touch
if #available(iOS 9.0, *) {
if traitCollection.forceTouchCapability == UIForceTouchCapability.Available {
registerForPreviewingWithDelegate(self, sourceView: cell)
}
} else {
// Fallback on earlier versions add long press gesture
let longPressGesture:UILongPressGestureRecognizer = UILongPressGestureRecognizer.init(target: self, action: #selector(MyPhotoMemoryVC.cellLongPressGesture(_:)))
self.myPhotoMemoryTableView.addGestureRecognizer(longPressGesture)
}```
- 代理
```swift
class MyPhotoMemoryVC: UIViewController, UITableViewDelegate, UITableViewDataSource,UIViewControllerPreviewingDelegate{```
- 两个代理方法中取出 Cell 和 数据 并传递给详情控制器 (Swift中 两个代理方法 都要写 不然报错)
```Swift
func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
// Avoid add two
if ((self.presentedViewController?.isKindOfClass(MyPhotoMemoryPeekVC.classForCoder())) != nil){
return nil
}else{
// Get select indexPath
if #available(iOS 9.0, *) {
let indexPath:NSIndexPath = self.myPhotoMemoryTableView.indexPathForCell(previewingContext.sourceView as! MyPhotoMemoryCell)!
// Get model
let dic:[NSDate:[MyMemoryModel]] = self.memoryModelArray[indexPath.section]
let model:MyMemoryModel = dic.values.first![indexPath.row]
let myPhotoSB = UIStoryboard.init(name: "Main", bundle: nil)
let myPhotoMemoryPeekVC = myPhotoSB.instantiateViewControllerWithIdentifier("MyPhotoMemoryPeekVC") as? MyPhotoMemoryPeekVC
myPhotoMemoryPeekVC?.model = model
return myPhotoMemoryPeekVC
} else {
// Fallback on earlier versions
return nil
}
}
}
func previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: UIViewController) {
}```
- 详情控制器 上滑 按钮功能
@available(iOS 9.0, *)
override func previewActionItems() -> [UIPreviewActionItem] {
let deleteAction = UIPreviewAction.init(title: "删除", style: UIPreviewActionStyle.Default) { (action, vc) in
// Deal delete
print("3D Touch")
MyPhotoMemoryManager.shareInstance.deleteMemoryWithModel(self.model!)
NSNotificationCenter.defaultCenter().postNotificationName(peekVCDeleteMemoryNotification, object: nil)
self.dismissVC(animated: true)
}
let cancelAction = UIPreviewAction.init(title: "取消", style: UIPreviewActionStyle.Default) { (action, vc) in
self.dismissVC(animated: true)
}
let arr:[UIPreviewAction] = [deleteAction,cancelAction]
return arr
}
}```
网友评论