Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/ngageoint/mage-ios into …
Browse files Browse the repository at this point in the history
…develop
  • Loading branch information
bosborn committed Sep 8, 2023
2 parents 829ba56 + e90b454 commit f75ef58
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 74 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file.
Adheres to [Semantic Versioning](http://semver.org/).

---
## 4.0.6

##### Features
* Update GeoPackage library to 8.0.3

##### Bug Fixes
* PNG photo attachments converted to JPEG get a `.jpeg` file extension to match media type

## 4.0.5

##### Features
Expand Down
16 changes: 12 additions & 4 deletions MAGE.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
4C546FEC195A27F4000CF230 /* LocationAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C546FEB195A27F4000CF230 /* LocationAnnotation.m */; };
4CF141B21992A5D900C4B70E /* DeviceUUID.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CF141B11992A5D900C4B70E /* DeviceUUID.m */; };
7BE337090E1E1E71380E1A61 /* libPods-MAGETests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E35CAAC522CDD65F899A0C68 /* libPods-MAGETests.a */; };
7D0F874B2AA795CD009664E5 /* test_image_attachment.png in Resources */ = {isa = PBXBuildFile; fileRef = 7D0F874A2AA795CD009664E5 /* test_image_attachment.png */; };
8474FD9726FB8B220041891A /* EmailBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 8474FD9626FB8B220041891A /* EmailBuilder.m */; };
8474FD9A26FB8B890041891A /* LinkGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 8474FD9926FB8B890041891A /* LinkGenerator.m */; };
8474FD9D26FB8C410041891A /* ContactInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 8474FD9C26FB8C410041891A /* ContactInfo.m */; };
Expand Down Expand Up @@ -748,6 +749,7 @@
4CF141B01992A5D900C4B70E /* DeviceUUID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeviceUUID.h; sourceTree = "<group>"; };
4CF141B11992A5D900C4B70E /* DeviceUUID.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DeviceUUID.m; sourceTree = "<group>"; };
4FF82DA2D695899B2556C0D1 /* Pods-MAGE-MAGETests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MAGE-MAGETests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MAGE-MAGETests/Pods-MAGE-MAGETests.debug.xcconfig"; sourceTree = "<group>"; };
7D0F874A2AA795CD009664E5 /* test_image_attachment.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = test_image_attachment.png; sourceTree = "<group>"; };
8474FD9526FB8B220041891A /* EmailBuilder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EmailBuilder.h; sourceTree = "<group>"; };
8474FD9626FB8B220041891A /* EmailBuilder.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EmailBuilder.m; sourceTree = "<group>"; };
8474FD9826FB8B890041891A /* LinkGenerator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LinkGenerator.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2141,6 +2143,7 @@
F7614DA820068FF300676366 /* responses */ = {
isa = PBXGroup;
children = (
7D0F874A2AA795CD009664E5 /* test_image_attachment.png */,
F7CE22FF254368B000D710DE /* allTheThings.json */,
F70039452006CB0700E6E660 /* apiFail.json */,
F7614DA92006902000676366 /* apiSuccess.json */,
Expand Down Expand Up @@ -2996,6 +2999,7 @@
F7F7532B2565862F00EF51FF /* testmovie.MOV in Resources */,
F71446F524A3FAF5005A5EC1 /* feedContent.json in Resources */,
F7154A982608D2A0002C8617 /* apiSuccess6NoDisclaimer.json in Resources */,
7D0F874B2AA795CD009664E5 /* test_image_attachment.png in Resources */,
F70D19E32742CE0D006E12F8 /* plantsAnimalsBuildingsIcons.zip in Resources */,
F795ED1424BD061C0028FBFC /* observations.json in Resources */,
F7098F262492C36700313703 /* test_marker.png in Resources */,
Expand Down Expand Up @@ -3837,21 +3841,23 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = MAGE/MAGE.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_TEAM = ZL8G5D9G2H;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = ZL8G5D9G2H;
ENABLE_BITCODE = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Mage/MAGE-Prefix.pch";
INFOPLIST_FILE = "Mage/MAGE-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MARKETING_VERSION = 4.0.5;
MARKETING_VERSION = 4.0.6;
OTHER_LDFLAGS = "$(inherited)";
OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/AFNetworking/AFNetworking.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/DateTools/DateTools.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/HexColors/HexColors.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/MDFInternationalization/MDFInternationalization.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/MDFTextAccessibility/MDFTextAccessibility.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/MagicalRecord/MagicalRecord.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/MaterialComponents/MaterialComponents.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/MotionAnimator/MotionAnimator.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/MotionInterchange/MotionInterchange.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/PureLayout/PureLayout.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/SSZipArchive/SSZipArchive.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/UIImage_Categories/UIImage-Categories.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/geopackage_ios/geopackage-ios.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/libPhoneNumber_iOS/libPhoneNumber-iOS.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/ogc_api_features_json_ios/ogc-api-features-json-ios.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/sf_geojson_ios/sf-geojson-ios.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/sf_ios/sf-ios.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/sf_proj_ios/sf-proj-ios.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/sf_wkb_ios/sf-wkb-ios.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/sf_wkt_ios/sf-wkt-ios.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/tiff_ios/tiff-ios.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/zxcvbn_ios/zxcvbn-ios.modulemap\"";
PRODUCT_BUNDLE_IDENTIFIER = mil.nga.mage;
PRODUCT_NAME = MAGE;
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "MAGE Development";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "MAGE Development";
SWIFT_OBJC_BRIDGING_HEADER = "Mage/MAGE-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
Expand All @@ -3871,20 +3877,22 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = MAGE/MAGE.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_TEAM = ZL8G5D9G2H;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = ZL8G5D9G2H;
ENABLE_BITCODE = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Mage/MAGE-Prefix.pch";
INFOPLIST_FILE = "Mage/MAGE-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MARKETING_VERSION = 4.0.5;
MARKETING_VERSION = 4.0.6;
OTHER_LDFLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = mil.nga.mage;
PRODUCT_NAME = MAGE;
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "MAGE Development";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "MAGE Development";
SWIFT_OBJC_BRIDGING_HEADER = "Mage/MAGE-Bridging-Header.h";
SWIFT_VERSION = 5.0;
WRAPPER_EXTENSION = app;
Expand Down
86 changes: 42 additions & 44 deletions Mage/AttachmentCreationCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -193,50 +193,49 @@ extension AttachmentCreationCoordinator: AttachmentCreationDelegate {

extension AttachmentCreationCoordinator: PHPickerViewControllerDelegate {

func handlePhoto(phasset: PHAsset?, utType: UTType?) {
func handlePhoto(photo: PHAsset?, utType: UTType?) {
DispatchQueue.global(qos: .userInitiated).async { [self] in
if let phasset = phasset {
let dateFormatter = DateFormatter();
dateFormatter.dateFormat = "yyyyMMdd_HHmmss";

let fileType = utType?.preferredFilenameExtension ?? "jpeg"
let mimeType = utType?.preferredMIMEType ?? "image/jpeg"

guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
return;
guard let photo else {
galleryPermissionDenied()
return
}
let dateFormatter = DateFormatter();
dateFormatter.dateFormat = "yyyyMMdd_HHmmss";
guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
return
}
let attachmentsDirectory = documentsDirectory.appendingPathComponent("attachments")
let manager = PHImageManager.default()
let requestOptions = PHImageRequestOptions()
requestOptions.isSynchronous = true
requestOptions.deliveryMode = .fastFormat
requestOptions.isNetworkAccessAllowed = true

manager.requestImageDataAndOrientation(for: photo, options: requestOptions) { (data, fileName, orientation, info) in
guard let data else {
return
}
let attachmentsDirectory = documentsDirectory.appendingPathComponent("attachments")
let fileToWriteTo = attachmentsDirectory.appendingPathComponent("MAGE_\(dateFormatter.string(from: Date())).\(fileType)");

let manager = PHImageManager.default()
let requestOptions = PHImageRequestOptions()
requestOptions.isSynchronous = true
requestOptions.deliveryMode = .fastFormat
requestOptions.isNetworkAccessAllowed = true

manager.requestImageDataAndOrientation(for: phasset, options: requestOptions) { (data, fileName, orientation, info) in
if let data = data,
let cImage = CIImage(data: data) {
do {
try FileManager.default.createDirectory(at: fileToWriteTo.deletingLastPathComponent(), withIntermediateDirectories: true, attributes: [.protectionKey : FileProtectionType.complete]);

guard let finalData = cImage.qualityScaled() else { return }

do {
try finalData.write(to: fileToWriteTo, options: .completeFileProtection)
self.addAttachmentForSaving(location: fileToWriteTo, contentType: mimeType)
} catch {
print("Unable to write image to file \(fileToWriteTo): \(error)")
}

} catch {
print("Error creating directory path \(fileToWriteTo.deletingLastPathComponent()): \(error)")
}

}
let scaledImagePath = attachmentsDirectory.appendingPathComponent("MAGE_\(dateFormatter.string(from: Date())).jpeg")
do {
try FileManager.default.createDirectory(at: attachmentsDirectory, withIntermediateDirectories: true, attributes: [.protectionKey : FileProtectionType.complete])
}
catch {
print("error creating directory \(attachmentsDirectory) to save scaled attachment file \(fileName ?? "<unknown file>")", error)
return
}
guard let baseImage = CIImage(data: data) else {
return
}
guard let scaledImageData = baseImage.qualityScaled() else {
return
}
do {
try scaledImageData.write(to: scaledImagePath, options: .completeFileProtection)
self.addAttachmentForSaving(location: scaledImagePath, contentType: "image/jpeg")
}
catch {
print("error saving scaled attachment image \(scaledImagePath) from base image \(fileName ?? "<unknown file>")", error)
}
} else {
galleryPermissionDenied()
}
}
}
Expand Down Expand Up @@ -358,7 +357,7 @@ extension AttachmentCreationCoordinator: PHPickerViewControllerDelegate {
let options = PHFetchOptions()
options.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.image.rawValue)
let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [assetIdentifier], options: nil)
handlePhoto(phasset: fetchResult.firstObject, utType: utType)
handlePhoto(photo: fetchResult.firstObject, utType: utType)
picker.dismiss(animated: true, completion: nil)
return
}
Expand All @@ -372,7 +371,7 @@ extension AttachmentCreationCoordinator: PHPickerViewControllerDelegate {
return
}
}
MDCSnackbarManager.default.show(MDCSnackbarMessage(text: "Could not handle asset of types: \(itemProvider.registeredTypeIdentifiers)"))
MDCSnackbarManager.default.show(MDCSnackbarMessage(text: "Could not handle asset types: \(itemProvider.registeredTypeIdentifiers)"))
}
}
}
Expand Down Expand Up @@ -424,7 +423,6 @@ extension AttachmentCreationCoordinator: UIImagePickerControllerDelegate {

do {
try FileManager.default.createDirectory(at: fileToWriteTo.deletingLastPathComponent(), withIntermediateDirectories: true, attributes: [.protectionKey : FileProtectionType.complete]);
// let finalImage = chosenImage.qualityScaled();
guard let imageData = chosenImage.qualityScaled() else { return };
var metadata: [AnyHashable : Any] = info[.mediaMetadata] as? [AnyHashable : Any] ?? [:];

Expand Down
2 changes: 1 addition & 1 deletion Mage/Extensions/MageImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ extension CIImage {

func jpegData() -> Data? {
if let colorSpace = CGColorSpace(name: CGColorSpace.sRGB) {
let context = CIContext()
let context = CIContext()
return context.jpegRepresentation(of: self, colorSpace: colorSpace, options: [kCGImageDestinationLossyCompressionQuality as CIImageRepresentationOption : 1.0])
}
return nil
Expand Down
22 changes: 13 additions & 9 deletions Mage/SettingsDataSource.m
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,19 @@ - (instancetype) initWithScheme: (id<MDCContainerScheming>) containerScheme {
User *user = [User fetchCurrentUserWithContext:[NSManagedObjectContext MR_defaultContext]];
NSArray *recentEventIds = [user.recentEventIds filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF != %@", self.event.remoteId]];

NSFetchRequest *recentRequest = [Event MR_requestAllInContext:[NSManagedObjectContext MR_defaultContext]];
[recentRequest setPredicate:[NSPredicate predicateWithFormat:@"(remoteId IN %@)", recentEventIds]];
[recentRequest setIncludesSubentities:NO];
NSSortDescriptor* sortBy = [NSSortDescriptor sortDescriptorWithKey:@"recentSortOrder" ascending:YES];
[recentRequest setSortDescriptors:[NSArray arrayWithObject:sortBy]];

NSError *error = nil;
self.recentEvents = [[NSManagedObjectContext MR_defaultContext] executeFetchRequest:recentRequest error:&error];
if (error != nil) {
if (recentEventIds != nil) {
NSFetchRequest *recentRequest = [Event MR_requestAllInContext:[NSManagedObjectContext MR_defaultContext]];
[recentRequest setPredicate:[NSPredicate predicateWithFormat:@"(remoteId IN %@)", recentEventIds]];
[recentRequest setIncludesSubentities:NO];
NSSortDescriptor* sortBy = [NSSortDescriptor sortDescriptorWithKey:@"recentSortOrder" ascending:YES];
[recentRequest setSortDescriptors:[NSArray arrayWithObject:sortBy]];

NSError *error = nil;
self.recentEvents = [[NSManagedObjectContext MR_defaultContext] executeFetchRequest:recentRequest error:&error];
if (error != nil) {
self.recentEvents = [[NSArray alloc] init];
}
} else {
self.recentEvents = [[NSArray alloc] init];
}

Expand Down
Loading

0 comments on commit f75ef58

Please sign in to comment.