mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 13:37:11 +00:00
Move Map Libre API key to Xcode Cloud (#1313)
* Add config_production lane * Add maplibre to .gitignore * Add setupMapLibreKey * Add documentation * Fix failing UTs * Fix more UTs * Cleanup * Add secrets.xcconfig * Cleanup gitignore file * Update post-checkout hook * Cleanup SetupProject * Update project * Remove leftover in SetupProject * Cleanup project.yml * Add fastlane-plugin-xcconfig * Improve test * Update docs
This commit is contained in:
parent
027b6b21f7
commit
a7256bb486
@ -4,3 +4,6 @@ git lfs post-checkout "$@"
|
||||
|
||||
#!/bin/bash
|
||||
export PATH="$PATH:/opt/homebrew/bin"
|
||||
|
||||
# ignores updates of 'secrets.xcconfig' to avoid pushing sensitive data by mistake
|
||||
git update-index --assume-unchanged secrets.xcconfig
|
@ -967,6 +967,7 @@
|
||||
40B21E611DADDEF00307E7AC /* String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = "<group>"; };
|
||||
4132F882A984ED971338EE9D /* ReportContentScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportContentScreenUITests.swift; sourceTree = "<group>"; };
|
||||
4151163F666ED94FD959475A /* NotificationName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationName.swift; sourceTree = "<group>"; };
|
||||
41553551C55AD59885840F0E /* secrets.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = secrets.xcconfig; sourceTree = "<group>"; };
|
||||
4176C3E20C772DE8D182863C /* LegalInformationScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreen.swift; sourceTree = "<group>"; };
|
||||
421E716C521F96D24ECE69B3 /* NoticeRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||
421FA93BCC2840E66E4F306F /* NotificationSettingsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
@ -2004,6 +2005,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5D26A086A8278D39B5756D6F /* project.yml */,
|
||||
41553551C55AD59885840F0E /* secrets.xcconfig */,
|
||||
99B9B46F2D621380428E68F7 /* ElementX */,
|
||||
A4852B57D55D71EEBFCD931D /* UnitTests */,
|
||||
C0FAC17D4DD7D3A502822550 /* UITests */,
|
||||
@ -3590,6 +3592,14 @@
|
||||
path = Timeline;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
"TEMP_FFE5FDBA-B4DD-4FF7-B172-18026F248E20" /* element-x-ios */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
41553551C55AD59885840F0E /* secrets.xcconfig */,
|
||||
);
|
||||
path = "element-x-ios";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
@ -4822,6 +4832,7 @@
|
||||
};
|
||||
62E1B7866DF0ED442C39A83B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 41553551C55AD59885840F0E /* secrets.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = ElementX/SupportingFiles/ElementX.entitlements;
|
||||
@ -4845,6 +4856,7 @@
|
||||
};
|
||||
6897D5BC19A2EA6ABD57DE7E /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 41553551C55AD59885840F0E /* secrets.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = ElementX/SupportingFiles/ElementX.entitlements;
|
||||
|
@ -205,7 +205,7 @@ final class AppSettings {
|
||||
let darkTileMapStyleURL: URL = "https://api.maptiler.com/maps/dea61faf-292b-4774-9660-58fcef89a7f3"
|
||||
|
||||
// maptiler api key
|
||||
let mapTilerApiKey = "fU3vlMsMn4Jb6dnEIFsx"
|
||||
let mapTilerApiKey = InfoPlistReader.main.mapLibreAPIKey
|
||||
|
||||
// maptiler geocoding url
|
||||
let geocodingURLFormatString = "https://api.maptiler.com/geocoding/%f,%f.json"
|
||||
|
@ -23,6 +23,7 @@ struct InfoPlistReader {
|
||||
static let keychainAccessGroupIdentifier = "keychainAccessGroupIdentifier"
|
||||
static let bundleShortVersion = "CFBundleShortVersionString"
|
||||
static let bundleDisplayName = "CFBundleDisplayName"
|
||||
static let mapLibreAPIKey = "mapLibreAPIKey"
|
||||
}
|
||||
|
||||
/// Info.plist reader on the bundle object that contains the current executable.
|
||||
@ -76,6 +77,11 @@ struct InfoPlistReader {
|
||||
infoPlistStringValue(forKey: Keys.bundleDisplayName)
|
||||
}
|
||||
|
||||
/// Map Libre API Key
|
||||
var mapLibreAPIKey: String {
|
||||
infoPlistStringValue(forKey: Keys.mapLibreAPIKey)
|
||||
}
|
||||
|
||||
private func infoPlistStringValue(forKey key: String) -> String {
|
||||
guard let result = bundle.object(forInfoDictionaryKey: key) as? String else {
|
||||
fatalError("Add \(key) into your target's Info.plst")
|
||||
|
@ -60,5 +60,7 @@
|
||||
<string>$(BASE_BUNDLE_IDENTIFIER)</string>
|
||||
<key>keychainAccessGroupIdentifier</key>
|
||||
<string>$(KEYCHAIN_ACCESS_GROUP_IDENTIFIER)</string>
|
||||
<key>mapLibreAPIKey</key>
|
||||
<string>$(MAPLIBRE_API_KEY)</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -45,6 +45,10 @@ targets:
|
||||
type: application
|
||||
platform: iOS
|
||||
|
||||
configFiles:
|
||||
Debug: ../../secrets.xcconfig
|
||||
Release: ../../secrets.xcconfig
|
||||
|
||||
info:
|
||||
path: ../SupportingFiles/Info.plist
|
||||
properties:
|
||||
@ -76,6 +80,7 @@ targets:
|
||||
BGTaskSchedulerPermittedIdentifiers: [
|
||||
io.element.elementx.background.refresh
|
||||
]
|
||||
mapLibreAPIKey: $(MAPLIBRE_API_KEY)
|
||||
|
||||
|
||||
settings:
|
||||
|
@ -123,6 +123,7 @@ GEM
|
||||
rest-client (~> 2.0, >= 2.0.2)
|
||||
fastlane-plugin-sentry (1.15.0)
|
||||
os (~> 1.1, >= 1.1.4)
|
||||
fastlane-plugin-xcconfig (2.0.0)
|
||||
fastlane-plugin-xcodegen (1.1.0)
|
||||
fastlane-plugin-brew (~> 0.1.1)
|
||||
gh_inspector (1.1.3)
|
||||
@ -263,9 +264,10 @@ DEPENDENCIES
|
||||
fastlane-plugin-browserstack
|
||||
fastlane-plugin-diawi!
|
||||
fastlane-plugin-sentry
|
||||
fastlane-plugin-xcconfig
|
||||
fastlane-plugin-xcodegen
|
||||
slather
|
||||
xcode-install
|
||||
|
||||
BUNDLED WITH
|
||||
2.3.26
|
||||
2.4.16
|
||||
|
@ -41,6 +41,10 @@ When you are experiencing an issue on ElementX iOS, please first search in [GitH
|
||||
and then in [#element-x-ios:matrix.org](https://matrix.to/#/#element-x-ios:matrix.org).
|
||||
If after your research you still have a question, ask at [#element-x-ios:matrix.org](https://matrix.to/#/#element-x-ios:matrix.org). Otherwise feel free to create a GitHub issue if you encounter a bug or a crash, by explaining clearly in detail what happened. You can also perform bug reporting (Rageshake) from the Element application by shaking your phone or going to the application settings. This is especially recommended when you encounter a crash.
|
||||
|
||||
## Forking
|
||||
|
||||
Please read our [forking guide](docs/FORKING.md).
|
||||
|
||||
## Copyright & License
|
||||
|
||||
Copyright (c) 2022 New Vector Ltd
|
||||
|
@ -88,10 +88,9 @@ class HomeScreenViewModelTests: XCTestCase {
|
||||
let room: RoomProxyMock = .init(with: .init(id: mockRoomId, displayName: "Some room"))
|
||||
room.leaveRoomClosure = { .failure(.failedLeavingRoom) }
|
||||
clientProxy.roomForIdentifierMocks[mockRoomId] = room
|
||||
let deferred = deferFulfillment(context.$viewState.first(), message: "viewState should be published.")
|
||||
context.send(viewAction: .confirmLeaveRoom(roomIdentifier: mockRoomId))
|
||||
try await deferred.fulfill()
|
||||
XCTAssertNotNil(context.alertInfo)
|
||||
let state = await context.nextViewState()
|
||||
XCTAssertNotNil(state?.bindings.alertInfo)
|
||||
}
|
||||
|
||||
func testLeaveRoomSuccess() async throws {
|
||||
|
@ -179,27 +179,59 @@ final class NotificationManagerTests: XCTestCase {
|
||||
}
|
||||
|
||||
func test_MessageNotificationsRemoval() async throws {
|
||||
let notificationPublisher = NotificationCenter.default.publisher(for: .roomMarkedAsRead).first()
|
||||
var cancellables: Set<AnyCancellable> = .init()
|
||||
let expectation1 = expectation(description: #function)
|
||||
notificationPublisher
|
||||
.sink { _ in
|
||||
expectation1.fulfill()
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
// No interaction if the object is nil or of the wrong type
|
||||
NotificationCenter.default.post(name: .roomMarkedAsRead, object: nil)
|
||||
try await Task.sleep(for: .microseconds(200))
|
||||
await fulfillment(of: [expectation1])
|
||||
XCTAssertEqual(notificationCenter.deliveredNotificationsCallsCount, 0)
|
||||
XCTAssertEqual(notificationCenter.removeDeliveredNotificationsCallsCount, 0)
|
||||
|
||||
|
||||
let expectation2 = expectation(description: #function)
|
||||
notificationPublisher
|
||||
.sink { _ in
|
||||
expectation2.fulfill()
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
NotificationCenter.default.post(name: .roomMarkedAsRead, object: 1)
|
||||
try await Task.sleep(for: .microseconds(200))
|
||||
await fulfillment(of: [expectation2])
|
||||
XCTAssertEqual(notificationCenter.deliveredNotificationsCallsCount, 0)
|
||||
XCTAssertEqual(notificationCenter.removeDeliveredNotificationsCallsCount, 0)
|
||||
|
||||
|
||||
let expectation3 = expectation(description: #function)
|
||||
notificationPublisher
|
||||
.sink { _ in
|
||||
expectation3.fulfill()
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
// The center calls the delivered and the removal functions when an id is passed
|
||||
NotificationCenter.default.post(name: .roomMarkedAsRead, object: "RoomID")
|
||||
try await Task.sleep(for: .microseconds(200))
|
||||
await fulfillment(of: [expectation3])
|
||||
XCTAssertEqual(notificationCenter.deliveredNotificationsCallsCount, 1)
|
||||
XCTAssertEqual(notificationCenter.removeDeliveredNotificationsCallsCount, 1)
|
||||
}
|
||||
|
||||
func test_InvitesNotificationsRemoval() async throws {
|
||||
let notificationPublisher = NotificationCenter.default.publisher(for: .invitesScreenAppeared).first()
|
||||
let expectation = expectation(description: #function)
|
||||
var cancellables: Set<AnyCancellable> = .init()
|
||||
notificationPublisher
|
||||
.sink { _ in
|
||||
expectation.fulfill()
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
NotificationCenter.default.post(name: .invitesScreenAppeared, object: nil)
|
||||
try await Task.sleep(for: .microseconds(200))
|
||||
await fulfillment(of: [expectation])
|
||||
XCTAssertEqual(notificationCenter.deliveredNotificationsCallsCount, 1)
|
||||
XCTAssertEqual(notificationCenter.removeDeliveredNotificationsCallsCount, 1)
|
||||
}
|
||||
|
@ -8,4 +8,6 @@ install_xcode_cloud_brew_dependencies
|
||||
|
||||
if [ "$CI_WORKFLOW" = "Nightly" ]; then
|
||||
bundle exec fastlane config_nightly
|
||||
fi
|
||||
else
|
||||
bundle exec fastlane config_production
|
||||
fi
|
||||
|
32
docs/FORKING.md
Normal file
32
docs/FORKING.md
Normal file
@ -0,0 +1,32 @@
|
||||
# Forking
|
||||
|
||||
### Update the bundle identifier / app display name
|
||||
|
||||
To change the bundle identifier and the app display name for your app, open the `project.yml` file in the project root folder and change these settings:
|
||||
|
||||
```
|
||||
BASE_BUNDLE_IDENTIFIER: io.element.elementx
|
||||
APP_DISPLAY_NAME: Element X
|
||||
```
|
||||
|
||||
After the changes run `xcodegen` to propagate them.
|
||||
|
||||
### Setup the location sharing
|
||||
|
||||
The location sharing feature on Element X is currently integrated with [MapLibre](https://maplibre.org).
|
||||
|
||||
The MapLibre SDK requires an API key to work, so you need to get one for yourself.
|
||||
|
||||
After you get an API key, you need to configure the project by adding it inside the file `secrets.xconfig` in the project root folder. After you are done, the file should contain a setting like this:
|
||||
|
||||
```
|
||||
MAPLIBRE_API_KEY = your_map_libre_key
|
||||
```
|
||||
|
||||
It’s not recommended to push your API key in your repository since other people may get it.
|
||||
|
||||
One way to avoid pushing the API key by mistake is running on your machine the command:
|
||||
```
|
||||
git update-index assume-unchanged secrets.xcconfig
|
||||
```
|
||||
this will prevent pushing any update of the file`secrets.xcconfig`.
|
@ -180,6 +180,9 @@ lane :config_nightly do
|
||||
data = YAML.load_file target_file_path
|
||||
data["settings"]["BASE_APP_GROUP_IDENTIFIER"] = "io.element.nightly"
|
||||
data["settings"]["BASE_BUNDLE_IDENTIFIER"] = "io.element.elementx.nightly"
|
||||
|
||||
config_maplibre()
|
||||
|
||||
File.open(target_file_path, 'w') { |f| YAML.dump(data, f) }
|
||||
|
||||
xcodegen(spec: "project.yml")
|
||||
@ -193,6 +196,11 @@ lane :config_nightly do
|
||||
update_app_icon(caption_text: "Nightly #{release_version}", modulate: "100,20,100")
|
||||
end
|
||||
|
||||
lane :config_production do
|
||||
config_maplibre()
|
||||
xcodegen(spec: "project.yml")
|
||||
end
|
||||
|
||||
lane :upload_dsyms_to_sentry do |options|
|
||||
auth_token = ENV["SENTRY_AUTH_TOKEN"]
|
||||
UI.user_error!("Invalid Sentry Auth token.") unless !auth_token.to_s.empty?
|
||||
@ -409,5 +417,15 @@ private_lane :create_simulator_if_necessary do |options|
|
||||
rescue
|
||||
sh("xcrun simctl create '#{simulator_name}' #{simulator_type}")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
private_lane :config_maplibre do
|
||||
api_key = ENV["MAPLIBRE_API_KEY"]
|
||||
UI.user_error!("Invalid Map Libre API key.") unless !api_key.to_s.empty?
|
||||
|
||||
set_xcconfig_value(
|
||||
path: './secrets.xcconfig',
|
||||
name: 'MAPLIBRE_API_KEY',
|
||||
value: api_key
|
||||
)
|
||||
end
|
||||
|
@ -6,3 +6,4 @@ gem 'fastlane-plugin-diawi', git: 'https://github.com/mhtranbn/fastlane-plugin-d
|
||||
gem 'fastlane-plugin-xcodegen'
|
||||
gem 'fastlane-plugin-sentry'
|
||||
gem 'fastlane-plugin-browserstack'
|
||||
gem 'fastlane-plugin-xcconfig'
|
||||
|
@ -69,6 +69,14 @@ For _fastlane_ installation instructions, see [Installing _fastlane_](https://do
|
||||
|
||||
|
||||
|
||||
### config_production
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane config_production
|
||||
```
|
||||
|
||||
|
||||
|
||||
### upload_dsyms_to_sentry
|
||||
|
||||
```sh
|
||||
|
@ -4,6 +4,7 @@ attributes:
|
||||
|
||||
fileGroups:
|
||||
- project.yml
|
||||
- secrets.xcconfig
|
||||
|
||||
options:
|
||||
groupSortPosition: bottom
|
||||
|
20
secrets.xcconfig
Normal file
20
secrets.xcconfig
Normal file
@ -0,0 +1,20 @@
|
||||
//
|
||||
// Copyright 2023 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
// Configuration settings file format documentation can be found at:
|
||||
// https://help.apple.com/xcode/#/dev745c5c974
|
||||
|
||||
MAPLIBRE_API_KEY = your_key
|
Loading…
x
Reference in New Issue
Block a user