-
-
Notifications
You must be signed in to change notification settings - Fork 476
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
32 changed files
with
673 additions
and
170 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
85 changes: 85 additions & 0 deletions
85
ios/PushDeer-iOS/PushDeer.xcodeproj/xcshareddata/xcschemes/PushDeerClip.xcscheme
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<Scheme | ||
LastUpgradeVersion = "1320" | ||
version = "1.3"> | ||
<BuildAction | ||
parallelizeBuildables = "YES" | ||
buildImplicitDependencies = "YES"> | ||
<BuildActionEntries> | ||
<BuildActionEntry | ||
buildForTesting = "YES" | ||
buildForRunning = "YES" | ||
buildForProfiling = "YES" | ||
buildForArchiving = "YES" | ||
buildForAnalyzing = "YES"> | ||
<BuildableReference | ||
BuildableIdentifier = "primary" | ||
BlueprintIdentifier = "52B8CF63277E0B44004CB680" | ||
BuildableName = "PushDeerClip.app" | ||
BlueprintName = "PushDeerClip" | ||
ReferencedContainer = "container:PushDeer.xcodeproj"> | ||
</BuildableReference> | ||
</BuildActionEntry> | ||
</BuildActionEntries> | ||
</BuildAction> | ||
<TestAction | ||
buildConfiguration = "Debug" | ||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||
shouldUseLaunchSchemeArgsEnv = "YES"> | ||
<Testables> | ||
</Testables> | ||
</TestAction> | ||
<LaunchAction | ||
buildConfiguration = "Debug" | ||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||
launchStyle = "0" | ||
useCustomWorkingDirectory = "NO" | ||
ignoresPersistentStateOnLaunch = "NO" | ||
debugDocumentVersioning = "YES" | ||
debugServiceExtension = "internal" | ||
allowLocationSimulation = "YES"> | ||
<BuildableProductRunnable | ||
runnableDebuggingMode = "0"> | ||
<BuildableReference | ||
BuildableIdentifier = "primary" | ||
BlueprintIdentifier = "52B8CF63277E0B44004CB680" | ||
BuildableName = "PushDeerClip.app" | ||
BlueprintName = "PushDeerClip" | ||
ReferencedContainer = "container:PushDeer.xcodeproj"> | ||
</BuildableReference> | ||
</BuildableProductRunnable> | ||
<EnvironmentVariables> | ||
<EnvironmentVariable | ||
key = "_XCAppClipURL" | ||
value = "https://example.com" | ||
isEnabled = "NO"> | ||
</EnvironmentVariable> | ||
</EnvironmentVariables> | ||
</LaunchAction> | ||
<ProfileAction | ||
buildConfiguration = "Release" | ||
shouldUseLaunchSchemeArgsEnv = "YES" | ||
savedToolIdentifier = "" | ||
useCustomWorkingDirectory = "NO" | ||
debugDocumentVersioning = "YES"> | ||
<BuildableProductRunnable | ||
runnableDebuggingMode = "0"> | ||
<BuildableReference | ||
BuildableIdentifier = "primary" | ||
BlueprintIdentifier = "52B8CF63277E0B44004CB680" | ||
BuildableName = "PushDeerClip.app" | ||
BlueprintName = "PushDeerClip" | ||
ReferencedContainer = "container:PushDeer.xcodeproj"> | ||
</BuildableReference> | ||
</BuildableProductRunnable> | ||
</ProfileAction> | ||
<AnalyzeAction | ||
buildConfiguration = "Debug"> | ||
</AnalyzeAction> | ||
<ArchiveAction | ||
buildConfiguration = "Release" | ||
revealArchiveInOrganizer = "YES"> | ||
</ArchiveAction> | ||
</Scheme> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
// | ||
// MessageModel.swift | ||
// PushDeer | ||
// | ||
// Created by HEXT on 2022/1/15. | ||
// | ||
|
||
import Foundation | ||
import CoreData | ||
|
||
extension MessageModel { | ||
convenience init(id: Int64, uid: String, text: String, desp: String, type: String, pushkey_name: String, created_at: String, context: NSManagedObjectContext = PersistenceController.shared.container.viewContext) { | ||
self.init(context: context) | ||
self.id = id | ||
self.uid = uid | ||
self.text = text | ||
self.desp = desp | ||
self.type = type | ||
self.pushkey_name = pushkey_name | ||
self.created_at = created_at | ||
} | ||
convenience init(messageItem: MessageItem, context: NSManagedObjectContext = PersistenceController.shared.container.viewContext) { | ||
self.init( | ||
id: Int64(messageItem.id), | ||
uid: messageItem.uid, | ||
text: messageItem.text, | ||
desp: messageItem.desp, | ||
type: messageItem.type, | ||
pushkey_name: messageItem.pushkey_name, | ||
created_at: messageItem.created_at, | ||
context: context) | ||
} | ||
|
||
var createdDateStr: String { | ||
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSZ" | ||
let createdDate = dateFormatter.date(from: self.created_at ?? "") ?? Date() | ||
let timeInterval = -createdDate.timeIntervalSinceNow | ||
let minute = Int(floor(timeInterval / 60)) | ||
if minute == 0 { | ||
return "刚刚" | ||
} else if minute <= 30 { | ||
return "\(minute)分钟前" | ||
} else if Calendar.current.isDateInToday(createdDate) { | ||
dateFormatter.dateFormat = "HH:mm:ss" | ||
} else { | ||
dateFormatter.dateFormat = "yyyy/MM/dd HH:mm:ss" | ||
} | ||
return dateFormatter.string(from: createdDate) | ||
} | ||
|
||
static let _viewContext = PersistenceController.shared.container.viewContext | ||
static let _fetchRequest = MessageModel.fetchRequest() | ||
|
||
/// 持久化保存和更新 | ||
static func saveAndUpdate(messageItems: [MessageItem]) throws -> Void { | ||
try messageItems.forEach(saveAndUpdate) | ||
} | ||
|
||
/// 持久化保存和更新 | ||
static func saveAndUpdate(messageItem: MessageItem) throws -> Void { | ||
_fetchRequest.predicate = NSPredicate(format: "id = \(messageItem.id)") | ||
let models = try _viewContext.fetch(_fetchRequest) | ||
if models.isEmpty { | ||
// 如果本地不存在, 就构建一个新的放进 context | ||
_ = MessageModel(messageItem: messageItem, context: _viewContext) | ||
} else { | ||
// 如果存在, 就更新第一个, 删除其它重复的 | ||
models.enumerated().forEach { element in | ||
let messageModel = element.element | ||
let index = element.offset | ||
if index == 0 { | ||
messageModel.id = Int64(messageItem.id); | ||
messageModel.uid = messageItem.uid; | ||
messageModel.text = messageItem.text; | ||
messageModel.desp = messageItem.desp; | ||
messageModel.type = messageItem.type; | ||
messageModel.pushkey_name = messageItem.pushkey_name; | ||
messageModel.created_at = messageItem.created_at; | ||
} else { | ||
_viewContext.delete(messageModel) | ||
} | ||
} | ||
} | ||
// 保存 context 中的所有改动 | ||
try _viewContext.save() | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
ios/PushDeer-iOS/PushDeer/Model/PushDeerData.xcdatamodeld/PushDeerData.xcdatamodel/contents
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="19574" systemVersion="21C52" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier=""> | ||
<entity name="MessageModel" representedClassName="MessageModel" syncable="YES" codeGenerationType="class"> | ||
<attribute name="created_at" optional="YES" attributeType="String"/> | ||
<attribute name="desp" optional="YES" attributeType="String"/> | ||
<attribute name="id" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/> | ||
<attribute name="pushkey_name" optional="YES" attributeType="String"/> | ||
<attribute name="text" optional="YES" attributeType="String"/> | ||
<attribute name="type" optional="YES" attributeType="String"/> | ||
<attribute name="uid" optional="YES" attributeType="String"/> | ||
</entity> | ||
<elements> | ||
<element name="MessageModel" positionX="-45" positionY="1" width="128" height="148"/> | ||
</elements> | ||
</model> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// | ||
// Persistence.swift | ||
// PushDeer | ||
// | ||
// Created by HEXT on 2022/1/14. | ||
// | ||
|
||
import CoreData | ||
|
||
struct PersistenceController { | ||
|
||
static let shared = PersistenceController() | ||
|
||
let container: NSPersistentContainer | ||
|
||
init(inMemory: Bool = false) { | ||
container = NSPersistentContainer(name: "PushDeerData") | ||
if inMemory { | ||
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null") | ||
} | ||
container.loadPersistentStores(completionHandler: { (storeDescription, error) in | ||
if let error = error as NSError? { | ||
// Replace this implementation with code to handle the error appropriately. | ||
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. | ||
|
||
/* | ||
Typical reasons for an error here include: | ||
* The parent directory does not exist, cannot be created, or disallows writing. | ||
* The persistent store is not accessible, due to permissions or data protection when the device is locked. | ||
* The device is out of space. | ||
* The store could not be migrated to the current model version. | ||
Check the error message to determine what the actual problem was. | ||
*/ | ||
fatalError("Unresolved error \(error), \(error.userInfo)") | ||
} | ||
}) | ||
container.viewContext.automaticallyMergesChangesFromParent = true | ||
} | ||
} |
Oops, something went wrong.