diff --git a/platform/CMakeLists.txt b/platform/CMakeLists.txt index f030c5f6d4..cfaf56bdf6 100644 --- a/platform/CMakeLists.txt +++ b/platform/CMakeLists.txt @@ -108,7 +108,6 @@ else() # neither iPhone nor Android http_thread_apple.h http_thread_apple.mm http_uploader_apple.mm - http_uploader_apple.swift marketing_service_dummy.cpp platform_mac.mm platform_unix_impl.cpp @@ -137,13 +136,8 @@ add_subdirectory(platform_tests_support) add_library(${PROJECT_NAME} ${SRC}) -# 2 next lines are added for future support of swift code compilation. -set(SWIFT_BRIDGING_HEADER platform-Swift.h) -set_property(TARGET ${PROJECT_NAME} PROPERTY XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "${SWIFT_BRIDGING_HEADER}") - if (APPLE) -# "-DIGNORE_SWIFT=1" key is added as the temporary solution until support of swift code compilation. - target_compile_options(${PROJECT_NAME} PUBLIC "-fobjc-arc" "-DIGNORE_SWIFT=1") + target_compile_options(${PROJECT_NAME} PUBLIC "-fobjc-arc") endif() omim_add_test_subdirectory(platform_tests) diff --git a/platform/http_uploader_apple.mm b/platform/http_uploader_apple.mm index 18f2584ae3..714d84795b 100644 --- a/platform/http_uploader_apple.mm +++ b/platform/http_uploader_apple.mm @@ -1,7 +1,4 @@ #import -#ifndef IGNORE_SWIFT // Temporary solution for CMAKE builds. TODO: Remove when support of swift code compilation is added. -#import "platform-Swift.h" -#endif #include "platform/http_uploader.hpp" @@ -10,37 +7,111 @@ #include +@interface MultipartUploadTask : NSObject + +@property (copy, nonatomic) NSString *method; +@property (copy, nonatomic) NSString *urlString; +@property (copy, nonatomic) NSString *fileKey; +@property (copy, nonatomic) NSString *filePath; +@property (strong, nonatomic) NSDictionary *params; +@property (strong, nonatomic) NSDictionary *headers; + +@end + +@implementation MultipartUploadTask + +- (NSData *)requestDataWithBoundary:(NSString *)boundary { + NSMutableData *data = [NSMutableData data]; + + [self.params enumerateKeysAndObjectsUsingBlock:^(NSString * key, NSString * value, BOOL * stop) { + [data appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] + dataUsingEncoding:NSUTF8StringEncoding]]; + [data appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", + key] dataUsingEncoding:NSUTF8StringEncoding]]; + [data appendData:[[NSString stringWithFormat:@"%@\r\n", value] + dataUsingEncoding:NSUTF8StringEncoding]]; + }]; + + NSString *fileName = self.filePath.lastPathComponent; + NSData *fileData = [NSData dataWithContentsOfFile:self.filePath]; + NSString *mimeType = @"application/octet-stream"; + + [data appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] + dataUsingEncoding:NSUTF8StringEncoding]]; + [data appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", + self.fileKey, + fileName] + dataUsingEncoding:NSUTF8StringEncoding]]; + [data appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", mimeType] + dataUsingEncoding:NSUTF8StringEncoding]]; + [data appendData:fileData]; + [data appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; + [data appendData:[[NSString stringWithFormat:@"--%@--", boundary] + dataUsingEncoding:NSUTF8StringEncoding]]; + + return data; +} + +- (void)uploadWithCompletion:(void (^)(NSInteger httpCode, NSString *description))completion { + NSURL *url = [NSURL URLWithString:self.urlString]; + NSMutableURLRequest *uploadRequest = [NSMutableURLRequest requestWithURL:url]; + uploadRequest.timeoutInterval = 5; + uploadRequest.HTTPMethod = self.method; + + NSString *boundary = [NSString stringWithFormat:@"Boundary-%@", [[NSUUID UUID] UUIDString]]; + NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary]; + [uploadRequest setValue:contentType forHTTPHeaderField:@"Content-Type"]; + + NSData *postData = [self requestDataWithBoundary:boundary]; + + NSURLSessionUploadTask *uploadTask = [[NSURLSession sharedSession] + uploadTaskWithRequest:uploadRequest + fromData:postData + completionHandler:^(NSData *data, + NSURLResponse *response, + NSError *error) { + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; + if (error == nil) { + NSString *description = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + completion(httpResponse.statusCode, description); + } else { + completion(-1, error.localizedDescription); + } + }]; + [uploadTask resume]; +} + +@end + namespace platform { HttpUploader::Result HttpUploader::Upload() const { -#ifndef IGNORE_SWIFT // Temporary solution for CMAKE builds. TODO: Remove when support of swift code compilation is added. std::shared_ptr resultPtr = std::make_shared(); std::shared_ptr waiterPtr = std::make_shared(); auto mapTransform = ^NSDictionary *(std::map keyValues) { - NSMutableDictionary * params = [@{} mutableCopy]; + NSMutableDictionary * params = [NSMutableDictionary dictionary]; for (auto const & keyValue : keyValues) params[@(keyValue.first.c_str())] = @(keyValue.second.c_str()); return [params copy]; }; - [MultipartUploader uploadWithMethod:@(m_method.c_str()) - url:@(m_url.c_str()) - fileKey:@(m_fileKey.c_str()) - filePath:@(m_filePath.c_str()) - params:mapTransform(m_params) - headers:mapTransform(m_headers) - callback:[resultPtr, waiterPtr](NSInteger httpCode, NSString * _Nonnull description) { - resultPtr->m_httpCode = static_cast(httpCode); - resultPtr->m_description = description.UTF8String; - waiterPtr->Notify(); - }]; + auto *uploadTask = [[MultipartUploadTask alloc] init]; + uploadTask.method = @(m_method.c_str()); + uploadTask.urlString = @(m_url.c_str()); + uploadTask.fileKey = @(m_fileKey.c_str()); + uploadTask.filePath = @(m_filePath.c_str()); + uploadTask.params = mapTransform(m_params); + uploadTask.headers = mapTransform(m_headers); + [uploadTask uploadWithCompletion:[resultPtr, waiterPtr](NSInteger httpCode, NSString *description) { + resultPtr->m_httpCode = static_cast(httpCode); + resultPtr->m_description = description.UTF8String; + waiterPtr->Notify(); + }]; waiterPtr->Wait(); return *resultPtr; -#endif - return {}; } } // namespace platform diff --git a/platform/http_uploader_apple.swift b/platform/http_uploader_apple.swift deleted file mode 100644 index 5b0cbc7395..0000000000 --- a/platform/http_uploader_apple.swift +++ /dev/null @@ -1,32 +0,0 @@ -import Foundation -import Alamofire - -final class MultipartUploader: NSObject { - static var manager: Alamofire.SessionManager = { - let configuration = URLSessionConfiguration.default - configuration.timeoutIntervalForRequest = 5 - return Alamofire.SessionManager(configuration: configuration) - }() - - @objc - static func upload(method: String, url: String, fileKey: String, filePath: String, params: [String: String], headers: [String: String], callback: @escaping (Int, String) -> Void) { - - let multipartFormData: (Alamofire.MultipartFormData) -> Void = { mfd in - for (key, value) in params { - mfd.append(value.data(using: .utf8, allowLossyConversion: false)!, withName: key) - } - mfd.append(URL(fileURLWithPath: filePath), withName: fileKey) - } - - let method = HTTPMethod(rawValue: method) ?? .post - - manager.upload(multipartFormData: multipartFormData, to: url, method: method, headers: headers) { encodingResult in - switch encodingResult { - case let .success(upload, _, _): - upload.responseJSON { callback($0.response?.statusCode ?? -1, $0.error?.localizedDescription ?? "") } - case let .failure(encodingError): - callback(-1, encodingError.localizedDescription) - } - } - } -} diff --git a/xcode/common.xcconfig b/xcode/common.xcconfig index 9af665a948..26df6ce864 100644 --- a/xcode/common.xcconfig +++ b/xcode/common.xcconfig @@ -32,7 +32,6 @@ CLANG_WARN_ENUM_CONVERSION = YES CLANG_WARN_INFINITE_RECURSION = YES CLANG_WARN_INT_CONVERSION = YES CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES -CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION = YES CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES diff --git a/xcode/map/map.xcodeproj/project.pbxproj b/xcode/map/map.xcodeproj/project.pbxproj index 22f72b7191..b98c61aa87 100644 --- a/xcode/map/map.xcodeproj/project.pbxproj +++ b/xcode/map/map.xcodeproj/project.pbxproj @@ -52,6 +52,8 @@ 45F6EE9D1FB1C77600019892 /* search_api.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 45F6EE9A1FB1C77500019892 /* search_api.hpp */; }; 45F6EE9E1FB1C77600019892 /* mwm_tree.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 45F6EE9B1FB1C77500019892 /* mwm_tree.hpp */; }; 45F6EE9F1FB1C77600019892 /* search_api.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45F6EE9C1FB1C77500019892 /* search_api.cpp */; }; + 47A9D82220A19E9E00E4671B /* libopen_location_code.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 47A9D82120A19E9E00E4671B /* libopen_location_code.a */; }; + 47A9D82420A19EC300E4671B /* libkml.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 47A9D82320A19EC300E4671B /* libkml.a */; }; 56EE14D31FE80E900036F20C /* libtransit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 56EE14D41FE80E900036F20C /* libtransit.a */; }; 56EE14D51FE80EBD0036F20C /* libmwm_diff.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 56EE14D61FE80EBD0036F20C /* libmwm_diff.a */; }; 56EE14D71FE80F290036F20C /* libbsdiff.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 56EE14D81FE80F290036F20C /* libbsdiff.a */; }; @@ -217,6 +219,8 @@ 45F6EE9A1FB1C77500019892 /* search_api.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = search_api.hpp; sourceTree = ""; }; 45F6EE9B1FB1C77500019892 /* mwm_tree.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = mwm_tree.hpp; sourceTree = ""; }; 45F6EE9C1FB1C77500019892 /* search_api.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = search_api.cpp; sourceTree = ""; }; + 47A9D82120A19E9E00E4671B /* libopen_location_code.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libopen_location_code.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 47A9D82320A19EC300E4671B /* libkml.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libkml.a; sourceTree = BUILT_PRODUCTS_DIR; }; 56EE14D41FE80E900036F20C /* libtransit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libtransit.a; sourceTree = BUILT_PRODUCTS_DIR; }; 56EE14D61FE80EBD0036F20C /* libmwm_diff.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libmwm_diff.a; sourceTree = BUILT_PRODUCTS_DIR; }; 56EE14D81FE80F290036F20C /* libbsdiff.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libbsdiff.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -342,6 +346,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 47A9D82420A19EC300E4671B /* libkml.a in Frameworks */, + 47A9D82220A19E9E00E4671B /* libopen_location_code.a in Frameworks */, 56EE14D71FE80F290036F20C /* libbsdiff.a in Frameworks */, 56EE14D51FE80EBD0036F20C /* libmwm_diff.a in Frameworks */, 56EE14D31FE80E900036F20C /* libtransit.a in Frameworks */, @@ -402,6 +408,8 @@ 34DDA17E1DBE5DF40088A609 /* Frameworks */ = { isa = PBXGroup; children = ( + 47A9D82320A19EC300E4671B /* libkml.a */, + 47A9D82120A19E9E00E4671B /* libopen_location_code.a */, 56EE14D81FE80F290036F20C /* libbsdiff.a */, 56EE14D61FE80EBD0036F20C /* libmwm_diff.a */, 56EE14D41FE80E900036F20C /* libtransit.a */, diff --git a/xcode/platform/platform-Bridging-Header.h b/xcode/platform/platform-Bridging-Header.h deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/xcode/platform/platform.xcodeproj/project.pbxproj b/xcode/platform/platform.xcodeproj/project.pbxproj index 8c1fd19912..530e72cc9f 100644 --- a/xcode/platform/platform.xcodeproj/project.pbxproj +++ b/xcode/platform/platform.xcodeproj/project.pbxproj @@ -7,7 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 341EEFD02022FCB000D5DBE4 /* http_uploader_apple.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341EEFCF2022FCB000D5DBE4 /* http_uploader_apple.swift */; }; 34513AFA1DCB37C100471BDA /* marketing_service_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34513AF71DCB37C100471BDA /* marketing_service_ios.mm */; }; 34513AFB1DCB37C100471BDA /* marketing_service.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 34513AF81DCB37C100471BDA /* marketing_service.cpp */; }; 34513AFC1DCB37C100471BDA /* marketing_service.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 34513AF91DCB37C100471BDA /* marketing_service.hpp */; }; @@ -117,8 +116,6 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - 341EEFCE2022FCB000D5DBE4 /* platform-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "platform-Bridging-Header.h"; sourceTree = ""; }; - 341EEFCF2022FCB000D5DBE4 /* http_uploader_apple.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = http_uploader_apple.swift; sourceTree = ""; }; 344D8A2E204945D000CF532F /* platform_ios.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = platform_ios.h; sourceTree = ""; }; 34513AF71DCB37C100471BDA /* marketing_service_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = marketing_service_ios.mm; sourceTree = ""; }; 34513AF81DCB37C100471BDA /* marketing_service.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = marketing_service.cpp; sourceTree = ""; }; @@ -336,7 +333,6 @@ 675343791A3F5CF500A0A8C3 /* Products */, 3496AB6F1DC1F5AB00C5DDBA /* Frameworks */, A8E540F51F9F97CD00A1B8FA /* Recovered References */, - 341EEFCE2022FCB000D5DBE4 /* platform-Bridging-Header.h */, ); sourceTree = ""; }; @@ -376,7 +372,6 @@ 6753438E1A3F5D5900A0A8C3 /* http_thread_apple.mm */, 6753438F1A3F5D5A00A0A8C3 /* http_thread_callback.hpp */, 3D318A042021DD8A007B2607 /* http_uploader_apple.mm */, - 341EEFCF2022FCB000D5DBE4 /* http_uploader_apple.swift */, 3D318A052021DD8B007B2607 /* http_uploader.hpp */, 674125041B4C00CC00A3E828 /* local_country_file_utils.cpp */, 674125051B4C00CC00A3E828 /* local_country_file_utils.hpp */, @@ -662,7 +657,6 @@ 451E32A01F73A8B000964C9F /* secure_storage_ios.mm in Sources */, 675343DB1A3F5D5A00A0A8C3 /* wifi_location_service.cpp in Sources */, 56EB1EDC1C6B6E6C0022D831 /* file_logging.cpp in Sources */, - 341EEFD02022FCB000D5DBE4 /* http_uploader_apple.swift in Sources */, 675343B11A3F5D5A00A0A8C3 /* apple_location_service.mm in Sources */, 675343B31A3F5D5A00A0A8C3 /* chunks_download_strategy.cpp in Sources */, 34513AFA1DCB37C100471BDA /* marketing_service_ios.mm in Sources */,