Move SwiftCSV into the project
This commit is contained in:
parent
056ec0349a
commit
8e651aadc2
1
Podfile
1
Podfile
|
@ -63,7 +63,6 @@ def shared_pods
|
||||||
pod 'Reachability', :inhibit_warnings => true
|
pod 'Reachability', :inhibit_warnings => true
|
||||||
pod 'YYImage', :inhibit_warnings => true
|
pod 'YYImage', :inhibit_warnings => true
|
||||||
pod 'ZXingObjC', '~> 3.6.4', :inhibit_warnings => true
|
pod 'ZXingObjC', '~> 3.6.4', :inhibit_warnings => true
|
||||||
pod 'SwiftCSV', '~> 0.5.6', :inhibit_warnings => true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
target 'Signal' do
|
target 'Signal' do
|
||||||
|
|
|
@ -129,7 +129,6 @@ PODS:
|
||||||
- SQLCipher/common
|
- SQLCipher/common
|
||||||
- SSZipArchive (2.2.3)
|
- SSZipArchive (2.2.3)
|
||||||
- Starscream (3.0.6)
|
- Starscream (3.0.6)
|
||||||
- SwiftCSV (0.5.6)
|
|
||||||
- SwiftProtobuf (1.5.0)
|
- SwiftProtobuf (1.5.0)
|
||||||
- YapDatabase/SQLCipher (3.1.1):
|
- YapDatabase/SQLCipher (3.1.1):
|
||||||
- YapDatabase/SQLCipher/Core (= 3.1.1)
|
- YapDatabase/SQLCipher/Core (= 3.1.1)
|
||||||
|
@ -226,7 +225,6 @@ DEPENDENCIES:
|
||||||
- SQLCipher (>= 4.0.1)
|
- SQLCipher (>= 4.0.1)
|
||||||
- SSZipArchive
|
- SSZipArchive
|
||||||
- Starscream (from `https://github.com/signalapp/Starscream.git`, branch `signal-release`)
|
- Starscream (from `https://github.com/signalapp/Starscream.git`, branch `signal-release`)
|
||||||
- SwiftCSV (~> 0.5.6)
|
|
||||||
- YapDatabase/SQLCipher (from `https://github.com/signalapp/YapDatabase.git`, branch `signal-release`)
|
- YapDatabase/SQLCipher (from `https://github.com/signalapp/YapDatabase.git`, branch `signal-release`)
|
||||||
- YYImage
|
- YYImage
|
||||||
- ZXingObjC (~> 3.6.4)
|
- ZXingObjC (~> 3.6.4)
|
||||||
|
@ -246,7 +244,6 @@ SPEC REPOS:
|
||||||
- SAMKeychain
|
- SAMKeychain
|
||||||
- SQLCipher
|
- SQLCipher
|
||||||
- SSZipArchive
|
- SSZipArchive
|
||||||
- SwiftCSV
|
|
||||||
- SwiftProtobuf
|
- SwiftProtobuf
|
||||||
- YYImage
|
- YYImage
|
||||||
- ZXingObjC
|
- ZXingObjC
|
||||||
|
@ -329,12 +326,11 @@ SPEC CHECKSUMS:
|
||||||
SQLCipher: e434ed542b24f38ea7b36468a13f9765e1b5c072
|
SQLCipher: e434ed542b24f38ea7b36468a13f9765e1b5c072
|
||||||
SSZipArchive: 62d4947b08730e4cda640473b0066d209ff033c9
|
SSZipArchive: 62d4947b08730e4cda640473b0066d209ff033c9
|
||||||
Starscream: 8aaf1a7feb805c816d0e7d3190ef23856f6665b9
|
Starscream: 8aaf1a7feb805c816d0e7d3190ef23856f6665b9
|
||||||
SwiftCSV: efb4a15dd7f2f1212b3d6986f97a3369ff6c5100
|
|
||||||
SwiftProtobuf: 241400280f912735c1e1b9fe675fdd2c6c4d42e2
|
SwiftProtobuf: 241400280f912735c1e1b9fe675fdd2c6c4d42e2
|
||||||
YapDatabase: b418a4baa6906e8028748938f9159807fd039af4
|
YapDatabase: b418a4baa6906e8028748938f9159807fd039af4
|
||||||
YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54
|
YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54
|
||||||
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
|
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
|
||||||
|
|
||||||
PODFILE CHECKSUM: 8803b27f35a08849d8e3e6595c88b62522a16ae7
|
PODFILE CHECKSUM: c26d913ac0e7de8c047412658746634a46681fed
|
||||||
|
|
||||||
COCOAPODS: 1.9.3
|
COCOAPODS: 1.9.3
|
||||||
|
|
|
@ -582,6 +582,13 @@
|
||||||
C3638C0524C7F0B500AF29BC /* LK002RemoveFriendRequests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3638C0424C7F0B500AF29BC /* LK002RemoveFriendRequests.swift */; };
|
C3638C0524C7F0B500AF29BC /* LK002RemoveFriendRequests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3638C0424C7F0B500AF29BC /* LK002RemoveFriendRequests.swift */; };
|
||||||
C369549D24D27A3500CEB4E3 /* MultiDeviceRemovalSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C369549C24D27A3500CEB4E3 /* MultiDeviceRemovalSheet.swift */; };
|
C369549D24D27A3500CEB4E3 /* MultiDeviceRemovalSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C369549C24D27A3500CEB4E3 /* MultiDeviceRemovalSheet.swift */; };
|
||||||
C36B8707243C50C60049991D /* SignalMessaging.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 453518921FC63DBF00210559 /* SignalMessaging.framework */; };
|
C36B8707243C50C60049991D /* SignalMessaging.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 453518921FC63DBF00210559 /* SignalMessaging.framework */; };
|
||||||
|
C396DAEF2518408B00FF6DC5 /* ParsingState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C396DAE82518408900FF6DC5 /* ParsingState.swift */; };
|
||||||
|
C396DAF02518408B00FF6DC5 /* String+Lines.swift in Sources */ = {isa = PBXBuildFile; fileRef = C396DAE92518408A00FF6DC5 /* String+Lines.swift */; };
|
||||||
|
C396DAF12518408B00FF6DC5 /* EnumeratedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C396DAEA2518408A00FF6DC5 /* EnumeratedView.swift */; };
|
||||||
|
C396DAF22518408B00FF6DC5 /* NamedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C396DAEB2518408A00FF6DC5 /* NamedView.swift */; };
|
||||||
|
C396DAF32518408B00FF6DC5 /* Description.swift in Sources */ = {isa = PBXBuildFile; fileRef = C396DAEC2518408A00FF6DC5 /* Description.swift */; };
|
||||||
|
C396DAF42518408B00FF6DC5 /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = C396DAED2518408B00FF6DC5 /* Parser.swift */; };
|
||||||
|
C396DAF52518408B00FF6DC5 /* CSV.swift in Sources */ = {isa = PBXBuildFile; fileRef = C396DAEE2518408B00FF6DC5 /* CSV.swift */; };
|
||||||
C39DD28824F3318C008590FC /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C39DD28724F3318C008590FC /* Colors.xcassets */; };
|
C39DD28824F3318C008590FC /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C39DD28724F3318C008590FC /* Colors.xcassets */; };
|
||||||
C39DD28A24F3336E008590FC /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C39DD28724F3318C008590FC /* Colors.xcassets */; };
|
C39DD28A24F3336E008590FC /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C39DD28724F3318C008590FC /* Colors.xcassets */; };
|
||||||
C39DD28B24F3336F008590FC /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C39DD28724F3318C008590FC /* Colors.xcassets */; };
|
C39DD28B24F3336F008590FC /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C39DD28724F3318C008590FC /* Colors.xcassets */; };
|
||||||
|
@ -1373,6 +1380,13 @@
|
||||||
C396469D2509D3F400B0B9F5 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = translations/ja.lproj/Localizable.strings; sourceTree = "<group>"; };
|
C396469D2509D3F400B0B9F5 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = translations/ja.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
C396469E2509D40400B0B9F5 /* vi-VN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "vi-VN"; path = "translations/vi-VN.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
C396469E2509D40400B0B9F5 /* vi-VN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "vi-VN"; path = "translations/vi-VN.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||||
C396469F2509D41100B0B9F5 /* id-ID */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "id-ID"; path = "translations/id-ID.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
C396469F2509D41100B0B9F5 /* id-ID */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "id-ID"; path = "translations/id-ID.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||||
|
C396DAE82518408900FF6DC5 /* ParsingState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParsingState.swift; sourceTree = "<group>"; };
|
||||||
|
C396DAE92518408A00FF6DC5 /* String+Lines.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Lines.swift"; sourceTree = "<group>"; };
|
||||||
|
C396DAEA2518408A00FF6DC5 /* EnumeratedView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnumeratedView.swift; sourceTree = "<group>"; };
|
||||||
|
C396DAEB2518408A00FF6DC5 /* NamedView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NamedView.swift; sourceTree = "<group>"; };
|
||||||
|
C396DAEC2518408A00FF6DC5 /* Description.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Description.swift; sourceTree = "<group>"; };
|
||||||
|
C396DAED2518408B00FF6DC5 /* Parser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Parser.swift; sourceTree = "<group>"; };
|
||||||
|
C396DAEE2518408B00FF6DC5 /* CSV.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSV.swift; sourceTree = "<group>"; };
|
||||||
C39DD28724F3318C008590FC /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = "<group>"; };
|
C39DD28724F3318C008590FC /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = "<group>"; };
|
||||||
C3AA6BB824CE8F1B002358B6 /* Migrating Translations from Android.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "Migrating Translations from Android.md"; sourceTree = "<group>"; };
|
C3AA6BB824CE8F1B002358B6 /* Migrating Translations from Android.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "Migrating Translations from Android.md"; sourceTree = "<group>"; };
|
||||||
C3AECBEA24EF5244005743DE /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = translations/fa.lproj/Localizable.strings; sourceTree = "<group>"; };
|
C3AECBEA24EF5244005743DE /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = translations/fa.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
|
@ -2728,6 +2742,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
C3DAB3232480CB2A00725F25 /* SRCopyableLabel.swift */,
|
C3DAB3232480CB2A00725F25 /* SRCopyableLabel.swift */,
|
||||||
|
C396DAE72518407300FF6DC5 /* SwiftCSV */,
|
||||||
);
|
);
|
||||||
path = Dependencies;
|
path = Dependencies;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2749,6 +2764,20 @@
|
||||||
path = Migrations;
|
path = Migrations;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
C396DAE72518407300FF6DC5 /* SwiftCSV */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
C396DAEE2518408B00FF6DC5 /* CSV.swift */,
|
||||||
|
C396DAEC2518408A00FF6DC5 /* Description.swift */,
|
||||||
|
C396DAEA2518408A00FF6DC5 /* EnumeratedView.swift */,
|
||||||
|
C396DAEB2518408A00FF6DC5 /* NamedView.swift */,
|
||||||
|
C396DAED2518408B00FF6DC5 /* Parser.swift */,
|
||||||
|
C396DAE82518408900FF6DC5 /* ParsingState.swift */,
|
||||||
|
C396DAE92518408A00FF6DC5 /* String+Lines.swift */,
|
||||||
|
);
|
||||||
|
path = SwiftCSV;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
D221A07E169C9E5E00537ABF = {
|
D221A07E169C9E5E00537ABF = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -3413,7 +3442,6 @@
|
||||||
"${BUILT_PRODUCTS_DIR}/SessionMetadataKit/SessionMetadataKit.framework",
|
"${BUILT_PRODUCTS_DIR}/SessionMetadataKit/SessionMetadataKit.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/SessionServiceKit/SessionServiceKit.framework",
|
"${BUILT_PRODUCTS_DIR}/SessionServiceKit/SessionServiceKit.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/Starscream/Starscream.framework",
|
"${BUILT_PRODUCTS_DIR}/Starscream/Starscream.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/SwiftCSV/SwiftCSV.framework",
|
|
||||||
"${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework",
|
"${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/YYImage/YYImage.framework",
|
"${BUILT_PRODUCTS_DIR}/YYImage/YYImage.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/YapDatabase/YapDatabase.framework",
|
"${BUILT_PRODUCTS_DIR}/YapDatabase/YapDatabase.framework",
|
||||||
|
@ -3443,7 +3471,6 @@
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SessionMetadataKit.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SessionMetadataKit.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SessionServiceKit.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SessionServiceKit.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Starscream.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Starscream.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftCSV.framework",
|
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYImage.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYImage.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YapDatabase.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YapDatabase.framework",
|
||||||
|
@ -3497,7 +3524,6 @@
|
||||||
"${BUILT_PRODUCTS_DIR}/SessionMetadataKit/SessionMetadataKit.framework",
|
"${BUILT_PRODUCTS_DIR}/SessionMetadataKit/SessionMetadataKit.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/SessionServiceKit/SessionServiceKit.framework",
|
"${BUILT_PRODUCTS_DIR}/SessionServiceKit/SessionServiceKit.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/Starscream/Starscream.framework",
|
"${BUILT_PRODUCTS_DIR}/Starscream/Starscream.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/SwiftCSV/SwiftCSV.framework",
|
|
||||||
"${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework",
|
"${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/YYImage/YYImage.framework",
|
"${BUILT_PRODUCTS_DIR}/YYImage/YYImage.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/YapDatabase/YapDatabase.framework",
|
"${BUILT_PRODUCTS_DIR}/YapDatabase/YapDatabase.framework",
|
||||||
|
@ -3523,7 +3549,6 @@
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SessionMetadataKit.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SessionMetadataKit.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SessionServiceKit.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SessionServiceKit.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Starscream.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Starscream.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftCSV.framework",
|
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYImage.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYImage.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YapDatabase.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YapDatabase.framework",
|
||||||
|
@ -3729,10 +3754,12 @@
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
C396DAF52518408B00FF6DC5 /* CSV.swift in Sources */,
|
||||||
B8CCF63723961D6D0091D419 /* NewPrivateChatVC.swift in Sources */,
|
B8CCF63723961D6D0091D419 /* NewPrivateChatVC.swift in Sources */,
|
||||||
4CC0B59C20EC5F2E00CF6EE0 /* ConversationConfigurationSyncOperation.swift in Sources */,
|
4CC0B59C20EC5F2E00CF6EE0 /* ConversationConfigurationSyncOperation.swift in Sources */,
|
||||||
3461293E1FD1D72B00532771 /* ExperienceUpgradeFinder.swift in Sources */,
|
3461293E1FD1D72B00532771 /* ExperienceUpgradeFinder.swift in Sources */,
|
||||||
34C4E2582118957600BEA353 /* WebRTCProto.swift in Sources */,
|
34C4E2582118957600BEA353 /* WebRTCProto.swift in Sources */,
|
||||||
|
C396DAF12518408B00FF6DC5 /* EnumeratedView.swift in Sources */,
|
||||||
34D1F0BD1F8D108C0066283D /* AttachmentUploadView.m in Sources */,
|
34D1F0BD1F8D108C0066283D /* AttachmentUploadView.m in Sources */,
|
||||||
452EC6DF205E9E30000E787C /* MediaGalleryViewController.swift in Sources */,
|
452EC6DF205E9E30000E787C /* MediaGalleryViewController.swift in Sources */,
|
||||||
34DC9BD921543E0C00FDDCEC /* DebugContactsUtils.m in Sources */,
|
34DC9BD921543E0C00FDDCEC /* DebugContactsUtils.m in Sources */,
|
||||||
|
@ -3778,6 +3805,7 @@
|
||||||
4CEB78C92178EBAB00F315D2 /* OWSSessionResetJobRecord.m in Sources */,
|
4CEB78C92178EBAB00F315D2 /* OWSSessionResetJobRecord.m in Sources */,
|
||||||
45794E861E00620000066731 /* CallUIAdapter.swift in Sources */,
|
45794E861E00620000066731 /* CallUIAdapter.swift in Sources */,
|
||||||
340FC8BA204DAC8D007AEB0F /* FingerprintViewScanController.m in Sources */,
|
340FC8BA204DAC8D007AEB0F /* FingerprintViewScanController.m in Sources */,
|
||||||
|
C396DAF32518408B00FF6DC5 /* Description.swift in Sources */,
|
||||||
4585C4681ED8F8D200896AEA /* SafetyNumberConfirmationAlert.swift in Sources */,
|
4585C4681ED8F8D200896AEA /* SafetyNumberConfirmationAlert.swift in Sources */,
|
||||||
B85357C123A1B81900AAF6CD /* SeedReminderViewDelegate.swift in Sources */,
|
B85357C123A1B81900AAF6CD /* SeedReminderViewDelegate.swift in Sources */,
|
||||||
450D19131F85236600970622 /* RemoteVideoView.m in Sources */,
|
450D19131F85236600970622 /* RemoteVideoView.m in Sources */,
|
||||||
|
@ -3804,6 +3832,7 @@
|
||||||
B80C6B572384A56D00FDBC8B /* DeviceLinksVC.swift in Sources */,
|
B80C6B572384A56D00FDBC8B /* DeviceLinksVC.swift in Sources */,
|
||||||
34A8B3512190A40E00218A25 /* MediaAlbumCellView.swift in Sources */,
|
34A8B3512190A40E00218A25 /* MediaAlbumCellView.swift in Sources */,
|
||||||
34D1F0AE1F867BFC0066283D /* OWSMessageCell.m in Sources */,
|
34D1F0AE1F867BFC0066283D /* OWSMessageCell.m in Sources */,
|
||||||
|
C396DAF42518408B00FF6DC5 /* Parser.swift in Sources */,
|
||||||
B8BB82AB238F669C00BA5194 /* ConversationCell.swift in Sources */,
|
B8BB82AB238F669C00BA5194 /* ConversationCell.swift in Sources */,
|
||||||
4C4AEC4520EC343B0020E72B /* DismissableTextField.swift in Sources */,
|
4C4AEC4520EC343B0020E72B /* DismissableTextField.swift in Sources */,
|
||||||
4CB5F26720F6E1E2004D1B42 /* MenuActionsViewController.swift in Sources */,
|
4CB5F26720F6E1E2004D1B42 /* MenuActionsViewController.swift in Sources */,
|
||||||
|
@ -3875,6 +3904,7 @@
|
||||||
C3DAB3242480CB2B00725F25 /* SRCopyableLabel.swift in Sources */,
|
C3DAB3242480CB2B00725F25 /* SRCopyableLabel.swift in Sources */,
|
||||||
B8B26C8F234D629C004ED98C /* MentionCandidateSelectionView.swift in Sources */,
|
B8B26C8F234D629C004ED98C /* MentionCandidateSelectionView.swift in Sources */,
|
||||||
B879D44B247E1D9200DB3608 /* PathStatusView.swift in Sources */,
|
B879D44B247E1D9200DB3608 /* PathStatusView.swift in Sources */,
|
||||||
|
C396DAF02518408B00FF6DC5 /* String+Lines.swift in Sources */,
|
||||||
B8CCF63F23975CFB0091D419 /* JoinPublicChatVC.swift in Sources */,
|
B8CCF63F23975CFB0091D419 /* JoinPublicChatVC.swift in Sources */,
|
||||||
34ABC0E421DD20C500ED9469 /* ConversationMessageMapping.swift in Sources */,
|
34ABC0E421DD20C500ED9469 /* ConversationMessageMapping.swift in Sources */,
|
||||||
34D8C0271ED3673300188D7C /* DebugUIMessages.m in Sources */,
|
34D8C0271ED3673300188D7C /* DebugUIMessages.m in Sources */,
|
||||||
|
@ -3896,6 +3926,7 @@
|
||||||
4539B5861F79348F007141FF /* PushRegistrationManager.swift in Sources */,
|
4539B5861F79348F007141FF /* PushRegistrationManager.swift in Sources */,
|
||||||
45FBC5D11DF8592E00E9B410 /* SignalCall.swift in Sources */,
|
45FBC5D11DF8592E00E9B410 /* SignalCall.swift in Sources */,
|
||||||
B8B26C91234D8CBD004ED98C /* MentionCandidateSelectionViewDelegate.swift in Sources */,
|
B8B26C91234D8CBD004ED98C /* MentionCandidateSelectionViewDelegate.swift in Sources */,
|
||||||
|
C396DAF22518408B00FF6DC5 /* NamedView.swift in Sources */,
|
||||||
340FC8BB204DAC8D007AEB0F /* OWSAddToContactViewController.m in Sources */,
|
340FC8BB204DAC8D007AEB0F /* OWSAddToContactViewController.m in Sources */,
|
||||||
45F32C232057297A00A300D5 /* MediaPageViewController.swift in Sources */,
|
45F32C232057297A00A300D5 /* MediaPageViewController.swift in Sources */,
|
||||||
452C468F1E427E200087B011 /* OutboundCallInitiator.swift in Sources */,
|
452C468F1E427E200087B011 /* OutboundCallInitiator.swift in Sources */,
|
||||||
|
@ -3915,6 +3946,7 @@
|
||||||
B82B4090239DD75000A248E7 /* RestoreVC.swift in Sources */,
|
B82B4090239DD75000A248E7 /* RestoreVC.swift in Sources */,
|
||||||
3488F9362191CC4000E524CC /* ConversationMediaView.swift in Sources */,
|
3488F9362191CC4000E524CC /* ConversationMediaView.swift in Sources */,
|
||||||
45F32C242057297A00A300D5 /* MessageDetailViewController.swift in Sources */,
|
45F32C242057297A00A300D5 /* MessageDetailViewController.swift in Sources */,
|
||||||
|
C396DAEF2518408B00FF6DC5 /* ParsingState.swift in Sources */,
|
||||||
3496955C219B605E00DCFE74 /* ImagePickerController.swift in Sources */,
|
3496955C219B605E00DCFE74 /* ImagePickerController.swift in Sources */,
|
||||||
B8BB82B523947F2D00BA5194 /* TextField.swift in Sources */,
|
B8BB82B523947F2D00BA5194 /* TextField.swift in Sources */,
|
||||||
34D1F0841F8678AA0066283D /* ConversationInputToolbar.m in Sources */,
|
34D1F0841F8678AA0066283D /* ConversationInputToolbar.m in Sources */,
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
//
|
||||||
|
// CSV.swift
|
||||||
|
// SwiftCSV
|
||||||
|
//
|
||||||
|
// Created by Naoto Kaneko on 2/18/16.
|
||||||
|
// Copyright © 2016 Naoto Kaneko. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol View {
|
||||||
|
associatedtype Rows
|
||||||
|
associatedtype Columns
|
||||||
|
|
||||||
|
var rows: Rows { get }
|
||||||
|
var columns: Columns { get }
|
||||||
|
|
||||||
|
init(header: [String], text: String, delimiter: Character, limitTo: Int?, loadColumns: Bool) throws
|
||||||
|
}
|
||||||
|
|
||||||
|
open class CSV {
|
||||||
|
static public let comma: Character = ","
|
||||||
|
|
||||||
|
public let header: [String]
|
||||||
|
|
||||||
|
lazy var _namedView: NamedView = {
|
||||||
|
return try! NamedView(
|
||||||
|
header: self.header,
|
||||||
|
text: self.text,
|
||||||
|
delimiter: self.delimiter,
|
||||||
|
loadColumns: self.loadColumns)
|
||||||
|
}()
|
||||||
|
|
||||||
|
lazy var _enumeratedView: EnumeratedView = {
|
||||||
|
return try! EnumeratedView(
|
||||||
|
header: self.header,
|
||||||
|
text: self.text,
|
||||||
|
delimiter: self.delimiter,
|
||||||
|
loadColumns: self.loadColumns)
|
||||||
|
}()
|
||||||
|
|
||||||
|
var text: String
|
||||||
|
var delimiter: Character
|
||||||
|
|
||||||
|
let loadColumns: Bool
|
||||||
|
|
||||||
|
/// List of dictionaries that contains the CSV data
|
||||||
|
public var namedRows: [[String : String]] {
|
||||||
|
return _namedView.rows
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Dictionary of header name to list of values in that column
|
||||||
|
/// Will not be loaded if loadColumns in init is false
|
||||||
|
public var namedColumns: [String : [String]] {
|
||||||
|
return _namedView.columns
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Collection of column fields that contain the CSV data
|
||||||
|
public var enumeratedRows: [[String]] {
|
||||||
|
return _enumeratedView.rows
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Collection of columns with metadata.
|
||||||
|
/// Will not be loaded if loadColumns in init is false
|
||||||
|
public var enumeratedColumns: [EnumeratedView.Column] {
|
||||||
|
return _enumeratedView.columns
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@available(*, unavailable, renamed: "namedRows")
|
||||||
|
public var rows: [[String : String]] {
|
||||||
|
return namedRows
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(*, unavailable, renamed: "namedColumns")
|
||||||
|
public var columns: [String : [String]] {
|
||||||
|
return namedColumns
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Load CSV data from a string.
|
||||||
|
///
|
||||||
|
/// - parameter string: CSV contents to parse.
|
||||||
|
/// - parameter delimiter: Character used to separate row and header fields (default is ',')
|
||||||
|
/// - parameter loadColumns: Whether to populate the `columns` dictionary (default is `true`)
|
||||||
|
/// - throws: `CSVParseError` when parsing `string` fails.
|
||||||
|
public init(string: String, delimiter: Character = comma, loadColumns: Bool = true) throws {
|
||||||
|
self.text = string
|
||||||
|
self.delimiter = delimiter
|
||||||
|
self.loadColumns = loadColumns
|
||||||
|
self.header = try Parser.array(text: string, delimiter: delimiter, limitTo: 1).first ?? []
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(*, deprecated, message: "Use init(url:delimiter:encoding:loadColumns:) instead of this path-based approach. Also, calling the parameter `name` instead of `path` was a mistake.")
|
||||||
|
public convenience init(name: String, delimiter: Character = comma, encoding: String.Encoding = .utf8, loadColumns: Bool = true) throws {
|
||||||
|
try self.init(url: URL(fileURLWithPath: name), delimiter: delimiter, encoding: encoding, loadColumns: loadColumns)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load a CSV file as a named resource from `bundle`.
|
||||||
|
///
|
||||||
|
/// - parameter name: Name of the file resource inside `bundle`.
|
||||||
|
/// - parameter ext: File extension of the resource; use `nil` to load the first file matching the name (default is `nil`)
|
||||||
|
/// - parameter bundle: `Bundle` to use for resource lookup (default is `.main`)
|
||||||
|
/// - parameter delimiter: Character used to separate row and header fields (default is ',')
|
||||||
|
/// - parameter encoding: encoding used to read file (default is `.utf8`)
|
||||||
|
/// - parameter loadColumns: Whether to populate the columns dictionary (default is `true`)
|
||||||
|
/// - throws: `CSVParseError` when parsing the contents of the resource fails, or file loading errors.
|
||||||
|
/// - returns: `nil` if the resource could not be found
|
||||||
|
public convenience init?(name: String, extension ext: String? = nil, bundle: Bundle = .main, delimiter: Character = comma, encoding: String.Encoding = .utf8, loadColumns: Bool = true) throws {
|
||||||
|
guard let url = bundle.url(forResource: name, withExtension: ext) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
try self.init(url: url, delimiter: delimiter, encoding: encoding, loadColumns: loadColumns)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load a CSV file from `url`.
|
||||||
|
///
|
||||||
|
/// - parameter url: URL of the file (will be passed to `String(contentsOfURL:encoding:)` to load)
|
||||||
|
/// - parameter delimiter: Character used to separate row and header fields (default is ',')
|
||||||
|
/// - parameter encoding: Character encoding to read file (default is `.utf8`)
|
||||||
|
/// - parameter loadColumns: Whether to populate the columns dictionary (default is `true`)
|
||||||
|
/// - throws: `CSVParseError` when parsing the contents of `url` fails, or file loading errors.
|
||||||
|
public convenience init(url: URL, delimiter: Character = comma, encoding: String.Encoding = .utf8, loadColumns: Bool = true) throws {
|
||||||
|
let contents = try String(contentsOf: url, encoding: encoding)
|
||||||
|
|
||||||
|
try self.init(string: contents, delimiter: delimiter, loadColumns: loadColumns)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Turn the CSV data into NSData using a given encoding
|
||||||
|
open func dataUsingEncoding(_ encoding: String.Encoding) -> Data? {
|
||||||
|
return description.data(using: encoding)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
//
|
||||||
|
// Description.swift
|
||||||
|
// SwiftCSV
|
||||||
|
//
|
||||||
|
// Created by Will Richardson on 11/04/16.
|
||||||
|
// Copyright © 2016 Naoto Kaneko. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension CSV: CustomStringConvertible {
|
||||||
|
public var description: String {
|
||||||
|
let head = header.joined(separator: ",") + "\n"
|
||||||
|
let cont = namedRows.map { row in
|
||||||
|
return header.map { key -> String in
|
||||||
|
let value = row[key]!
|
||||||
|
|
||||||
|
// Add quotes if value contains a comma
|
||||||
|
if value.contains(",") {
|
||||||
|
return "\"\(value)\""
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
|
||||||
|
}.joined(separator: ",")
|
||||||
|
|
||||||
|
}.joined(separator: "\n")
|
||||||
|
return head + cont
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
//
|
||||||
|
// EnumeratedView.swift
|
||||||
|
// SwiftCSV
|
||||||
|
//
|
||||||
|
// Created by Christian Tietze on 25/10/16.
|
||||||
|
// Copyright © 2016 Naoto Kaneko. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public struct EnumeratedView: View {
|
||||||
|
|
||||||
|
public struct Column {
|
||||||
|
public let header: String
|
||||||
|
public let rows: [String]
|
||||||
|
}
|
||||||
|
|
||||||
|
public private(set) var rows: [[String]]
|
||||||
|
public private(set) var columns: [Column]
|
||||||
|
|
||||||
|
public init(header: [String], text: String, delimiter: Character, limitTo: Int? = nil, loadColumns: Bool = false) throws {
|
||||||
|
|
||||||
|
var rows = [[String]]()
|
||||||
|
var columns: [EnumeratedView.Column] = []
|
||||||
|
|
||||||
|
try Parser.enumerateAsArray(text: text, delimiter: delimiter, limitTo: limitTo, startAt: 1) { fields in
|
||||||
|
rows.append(fields)
|
||||||
|
}
|
||||||
|
|
||||||
|
if loadColumns {
|
||||||
|
columns = header.enumerated().map { (index: Int, header: String) -> EnumeratedView.Column in
|
||||||
|
|
||||||
|
return EnumeratedView.Column(
|
||||||
|
header: header,
|
||||||
|
rows: rows.map { $0[index] })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.rows = rows
|
||||||
|
self.columns = columns
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
//
|
||||||
|
// NamedView.swift
|
||||||
|
// SwiftCSV
|
||||||
|
//
|
||||||
|
// Created by Christian Tietze on 22/10/16.
|
||||||
|
// Copyright © 2016 Naoto Kaneko. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
public struct NamedView: View {
|
||||||
|
|
||||||
|
public var rows: [[String : String]]
|
||||||
|
public var columns: [String : [String]]
|
||||||
|
|
||||||
|
public init(header: [String], text: String, delimiter: Character, limitTo: Int? = nil, loadColumns: Bool = false) throws {
|
||||||
|
|
||||||
|
var rows = [[String: String]]()
|
||||||
|
var columns = [String: [String]]()
|
||||||
|
|
||||||
|
try Parser.enumerateAsDict(header: header, content: text, delimiter: delimiter, limitTo: limitTo) { dict in
|
||||||
|
rows.append(dict)
|
||||||
|
}
|
||||||
|
|
||||||
|
if loadColumns {
|
||||||
|
for field in header {
|
||||||
|
columns[field] = rows.map { $0[field] ?? "" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.rows = rows
|
||||||
|
self.columns = columns
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
//
|
||||||
|
// Parser.swift
|
||||||
|
// SwiftCSV
|
||||||
|
//
|
||||||
|
// Created by Will Richardson on 13/04/16.
|
||||||
|
// Copyright © 2016 Naoto Kaneko. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
extension CSV {
|
||||||
|
/// Parse the file and call a block on each row, passing it in as a list of fields
|
||||||
|
/// limitTo will limit the result to a certain number of lines
|
||||||
|
public func enumerateAsArray(limitTo: Int? = nil, startAt: Int = 0, _ block: @escaping ([String]) -> ()) throws {
|
||||||
|
|
||||||
|
try Parser.enumerateAsArray(text: self.text, delimiter: self.delimiter, limitTo: limitTo, startAt: startAt, block: block)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func enumerateAsDict(_ block: @escaping ([String : String]) -> ()) throws {
|
||||||
|
|
||||||
|
try Parser.enumerateAsDict(header: self.header, content: self.text, delimiter: self.delimiter, block: block)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Parser {
|
||||||
|
|
||||||
|
static func array(text: String, delimiter: Character, limitTo: Int? = nil, startAt: Int = 0) throws -> [[String]] {
|
||||||
|
|
||||||
|
var rows = [[String]]()
|
||||||
|
|
||||||
|
try enumerateAsArray(text: text, delimiter: delimiter) { row in
|
||||||
|
rows.append(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
return rows
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse the text and call a block on each row, passing it in as a list of fields.
|
||||||
|
///
|
||||||
|
/// - parameter text: Text to parse.
|
||||||
|
/// - parameter delimiter: Character to split row and header fields by (default is ',')
|
||||||
|
/// - parameter limitTo: If set to non-nil value, enumeration stops
|
||||||
|
/// at the row with index `limitTo` (or on end-of-text, whichever is earlier.
|
||||||
|
/// - parameter startAt: Offset of rows to ignore before invoking `block` for the first time. Default is 0.
|
||||||
|
/// - parameter block: Callback invoked for every parsed row between `startAt` and `limitTo` in `text`.
|
||||||
|
static func enumerateAsArray(text: String, delimiter: Character, limitTo: Int? = nil, startAt: Int = 0, block: @escaping ([String]) -> ()) throws {
|
||||||
|
var currentIndex = text.startIndex
|
||||||
|
let endIndex = text.endIndex
|
||||||
|
|
||||||
|
var fields = [String]()
|
||||||
|
var field = ""
|
||||||
|
|
||||||
|
var count = 0
|
||||||
|
|
||||||
|
func finishRow() {
|
||||||
|
fields.append(String(field))
|
||||||
|
if count >= startAt {
|
||||||
|
block(fields)
|
||||||
|
}
|
||||||
|
count += 1
|
||||||
|
fields = [String]()
|
||||||
|
field = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
var state: ParsingState = ParsingState(
|
||||||
|
delimiter: delimiter,
|
||||||
|
finishRow: finishRow,
|
||||||
|
appendChar: { field.append($0) },
|
||||||
|
finishField: {
|
||||||
|
fields.append(field)
|
||||||
|
field = ""
|
||||||
|
})
|
||||||
|
|
||||||
|
func limitReached(_ count: Int) -> Bool {
|
||||||
|
|
||||||
|
guard let limitTo = limitTo,
|
||||||
|
count >= limitTo
|
||||||
|
else { return false }
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
while currentIndex < endIndex {
|
||||||
|
let char = text[currentIndex]
|
||||||
|
|
||||||
|
try state.change(char)
|
||||||
|
|
||||||
|
if limitReached(count) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
currentIndex = text.index(after: currentIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !fields.isEmpty || !field.isEmpty || limitReached(count) {
|
||||||
|
fields.append(field)
|
||||||
|
block(fields)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func enumerateAsDict(header: [String], content: String, delimiter: Character, limitTo: Int? = nil, block: @escaping ([String : String]) -> ()) throws {
|
||||||
|
|
||||||
|
let enumeratedHeader = header.enumerated()
|
||||||
|
|
||||||
|
try enumerateAsArray(text: content, delimiter: delimiter, startAt: 1) { fields in
|
||||||
|
var dict = [String: String]()
|
||||||
|
for (index, head) in enumeratedHeader {
|
||||||
|
dict[head] = index < fields.count ? fields[index] : ""
|
||||||
|
}
|
||||||
|
block(dict)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
//
|
||||||
|
// ParsingState.swift
|
||||||
|
// SwiftCSV
|
||||||
|
//
|
||||||
|
// Created by Christian Tietze on 25/10/16.
|
||||||
|
// Copyright © 2016 Naoto Kaneko. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
public enum CSVParseError: Error {
|
||||||
|
case generic(message: String)
|
||||||
|
case quotation(message: String)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// State machine of parsing CSV contents character by character.
|
||||||
|
struct ParsingState {
|
||||||
|
|
||||||
|
private(set) var atStart = true
|
||||||
|
private(set) var parsingField = false
|
||||||
|
private(set) var parsingQuotes = false
|
||||||
|
private(set) var innerQuotes = false
|
||||||
|
|
||||||
|
let delimiter: Character
|
||||||
|
let finishRow: () -> Void
|
||||||
|
let appendChar: (Character) -> Void
|
||||||
|
let finishField: () -> Void
|
||||||
|
|
||||||
|
init(delimiter: Character,
|
||||||
|
finishRow: @escaping () -> Void,
|
||||||
|
appendChar: @escaping (Character) -> Void,
|
||||||
|
finishField: @escaping () -> Void) {
|
||||||
|
|
||||||
|
self.delimiter = delimiter
|
||||||
|
self.finishRow = finishRow
|
||||||
|
self.appendChar = appendChar
|
||||||
|
self.finishField = finishField
|
||||||
|
}
|
||||||
|
|
||||||
|
mutating func change(_ char: Character) throws {
|
||||||
|
if atStart {
|
||||||
|
if char == "\"" {
|
||||||
|
atStart = false
|
||||||
|
parsingQuotes = true
|
||||||
|
} else if char == delimiter {
|
||||||
|
finishField()
|
||||||
|
} else if char.isNewline {
|
||||||
|
finishRow()
|
||||||
|
} else {
|
||||||
|
parsingField = true
|
||||||
|
atStart = false
|
||||||
|
appendChar(char)
|
||||||
|
}
|
||||||
|
} else if parsingField {
|
||||||
|
if innerQuotes {
|
||||||
|
if char == "\"" {
|
||||||
|
appendChar(char)
|
||||||
|
innerQuotes = false
|
||||||
|
} else {
|
||||||
|
throw CSVParseError.quotation(message: "Can't have non-quote here: \(char)")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if char == "\"" {
|
||||||
|
innerQuotes = true
|
||||||
|
} else if char == delimiter {
|
||||||
|
atStart = true
|
||||||
|
parsingField = false
|
||||||
|
innerQuotes = false
|
||||||
|
finishField()
|
||||||
|
} else if char.isNewline {
|
||||||
|
atStart = true
|
||||||
|
parsingField = false
|
||||||
|
innerQuotes = false
|
||||||
|
finishRow()
|
||||||
|
} else {
|
||||||
|
appendChar(char)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if parsingQuotes {
|
||||||
|
if innerQuotes {
|
||||||
|
if char == "\"" {
|
||||||
|
appendChar(char)
|
||||||
|
innerQuotes = false
|
||||||
|
} else if char == delimiter {
|
||||||
|
atStart = true
|
||||||
|
parsingField = false
|
||||||
|
innerQuotes = false
|
||||||
|
finishField()
|
||||||
|
} else if char.isNewline {
|
||||||
|
atStart = true
|
||||||
|
parsingQuotes = false
|
||||||
|
innerQuotes = false
|
||||||
|
finishRow()
|
||||||
|
} else {
|
||||||
|
throw CSVParseError.quotation(message: "Can't have non-quote here: \(char)")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if char == "\"" {
|
||||||
|
innerQuotes = true
|
||||||
|
} else {
|
||||||
|
appendChar(char)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw CSVParseError.generic(message: "me_irl")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// String+Lines.swift
|
||||||
|
// SwiftCSV
|
||||||
|
//
|
||||||
|
// Created by Naoto Kaneko on 2/24/16.
|
||||||
|
// Copyright © 2016 Naoto Kaneko. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
extension String {
|
||||||
|
internal var firstLine: String {
|
||||||
|
var current = startIndex
|
||||||
|
while current < endIndex && self[current].isNewline == false {
|
||||||
|
current = self.index(after: current)
|
||||||
|
}
|
||||||
|
return String(self[..<current])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Character {
|
||||||
|
internal var isNewline: Bool {
|
||||||
|
return self == "\n" || self == "\r\n" || self == "\r"
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
import SwiftCSV
|
|
||||||
|
|
||||||
final class IP2Country {
|
final class IP2Country {
|
||||||
var countryNamesCache: [String:String] = [:]
|
var countryNamesCache: [String:String] = [:]
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
github "TheLevelUp/ZXingObjC"
|
|
||||||
github "swiftcsv/SwiftCSV"
|
|
|
@ -1,2 +0,0 @@
|
||||||
github "TheLevelUp/ZXingObjC" "3.6.4"
|
|
||||||
github "swiftcsv/SwiftCSV" "0.5.6"
|
|
Loading…
Reference in New Issue