TECH PLAY

KINTOテクノロジーズ

KINTOテクノロジーズ の技術ブログ

936

Introduction Hello! My name is Ren.M from the Project Promotion Group at KINTO Technologies. My main role is to develop the front-end of KINTO ONE (Used Car) . In this article, rather than talking about technical stuff, I would like to tell you about our company’s in-house activities! Target audience of this article People who are interested in in-house club activities People who feel there is not enough communication between employees What are our in-house club activities? Our company fosters a culture of club activities, with a variety of in-house clubs, including a futsal club, a golf club, and more! Each club has its own dedicated channel on Slack, making it easy for anyone to join or participate at their discretion. In fact, some members enjoy being part of multiple clubs! I’m a member of the basketball club, which rents a gymnasium near the office for practice sessions lasting about three hours each evening. While gymnasium availability is determined by a lottery system, we consistently play every month without fail. To ensure smooth operations, we have volunteers who take on various responsibilities, including: Booking the gymnasium each month Handling payment for its usage Managing club expenses These tasks are shared among members on a volunteer basis. Once our reservation is confirmed, we announce it on Slack and invite participants! It depends on the day, but we usually have around ten participants joining us! Activity Scene What I have gained through club activities A refreshing break Our company is home to many engineers, and pretty much all of them do desk jobs. Also, because I sometimes work from home, no matter how hard I try, I am prone to not getting enough exercise. Participating in club activities provides me with a vital opportunity to exercise, refreshing both my mind and body. I find myself getting really passionate during practice, but I always make a conscious effort to avoid injury while having fun! More interaction with employees from other departments I believe this is one of the greatest strengths of our club activities. With employees from various departments participating, it provides a unique opportunity to connect with colleagues you don’t typically work with. In meetings, having prior relationships formed through club activities can facilitate smoother collaboration, as participants are not just strangers meeting for the first time. Additionally, I hope these activities help new employees feel more at home within our company Conclusion I hope this gives you a glimpse into what our club activities look like. I think in-house club activities are a positive culture that allows employees to refresh themselves while deepening their friendships! If you join our company, I encourage you to engage with colleagues through these activities! There are also many other articles about them on the Tech Blog, so please take a look if you're interested!
アバター
Self-introduction Hello. I am Sora Watanabe, a member of the SRE Team in the Platform Group at KINTO Technologies Corporation (from now on, KINTO Technologies). We contribute to improving the reliability of our company’s services by leveraging our experience in application development, infrastructure setup, and CI/CD for web services. Introduction No matter how great a service is, realistically, there is no way that problems will never occur. In today’s service delivery landscape, it’s essential to proactively set targets for an acceptable number of issues, and, in some cases, share these expectations with users to build consensus. Specifically, you define the levels of service using Service Level Indicators (SLIs), then set target values for them using Service Level Objectives (SLOs). Then, you obtain the users’ agreement to these target values through Service Level Agreements or SLAs. Having set your SLOs, the next step is to monitor for target violations. An alert needs to be triggered if a violation occurs. However, the rules for triggering alerts are prone to getting complex and difficult to manage. In order to solve this problem, in this article, I will introduce a way to streamline creating and managing alert rules by using an alert rule generator called Sloth. Background As I discussed in a previous article, at KINTO Technologies, we are using the stack “Prometheus + Grafana + X-Ray” to obtain telemetry data and improve the observability of our request-response-type web services. https://blog.kinto-technologies.com/posts/2022-12-09-AWS_Prometehus_Grafana_o11y/ Thanks to this, we are now successfully storing a wide variety of metrics in Prometheus, and for Spring Boot application metrics in particular, doing so without having to add any special instrumentation into the application code. The metrics stored include the success/failure status and response rate data on a per-request basis. This has enabled us to express SLIs for availability and latency using PromQL. Issues Typically, after establishing SLIs and SLOs for the web service’s Critical User Journey (CUJ), you then monitor the error budget usage for the deployed service. When doing so, you need to detect potential SLO/SLA violations at an appropriate time. To do that, you need to set up alerts to enable the developers to detect anomalies. According to The Site Reliability Workbook, multi-window, multi-burn-rate alerts are the most effective and recommended approach for detecting SLO violations. A key benefit is that they offer excellent control over precision, reproducibility, detection time, and reset time, making us eager to implement them actively. I will briefly explain about what “window” and “burn rate” mean: Window This means the measurement periods. These are the timeframes defined for when measurement begins and ends. Since SLOs are expressed as percentages, the service level resets to 100% at the start of each new measurement period when the previous one concludes. In general, the larger the window size, the harder it is to trigger and end alerts. Burn rate This refers to the rate at which the error budget is used up. Triggering an alert only after the error budget is fully consumed would be too late; ideally, an alert should be triggered once a certain portion of it has been used. The burn rate is calculated by defining a reference value of 1, which represents the rate at which the error budget would reach exactly 0 by the end of the measurement window if consumed at a steady pace. Then, the actual consumption rate is measured against this reference to see how many times faster the error budget is being depleted. This multiple is recorded as the burn rate. You configure the system to trigger an alert when the burn rate surpasses a predetermined threshold. For more information on multiwindow, multi-burn-rate alerts, see Chapter 5, “Alerting on SLOs” in The Site Reliability Workbook. https://www.oreilly.co.jp/books/9784873119137/ The English version has been published on the web: https://sre.google/workbook/alerting-on-slos/#6-multiwindow-multi-burn-rate-alerts To use the multiwindow, multi-burn-rate alerts approach, you need to set up an alert rule that specifies multiple windows and burn rates—i.e., multiple different parameters—for a single SLI/SLO definition. As a result, a challenge has been that the number of alert rules grows to the point where they become difficult to manage. What we will do In this article, we will use an open source tool called Sloth to solve this issue. https://sloth.dev/ By using Sloth, you can define SLI/SLO specifications with simple descriptions, which then generate Prometheus recording rules and alert rule definition files—tasks that would otherwise be complex and prone to errors. At KINTO Technologies, we adopt a configuration like the one in the figure below. Sloth is able to generate multiwindow, multi-burn rate alert rules by default. Therefore, in this article, I will show you how to set up multiwindow, multi-burn rate alert rules using Sloth. Generating alert rules :::message Sloth allows you to input SLI/SLO specification files that adhere to OpenSLO standard However, these currently do not appear to support generating Prometheus alert rules, so we have opted to use Sloth’s own SLI/SLO specification format instead. ::: The following simple SLI/SLO specification is expressed in a YAML file based on the Sloth standards. Category SLI SLO Availability The percentage of successful requests measured by the application over a 30-day period. Consider any HTTP status outside the ranges 500–599 and 429 as successful. Consolidate and measure all request paths except actuator. 99.5% version: "prometheus/v1" service: "KINTO" labels: owner: "KINTO Technologies Corporation" repo: "slo-maintenance" tier: "2" slos: # We allow failing (5xx and 429) 5 request every 1000 requests (99.5%). - name: "kinto-requests-availability" objective: 99.5 description: "Common SLO based on availability for HTTP request responses." sli: events: error_query: sum(rate(http_server_requests_seconds_count{application="kinto",status=~"(5..|429)",uri!~".*actuator.*"}[{{.window}}])) total_query: sum(rate(http_server_requests_seconds_count{application="kinto",uri!~".*actuator.*"}[{{.window}}])) alerting: name: KINTOHighErrorRate labels: category: "availability" annotations: # Overwrite default Sloth SLO alert summary on ticket and page alerts. summary: "High error rate on 'KINTO SERVICE' requests responses" page_alert: labels: severity: "critical" ticket_alert: labels: severity: "warning" http_server_requests_seconds_count is a metric for when using Spring Boot. With this file saved in the ./source/ directory, run the following command: docker pull ghcr.io/slok/sloth docker run -v /$(pwd):/home ghcr.io/slok/sloth generate -i /home/source/slo_spec.yml > slo_generated_rules.yml Running the above command generates the following files in the current directory. The generated files can be uploaded to Prometheus as is. :::details slo_generate_rules.yml --- # Code generated by Sloth (a9d9dc42fb66372fb1bd2c69ca354da4ace51b65): https://github.com/slok/sloth. # DO NOT EDIT. groups: - name: sloth-slo-sli-recordings-KINTO-kinto-requests-availability rules: - record: slo:sli_error:ratio_rate5m expr: | (sum(rate(http_server_requests_seconds_count{application="kinto",status=~"(5..|429)",uri!~".*actuator.*"}[5m]))) / (sum(rate(http_server_requests_seconds_count{application="kinto",uri!~".*actuator.*"}[5m]))) labels: owner: KINTO Technologies Corporation repo: slo-maintenance sloth_id: KINTO-kinto-requests-availability sloth_service: KINTO sloth_slo: kinto-requests-availability sloth_window: 5m tier: "2" - record: slo:sli_error:ratio_rate30m expr: | (sum(rate(http_server_requests_seconds_count{application="kinto",status=~"(5..|429)",uri!~".*actuator.*"}[30m]))) / (sum(rate(http_server_requests_seconds_count{application="kinto",uri!~".*actuator.*"}[30m]))) labels: owner: KINTO Technologies Corporation repo: slo-maintenance sloth_id: KINTO-kinto-requests-availability sloth_service: KINTO sloth_slo: kinto-requests-availability sloth_window: 30m tier: "2" - record: slo:sli_error:ratio_rate1h expr: | (sum(rate(http_server_requests_seconds_count{application="kinto",status=~"(5..|429)",uri!~".*actuator.*"}[1h]))) / (sum(rate(http_server_requests_seconds_count{application="kinto",uri!~".*actuator.*"}[1h]))) labels: owner: KINTO Technologies Corporation repo: slo-maintenance sloth_id: KINTO-kinto-requests-availability sloth_service: KINTO sloth_slo: kinto-requests-availability sloth_window: 1h tier: "2" - record: slo:sli_error:ratio_rate2h expr: | (sum(rate(http_server_requests_seconds_count{application="kinto",status=~"(5..|429)",uri!~".*actuator.*"}[2h]))) / (sum(rate(http_server_requests_seconds_count{application="kinto",uri!~".*actuator.*"}[2h]))) labels: owner: KINTO Technologies Corporation repo: slo-maintenance sloth_id: KINTO-kinto-requests-availability sloth_service: KINTO sloth_slo: kinto-requests-availability sloth_window: 2h tier: "2" - record: slo:sli_error:ratio_rate6h expr: | (sum(rate(http_server_requests_seconds_count{application="kinto",status=~"(5..|429)",uri!~".*actuator.*"}[6h]))) / (sum(rate(http_server_requests_seconds_count{application="kinto",uri!~".*actuator.*"}[6h]))) labels: owner: KINTO Technologies Corporation repo: slo-maintenance sloth_id: KINTO-kinto-requests-availability sloth_service: KINTO sloth_slo: kinto-requests-availability sloth_window: 6h tier: "2" - record: slo:sli_error:ratio_rate1d expr: | (sum(rate(http_server_requests_seconds_count{application="kinto",status=~"(5..|429)",uri!~".*actuator.*"}[1d]))) / (sum(rate(http_server_requests_seconds_count{application="kinto",uri!~".*actuator.*"}[1d]))) labels: owner: KINTO Technologies Corporation repo: slo-maintenance sloth_id: KINTO-kinto-requests-availability sloth_service: KINTO sloth_slo: kinto-requests-availability sloth_window: 1d tier: "2" - record: slo:sli_error:ratio_rate3d expr: | (sum(rate(http_server_requests_seconds_count{application="kinto",status=~"(5..|429)",uri!~".*actuator.*"}[3d]))) / (sum(rate(http_server_requests_seconds_count{application="kinto",uri!~".*actuator.*"}[3d]))) labels: owner: KINTO Technologies Corporation repo: slo-maintenance sloth_id: KINTO-kinto-requests-availability sloth_service: KINTO sloth_slo: kinto-requests-availability sloth_window: 3d tier: "2" - record: slo:sli_error:ratio_rate30d expr: | sum_over_time(slo:sli_error:ratio_rate5m{sloth_id="KINTO-kinto-requests-availability", sloth_service="KINTO", sloth_slo="kinto-requests-availability"}[30d]) / ignoring (sloth_window) count_over_time(slo:sli_error:ratio_rate5m{sloth_id="KINTO-kinto-requests-availability", sloth_service="KINTO", sloth_slo="kinto-requests-availability"}[30d]) labels: owner: KINTO Technologies Corporation repo: slo-maintenance sloth_id: KINTO-kinto-requests-availability sloth_service: KINTO sloth_slo: kinto-requests-availability sloth_window: 30d tier: "2" - name: sloth-slo-meta-recordings-KINTO-kinto-requests-availability rules: - record: slo:objective:ratio expr: vector(0.995) labels: owner: KINTO Technologies Corporation repo: slo-maintenance sloth_id: KINTO-kinto-requests-availability sloth_service: KINTO sloth_slo: kinto-requests-availability tier: "2" - record: slo:error_budget:ratio expr: vector(1-0.995) labels: owner: KINTO Technologies Corporation repo: slo-maintenance sloth_id: KINTO-kinto-requests-availability sloth_service: KINTO sloth_slo: kinto-requests-availability tier: "2" - record: slo:time_period:days expr: vector(30) labels: owner: KINTO Technologies Corporation repo: slo-maintenance sloth_id: KINTO-kinto-requests-availability sloth_service: KINTO sloth_slo: kinto-requests-availability tier: "2" - record: slo:current_burn_rate:ratio expr: | slo:sli_error:ratio_rate5m{sloth_id="KINTO-kinto-requests-availability", sloth_service="KINTO", sloth_slo="kinto-requests-availability"} / on(sloth_id, sloth_slo, sloth_service) group_left slo:error_budget:ratio{sloth_id="KINTO-kinto-requests-availability", sloth_service="KINTO", sloth_slo="kinto-requests-availability"} labels: owner: KINTO Technologies Corporation repo: slo-maintenance sloth_id: KINTO-kinto-requests-availability sloth_service: KINTO sloth_slo: kinto-requests-availability tier: "2" - record: slo:period_burn_rate:ratio expr: | slo:sli_error:ratio_rate30d{sloth_id="KINTO-kinto-requests-availability", sloth_service="KINTO", sloth_slo="kinto-requests-availability"} / on(sloth_id, sloth_slo, sloth_service) group_left slo:error_budget:ratio{sloth_id="KINTO-kinto-requests-availability", sloth_service="KINTO", sloth_slo="kinto-requests-availability"} labels: owner: KINTO Technologies Corporation repo: slo-maintenance sloth_id: KINTO-kinto-requests-availability sloth_service: KINTO sloth_slo: kinto-requests-availability tier: "2" - record: slo:period_error_budget_remaining:ratio expr: 1 - slo:period_burn_rate:ratio{sloth_id="KINTO-kinto-requests-availability", sloth_service="KINTO", sloth_slo="kinto-requests-availability"} labels: owner: KINTO Technologies Corporation repo: slo-maintenance sloth_id: KINTO-kinto-requests-availability sloth_service: KINTO sloth_slo: kinto-requests-availability tier: "2" - record: sloth_slo_info expr: vector(1) labels: owner: KINTO Technologies Corporation repo: slo-maintenance sloth_id: KINTO-kinto-requests-availability sloth_mode: cli-gen-prom sloth_objective: "99.5" sloth_service: KINTO sloth_slo: kinto-requests-availability sloth_spec: prometheus/v1 sloth_version: a9d9dc42fb66372fb1bd2c69ca354da4ace51b65 tier: "2" - name: sloth-slo-alerts-KINTO-kinto-requests-availability rules: - alert: KINTOHighErrorRate expr: | ( max(slo:sli_error:ratio_rate5m{sloth_id="KINTO-kinto-requests-availability", sloth_service="KINTO", sloth_slo="kinto-requests-availability"} > (14.4 * 0.005)) without (sloth_window) and max(slo:sli_error:ratio_rate1h{sloth_id="KINTO-kinto-requests-availability", sloth_service="KINTO", sloth_slo="kinto-requests-availability"} > (14.4 * 0.005)) without (sloth_window) ) or ( max(slo:sli_error:ratio_rate30m{sloth_id="KINTO-kinto-requests-availability", sloth_service="KINTO", sloth_slo="kinto-requests-availability"} > (6 * 0.005)) without (sloth_window) and max(slo:sli_error:ratio_rate6h{sloth_id="KINTO-kinto-requests-availability", sloth_service="KINTO", sloth_slo="kinto-requests-availability"} > (6 * 0.005)) without (sloth_window) ) labels: category: availability severity: critical sloth_severity: page annotations: summary: High error rate on 'KINTO SERVICE' requests responses title: (page) {{$labels.sloth_service}} {{$labels.sloth_slo}} SLO error budget burn rate is too fast. - alert: KINTOHighErrorRate expr: | ( max(slo:sli_error:ratio_rate2h{sloth_id="KINTO-kinto-requests-availability", sloth_service="KINTO", sloth_slo="kinto-requests-availability"} > (3 * 0.005)) without (sloth_window) and max(slo:sli_error:ratio_rate1d{sloth_id="KINTO-kinto-requests-availability", sloth_service="KINTO", sloth_slo="kinto-requests-availability"} > (3 * 0.005)) without (sloth_window) ) or ( max(slo:sli_error:ratio_rate6h{sloth_id="KINTO-kinto-requests-availability", sloth_service="KINTO", sloth_slo="kinto-requests-availability"} > (1 * 0.005)) without (sloth_window) and max(slo:sli_error:ratio_rate3d{sloth_id="KINTO-kinto-requests-availability", sloth_service="KINTO", sloth_slo="kinto-requests-availability"} > (1 * 0.005)) without (sloth_window) ) labels: category: availability severity: warning sloth_severity: ticket annotations: summary: High error rate on 'KINTO SERVICE' requests responses title: (ticket) {{$labels.sloth_service}} {{$labels.sloth_slo}} SLO error budget burn rate is too fast. ::: This time, we generated a simple example, but in practice, you’ll likely define multiple, more complex SLI/SLO specifications. Without Sloth, you would need to manage lengthy, generated-like code directly. Sloth significantly reduces the hassle involved in this process Configuration procedure At KINTO Technologies, we use Amazon Managed Service for Prometheus. This enables you to upload the generated files via the AWS Managed Console. For more information on how to use Amazon Managed Service for Prometheus, please refer to the official documentation: https://docs.aws.amazon.com/ja_jp/prometheus/latest/userguide/AMP-rules-upload.html Alternatively, you can run the AWS CLI from a workflow. Here is an example using GitHub Actions. name: SLO set up on: workflow_dispatch: jobs: setup-slo: name: Set up SLOs runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set AWS Credentials to EnvParam(Common) uses: aws-actions/configure-aws-credentials@v2 with: aws-access-key-id: ${{ AWS access key to be used }} aws-secret-access-key: ${{ AWS secret access key to be used }} aws-region: ${{ AWS region to be used }} ## Generate a configuration file from the definition file - name: download and setup generator binary run: | ## Please check the latest release situation as appropriate. wget https://github.com/slok/sloth/releases/download/vX.XX.X/sloth-linux-amd64 chmod +x sloth-linux-amd64 ./sloth-linux-amd64 validate -i ./services/kinto/source/slo_spec.yml ./sloth-linux-amd64 generate -i ./services/kinto/source/slo_spec.yml -o ./services/kinto/configuration.yml ## Upload the configuration file to Prometheus - name: upload configuration file to APM run: | base64 ./services/kinto/configuration.yml > ./services/kinto/configuration_base_64.yml aws amp create-rule-groups-namespace \ --data file://./services/kinto/configuration_base_64.yml \ --name slo-rules \ --workspace-id ${{ ID of the AMP workspace to be used }} ¥ --region ${{ AWS region to be used }} Visual representation Once the rule file has been uploaded to Prometheus, the next step is to represent the data visually. We use Grafana. Grafana Labs provides a dashboard template for Sloth, allowing you to visually represent the generated rules by simply importing it. https://sloth.dev/introduction/dashboards/ Procedure for configuring alerts Multiwindow, multi-burn rate alerts are sent from Prometheus. Create an Alert manager configuration file and upload it to Prometheus. https://docs.aws.amazon.com/ja_jp/prometheus/latest/userguide/AMP-alertmanager-config.html :::message With “Amazon Managed Service for Prometheus,” only notifications to Amazon SNS are currently supported. (We are hoping this will improve in the future!) Consequently, we create SNS topics in advance, then specify the topics’ ARNs in the configuration file. ::: At KINTO Technologies, we create a configuration file similar to the following to separate the routing of Critical and Warning alerts. The SNS attributes sent include the alert type information. alertmanager_config: | # The root route on which each incoming alert enters. route: # A default receiver receiver: warning_alert routes: - receiver: critical_alert matchers: - severity="critical" - receiver: warning_alert matchers: - severity="warning" # Amazon Managed Service for Prometheus, # The only receiver currently supported is Amazon Simple Notification Service (Amazon SNS). # If you have other types of receivers listed in the configuration, it will be rejected. # Expect future revisions. https://docs.aws.amazon.com/ja_jp/prometheus/latest/userguide/AMP-alertmanager-config.html receivers: - name: critical_alert sns_configs: - topic_arn: arn:aws:sns:{AWS region}:{AWS account}:prometheus-alertmanager sigv4: region: {AWS region} attributes: severity: critical slack_api_url: '<your slack api url>' slack_channel: '#<your channel name>' - name: warning_alert sns_configs: - topic_arn: arn:aws:sns:{AWS region}:{AWS account}:prometheus-alertmanager sigv4: region: {AWS region} attributes: severity: warning slack_api_url: '<your slack api url>' slack_channel: '#<your channel name>' Also, we subscribe to the SNS topics on AWS Lambda. Lambda uses the attributes from the triggered notification to dynamically route the alerts to the appropriate Slack channels. In practice, we will customize this more, for example, by making it hit the PagerDuty API if a Critical alert is triggered. # # this script based on https://aws.amazon.com/jp/premiumsupport/knowledge-center/sns-lambda-webhooks-chime-slack-teams/ # import urllib3 import json http = urllib3.PoolManager() def lambda_handler(event, context): print({"severity": event["Records"][0]["Sns"]["MessageAttributes"]["severity"]["Value"]}) url = event["Records"][0]["Sns"]["MessageAttributes"]["slack_api_url"]["Value"] msg = { "channel": event["Records"][0]["Sns"]["MessageAttributes"]["slack_channel"]["Value"], "username": "PROMETHEUS_ALERTMANAGER", "text": event["Records"][0]["Sns"]["Message"], "icon_emoji": "", } encoded_msg = json.dumps(msg).encode("utf-8") resp = http.request("POST", url, body=encoded_msg) print( { "message": event["Records"][0]["Sns"]["Message"], "status_code": resp.status, "response": resp.data, } ) Neat approaches we came up with SLOs as Code With Sloth, you can encode SLI/SLO specifications in the YAML file format. Since this is code, the version can be managed using tools like Git. In addition, you can use hosting tools such as GitHub to make it easier to review. As long as the SLI/SLO specifications are compatible with Prometheus (expressible using PromQL), they can be applied not only to applications but also to metrics monitoring for load balancers and external monitoring services. So, it is fair to say that Sloth has a wide scope of application. In the KINTO Technologies SRE Team, we consolidate all the YAML-format SLI/SLO specifications into a single GitHub repository. The SRE team provides a template in the repository, and the development teams define SLI/SLO specifications based on that, commit them, then create a pull request. The SRE team then reviews the pull request. This procedure makes it possible to understand the SLI/SLO specifications and reflect them in the monitoring smoothly. This approach helps reduce management costs and allows SLOs for any product to be more easily referenced across KINTO Technologies’ entire development organization. The service level of a dependency has a significant impact on the service level of its own service. Since KINTO Technologies' services rely on each other, sharing service levels across organizational boundaries helps maintain the service levels of individual services more effectively. Latency SLI With "slow being the new down," we need to monitor response times in addition to tracking 5xx errors. We will represent the following simple SLI/SLO specification in a YAML file that follows the Sloth standards. Category SLI SLO Latency Among the successful requests measured by the application, consolidate and measure all request paths except actuator. Among 30 days’ worth of requests, the percentage of those that return a response in less than 3,000 milliseconds. 99% version: "prometheus/v1" service: "KINTO" labels: owner: "KINTO Technologies Corporation" repo: "slo-maintenance" tier: "2" slos: ... # We allow failing (less than 3000ms) and (5xx and 429) 990 request every 1000 requests (99%). - name: "kinto-requests-latency-99percent-3000ms" objective: 99 description: "Common SLO based on latency for HTTP request responses." sli: raw: # Get the average satisfaction ratio and rest 1 (max good) to get the error ratio. error_ratio_query: | 1 - ( sum(rate(http_server_requests_seconds_bucket{le="3",application="kinto",status!~"(5..|429)",uri!~".*actuator.*"}[{{.window}}])) / sum(rate(http_server_requests_seconds_count{application="kinto",status!~"(5..|429)",uri!~".*actuator.*"}[{{.window}}])) ) alerting: name: KINTOHighErrorRate labels: category: "latency" annotations: summary: "High error rate on 'kinto service' requests responses" page_alert: labels: severity: "critical" ticket_alert: labels: severity: "warning" To get the data in histogram form, add the following settings to application.yml: management: ... metrics: tags: application: ${spring.application.name} distribution: percentiles-histogram: http: server: requests: true slo: http: server: requests: 100ms, 500ms, 3000ms Adding the settings below management.metrics.distribution configures it to give the metrics via the histogram-type percentages-histogram rather than the summary-type percentiles . The reason for this is that percentiles aggregate response times for a specific percentile only on a per-task basis and for the last minute, meaning they cannot be aggregated across multiple tasks or over an extended period, like 30 days. On the other hand, percentiles-histogram stores the number of requests with response times within the threshold as a value, so they can be aggregated for an arbitrary range across multiple tasks using PromQL. This approach allows us to define the latency SLI specification as the percentage of total requests that meet the specified criteria. Discussion Recommendation for a settable SLO: At least 94% The Site Reliability Workbook provides recommended window and burn rate thresholds for detecting error budget consumption. https://sre.google/workbook/alerting-on-slos/#6-multiwindow-multi-burn-rate-alerts By default, Sloth supports several of the burn rates given in the Site Reliability Workbook. Consequently, the maximum burn rate threshold for which alerts can occur is 14.4. In this case, for example, if the SLO is 93%, the error budget will be 7%. If we calculate the error rate for a burn rate of 14.4, we get 14.4 * 7 = 100.8. Basically, the error rate is calculated using “error requests divided by all requests,” so it cannot exceed 100. This means that if you set the SLO to 93%, there is zero probability that an alert will be fired that reports a burn rate above 14.4. Consequently, we recommend setting an SLO of at least 94%. Conclusion In my previous articles, I’ve shared the initiatives we’re working on within the KINTO Technologies SRE Team. What did you think? While the organization as a whole isn’t required to manage service levels with extreme rigor, we’re pleased to have the flexibility to easily test useful alerts using the techniques described here. The Platform Group is actively looking for new team members to join us If you are interested and would like to hear more, please feel free to contact us! @ card
アバター
Introduction Hello. I appreciate you taking the time to read this! My name is Nakamoto, and I work on developing the frontend for KINTO FACTORY ('FACTORY' in this article), a service that enables users to upgrade their current vehicles. In this article, I would like to introduce Strapi , an open-source tool which we implemented to create and manage the content for the newly launched FACTORY Magazine . What is Strapi? Strapi is a self-hosted, headless CMS that, unlike other SaaS-based CMS options, allows users to set up and manage their own servers, databases, and environments. (Strapi also offers Strapi Cloud , which provides a cloud environment.) At KINTO, we’ve worked with several SaaS CMS platforms to publish columns and articles. However, encountered limitations balancing operational efficiency with costs, along with the limited flexibility to add new features or customize existing ones. This led us to explore OSS CMS tools with the aim of setting up a self-hosted solution. WordPress is likely the most recognized OSS headless CMS. However, while researching other tools that are recently gaining popularity. This is how we came across Strapi. When evaluating open-source tools, we prioritized the following: Usability : A user-friendly management UI, accessible to both developers and content managers Community Support : Backed by a large community and extensive documentation Plugin Variety : A diverse range of plugins for easily extending functionality Scalability : Built on Node.js for high performance and scalability If certain functions were missing or didn’t align with our needs, we could easily modify or create plugins using our JavaScript expertise. The low implementation cost was also a key factor in our decision. Architecture and Deployment Mechanism Strapi, like FACTORY's e-commerce site, is hosted on AWS and consists of a simple architecture using ECS and Aurora. Strapi, as a CMS, operates independently from FACTORY's web application, primarily supporting internal teams like business units in writing and publishing articles. When publishing an article, it triggers a build of the web application, during which article information is retrieved from Strapi's API and directly embedded into the page. This setup means that users don’t directly interact with Strapi, creating a closed network for the CMS environment and eliminating unnecessary external access. Customization Case Study Let’s take a look at some of the customizations we implemented during the setup process. Creating new plugins In FACTORY magazine, there is a page titled User's Voice that features interviews with customers who have purchased and installed items from FACTORY. For these articles, it’s essential to link the car models or item names associated with each installation. Users enter details like "car model name (e.g., RAV4)" or "item name (e.g., Headlamp Design Upgrade)" in the standard input field. Vehicle Information Entry However, allowing free text entry can lead to inconsistencies in naming. To make it easier to search articles by car model or item—similar to a blog—it's more effective to link item IDs and other data stored within FACTORY to the articles. We addressed this by creating dropdown lists for these input fields, utilizing the BFF (Backend for Frontend) services already in place for the e-commerce site. Vehicle Selection Item Selection With this approach, the custom plugins enable precise linking of item and car model information. We also customized the images for an intuitive display, simplifying selection for the author. Leveraging the existing BFF from the e-commerce site highlights another advantage of a self-hosted CMS. Unlike SaaS solutions, this setup offers greater flexibility for customizations while minimizing security risks, as mentioned earlier. :::message An article on creating a custom API has already been published, so I encourage you to check that out as well! Implementing a custom API in Strapi ::: Customizing existing plugins As another example of customization, we introduced this existing plugin, tagsinput , to meet the requirement of searching for similar articles by linking tags to them. However, this plugin saves the entered tags in the database as an associative array, like this: [{ name: tag1 }, { name: tag2 }] . This made the search logic complicated when creating an API to search by tags. So, to simplify the search, I made slight customizations to the plugin, changing it to store the entered tags as an array of strings [tag1, tag2] . https://github.com/canopas/strapi-plugin-tagsinput/blob/1.0.6/admin/src/components/Input/index.js#L29-L36 @@ -26,8 +26,7 @@ const { formatMessage } = useIntl(); const [tags, setTags] = useState(() => { try { - const values = JSON.parse(value); - return values.map((value) => value.name); + return JSON.parse(value) || []; } catch (e) { return []; } https://github.com/canopas/strapi-plugin-tagsinput/blob/1.0.6/admin/src/components/Input/index.js#L64-L70 @@ -38,7 +37,7 @@ onChange({ target: { name, - value: JSON.stringify(tags.map((tag) => ({ name: tag }))), + value: JSON.stringify(tags), type: attribute.type, }, }); This approach makes it easy to tweak existing plugins, tailoring them to better suit our specific needs. One of the key customizations we've implemented is adding video tags to CKEditor, the rich text editor Strapi uses for article postings. Since this requires a more in-depth explanation, we’ll cover it in a separate article. Conclusion FACTORY was the first among KINTO's services to introduce Strapi, an open-source CMS tool. Teams using Strapi for writing and posting articles have shared positive feedback, noting it’s "easier to use than SaaS-based CMS services"—a promising sign for the tool’s future. We’re already receiving feature requests, which we plan to address by taking full advantage of Strapi’s customizability. Although we’re in the early stages of operations, I’m excited to gain experience and explore Strapi’s potential, looking beyond article publishing to find innovative uses. I also plan to share FACTORY's approach with other KINTO services using SaaS CMS tools, aiming to foster broader adoption and development across the company.
アバター
Introduction Hello, I'm Ryo, a developer of ID Platform in the Global Development Group. I participated in the OpenID Summit at Shibuya Stream Hall on January 19th 2024, so I am writing this article to share my impressions and the interesting points I found. Due to the COVID-19 pandemic, the summit was held for the first time in four years since the OpenID Summit Tokyo 2020. It was very exciting as many people who are interested in OpenID gathered at the venue on the day of the event. The topic this time was regarding what kind of change digital identity has brought about in the four years surrounding the COVID-19 pandemic, and what kind of development digital identity is likely to take place in the world in the future. Program Flow Impressions OpenID is not a very well known topic compared to other highly versatile technology fields, and I think there are many people who have never heard of it. However, when I arrived at the summit venue, there were many people who were interested in OpenID from many companies. I was a little surprised. Some people were attending for the first time, so in the morning, we were introduced to the history of OpenID's development so far, the future development and outlook for OpenID in the areas of digital identity and electronic money, and details of the translation of materials and human resource development activities being carried out by the OpenID Foundation Japan Working Group. From the content presented in the morning, I deeply felt that the future direction of OpenID development is changing from the area of authentication and authorization to identity verification (digital identity) and electronic payments management. As for the topics presented in the afternoon, each company explained the problems encountered during the implementation and operation stage of OpenID and the overall solutions and countermeasures. However, the afternoon program was held at two different venues, and since I cannot make copies of myself like Naruto , unfortunately I could not attend both at the same time. Impressive presentation Consideration of countermeasures against spoofing attacks when using OpenID Connect Presenter: Junki Yuasa (Nara Institute of Science and Technology, Laboratory for Cyber Resilience). The case presented here is quite rare, but I was surprised that a second-year master's student had delved so deeply into OpenID operation experiments. Although there are several authentication modes for OpenID, security may be low depending on the usage scenario, so I think that in future developments, we should be careful about risky parts in specific cases like this one. Mercari App Access Token Presenter: Nguyen Da (Mercari, Inc. ID Platform Team Software Engineer ). The Mercari App is well-known in Japan as a very popular online second hand marketplace. The ID Platform Engineer explained how Mercari ID faced some difficulties with the old method of operation, and how they worked to make it easier for users to use the service on the mobile app and browser. With that, I learned that although we have achieved many goals in utilizing browser cookies, only Chrome browsers have special specifications, with a cookie validity period of 400 days . Since we launched our ID platform, we have gone through many challenges and efforts regarding UI and UX, but I learned for the first time that the cookie validity period is 400 days . About JWT You may have heard of the name JWT (JSON Web Token), but if you are not familiar with authentication and authorization, you may not have had a chance to learn about the role of JWT or the interrelationship between JWK, JWS, and JWE, which are often mentioned together. So let me give a brief explanation in advance: JWT is a standard for ensuring the reliability of information exchanged on a network. Among them, JWS and JWE are examples of the implementation of the JWT standard. JWS (JSON Web Signature) uses "." as shown in the figure below.It is divided into three parts: ** Header (authentication method), Payload (actual information), Signature (guarantee against tampering)**. JWS has been base64 encoded, so the decoded Payload has all the information disclosed. According to the explanation of JWT, JWK (Json Web Key) is an encryption key that is written in the JWT Header and used to encrypt the hash of the Payload contents to generate a Signature. JWE (JSON Web Encryption) is a JWT that can protect the safety and integrity of the JWS mentioned above. So, it was divided into five parts using ".", with the second being a Payload-specific code that serves as the decryption key. Only the owner of the encryption key can decrypt the contents of the Payload. Source SD-JWT At this OpenID Summit, Italy's track record of electronic money implementation and operation was introduced. Here, they explained a new concept for me called SD-JWT . This was the first time I had heard of it, so I looked it up myself after the summit ended. From here on, we will finally delve into the main subject of this article. I would like to briefly explain what I found about SD-JWT. Selective Disclosure JWT (SD-JWT) is, as the name suggests, a JWT in which particular information is only disclosed to selected parties. I will first explain the background to the design of SD-JWT, when JWS and JWE already exist in the world. There are currently two types of Payload disclosures: Full Disclosure: Anyone can parse the JWS using base64 and see everything in the payload. Complete confidentiality: In the case of JWE, the contents of the JWE payload cannot be seen by anyone other than the owner who has the decryption key. However, there is no solution for cases where you only want to disclose some information. That is why SD-JWT was born. For example, when an electronic wallet owner purchases a product worth 100,000 yen, they do not need to see the general attribute information (birthday, address, phone number, etc.) that the product seller uses to authenticate the buyer, and they only want to see the buyer's electronic wallet balance. As a buyer, you can make a purchase by disclosing only essential information such as your balance and ID without disclosing all your personal information. This alone may not be enough, but it is effective to prevent leakage of personal information to a certain extent by disclosing only the necessary information of the owner from the JWS to the business operator. How to implement SD-JWT Let's start with the traditional ID token generation procedure. First, display the personal information of a certain user A in JSON format as shown below. { "sub": "cd48414c-381a-4b50-a935-858c1012daf0", "given_name": "jun", "family_name": "liang", "email": "jun.liang@example.com", "phone_number": "+81-080-123-4567", "address": { "street_address": "123-456", "locality": "shibuya", "region": "Tokyo", "country": "JP" }, "birthdate": "1989-01-01" } The issuer then assigns an SD-JWT Salt (random value) to each attribute information. { "sd_release": { "sub": "[\"2GLC42sKQveCfGfryNRN9c\", \"cd48414c-381a-4b50-a935-858c1012daf0\"]", "given_name": "[\"eluV5Og3gSNII8EYnsxC_B\", \"jun\"]", "family_name": "[\"6Ij7tM-a5iVPGboS5tmvEA\", \"liang\"]", "email": "[\"eI8ZWm9QnKPpNPeNen3dhQ\", \"jun.liang@example.com\"]", "phone_number": "[\"Qg_O64zqAxe412a108iroA\", \"+81-080-123-4567\"]", "address": "[\"AJx-095VPrpTtM4QMOqROA\", {\"street_address\": \"123-456\", \"locality\": \"shibuya\", \"region\": \"Tokyo\", \"country\": \"JP\"}]", "birthdate": "[\"Pc33CK2LchcU_lHggv_ufQ\", \"1989-01-01\"]" } } The attribute information of "sd_release" is calculated using the hash function specified in "_sd_alg" and stored in "_sd" below, and a new payload can be created by adding the issuer's signing key (cnf), validity period (ext), and issuance time (iat). The latest token is issued based on the payload, and the SD-JWT has been created. { "kid": "tLD9eT6t2cvfFbpgL0o5j/OooTotmvRIw9kGXREjC7U=", "alg": "RS256" }. { "_sd": [ "5nXy0Z3QiEba1V1lJzeKhAOGQXFlKLIWCLlhf_O-cmo", "9gZhHAhV7LZnOFZq_q7Fh8rzdqrrNM-hRWsVOlW3nuw", "S-JPBSkvqliFv1__thuXt3IzX5B_ZXm4W2qs4BoNFrA", "bviw7pWAkbzI078ZNVa_eMZvk0tdPa5w2o9R3Zycjo4", "o-LBCDrFF6tC9ew1vAlUmw6Y30CHZF5jOUFhpx5mogI", "pzkHIM9sv7oZH6YKDsRqNgFGLpEKIj3c5G6UKaTsAjQ", "rnAzCT6DTy4TsX9QCDv2wwAE4Ze20uRigtVNQkA52X0" ], "iss": "https://example.com/issuer", "iat": 1706075413, "exp": 1735689661, "_sd_alg": "sha-256", "cnf": { "jwk": { "kty": "EC", "crv": "P-256", "x": "SVqB4JcUD6lsfvqMr-OKUNUphdNn64Eay60978ZlL74", "y": "lf0u0pMj4lGAzZix5u4Cm5CMQIgMNpkwy163wtKYVKI", "d": "0g5vAEKzugrXaRbgKG0Tj2qJ5lMP4Bezds1_sTybkfk" } } }. { Signature The issuer calculates the Payload signature with the public key and places it here, ensuring that the contents of the Payload are not tampered with } The order of the attributes and hash values ​​of "sd_release" and "_sd" does not need to be maintained. How to use SD-JWT The issuer sends the SD-JWT and "sd_release" together to the owner. Depending on the usage situation, the owner can submit the attribute information they want to disclose and the SD-JWT at the same time, allowing authentication while maintaining safety and integrity. "email": "[\"eI8ZWm9QnKPpNPeNen3dhQ\", \"jun.liang@example.com\"]", If you only want to disclose your e-mail address, you will need to submit the above part together with the SD-JWT. The verifier can check the accuracy of the email by checking the following two points  The result of calculating the e-mail portion with the hash function matches "5nXy0Z3QiEba1V1lJzeKhAOGQXFlKLIWCLlhf_O-CMO" in the "_sd " list The signature recalculation result of the Payload matches the signature in SD-JWT (the Payload has not been tampered with). Summary By participating in this summit, I was able to understand the history and future development of OpenID. In addition, I learned about SD-JWT, which is a different format from the JWT that the ID team has used so far. There were many interesting discussions, so I recommend participating even if you are not usually involved in the field of ID. I am looking forward to being able to join as a speaker one day representing KINTO Technologies in the future. Reference OpenID Summit Tokyo 2024
アバター
Introduction Hello. I am Nakaguchi from KINTO Technologies’ Mobile App Development Group. I am the team leader of the iOS team for KINTO Easy Application app. As part of our team building efforts, we conducted a 180-degree feedback session, and I would like to share the details of this initiative. If you’re interested, please check out this article on our team’s retrospective , which was another initiative carried out by our team. Background Recently, a group of volunteers within our company organized a group reading session "GitLab ni manabu sekai saisentan no remote soshiki no tsukurikata: Dokumento no katsuyo de office nashi demo saidai no seika o dasu global kigyo no shikumi" . You can learn more about this group reading session in Learning from GitLab: How to Create the World's Most Advanced Remote Organization . This group reading session was truly inspiring to me, and I wanted to bring some of the insights back to my team. Among the various topics we discussed, I was particularly interested in the concept of 360-degree feedback. 360-degree feedback is an evaluation method where an employee receives feedback from multiple perspectives, including colleagues, superiors, and subordinates. In general, feedback tends to be given from superiors to subordinates. Personally, I’ve always believed that feedback between colleagues, or from co-workers to supervisors, is equally important. This led me to consider implementing 360-degree feedback within our team. However, during the session, we also identified that the 360-degree feedback has potential drawbacks, such as a broad range of respondents and evaluations given to an employee from individuals who may not be directly involved in the employee's work. In counteracting the drawbacks, I learned about the 180-degree feedback method limiting the respondents to just the team members and decided to introduce it to my team. Objectives Through the 180-degree feedback process, I aimed to achieve the following objectives: Identify the discrepancy between the roles the team expects each member to fulfill and others each member perceives for themselves. Recognize individual strengths and weaknesses, and use these insights for future growth Create an opportunity for team members to express their honest opinions about each other. Foster team unity by encouraging team members to be considerate of their peers' feelings through the survey process. I believed that this 180-degree feedback would be a great opportunity for members to understand each other, thereby improving the quality of relationships within the team. Implementation Method Target members: 1 team Leader 6 engineers Survey method We conducted an anonymous survey using Microsoft Forms. Each member answered the following questions for all other members except themselves: Quantitative evaluation (5-point scale): Questions regarding proactivity Questions regarding openness to others Questions regarding decision making attitude Questions regarding perseverance Questions regarding learning from new experiences Questions regarding initiative Qualitative evaluation (free text): Questions regarding self-strengths Questions regarding areas for improvement Words of appreciation to the target members Considerations to proceed the survey To ensure team members positively engage in the process, we, in advance, shared the background and objectives of the feedback at 1-on-1 meetings. To reinforce the anonymity of the survey, we conducted a pre-test survey and shared the results. To avoid a low response rate caused by insufficient time to complete the survey, we allocated specific time for its completion. As feedbacks may include harsh or negative comments about target members, we added a question to allow respondents to express their gratitude to the others at the end of the survey. (This helps to end the survey on a positive note and makes it easier for recipients to accept the feedback constructively.) As a team leader, I wanted to show my team members that I am open-minded to share my feedback results, including self-improvement areas, with them. (However, I did not pressure the team members to share their own feedback results.) Summary of My Feedback Results I have summarized my feedback results below. Strengths High communication skills and approachability: for example, I actively participate in meetings and make an effort to explain things clearly. Eagerness to learn and share knowledge with others: I consistently stay updated on new technology trends and share this information through Slack and meetings. Efforts to improve teamwork: I regularly organize team events to strengthen the bonds among team members. Strong information-gathering skills and quick response: I promptly address issues as they arise and communicate accurate information to relevant parties. Compassionate and reliable leader: I listen to any concerns from team members and appropriately provide them with advice. Areas for Improvement Understanding of product specifications: at times, I proceed with development without fully understanding the specifications of the features. Improvement to organize task tickets more frequently: the prioritization of tickets is sometimes insufficient, which causes important tasks to be delayed. Improvement to clearly explain the background and purpose of implementing initiatives: insufficient communication leaves the purpose of some initiatives unclear, resulting in a lack of understanding among team members. Improvement to take more risks: I may be too cautious when approaching new initiatives, which can result in missed opportunities. My feedback results showed that the areas I consciously focus on were recognized as strengths, which was very pleasing. On the other hand, the feedback on areas for improvement allowed me to recognize not only the aspects I was aware of but also those I had not realized. This feedback will help me grow further. Additionally, the words of appreciation from team members at the end boosted my motivation significantly. I am committed to continuing to contribute to the team even more in the future. Team Strengths and Areas for Improvement Identified Through 180-degree Feedback I also summarized the feedback as an overall team. Team strength Diverse technical skills and leadership : each member has strong technical skills and leadership abilities. Communication skills : communication within the team is active, and information is shared effectively. Problem-solving ability : the team actively tackles technical challenges and complex tasks. Learning motivation : there is a strong commitment to acquiring new knowledge and technical skills, leading to continuous growth. Areas for improvement for the entire team Improving information sharing efficiency : finding more efficient ways to share new technical skills and project-related information. Clarifying roles and responsibilities : further clarifying roles and responsibilities to fully leverage each team member’s abilities. Developing a broader perspective : emphasizing the importance of sharing the project’s overall vision and objectives among the team members. Technical skill sharing and knowledge management : promoting the cross-sharing of technical knowledge within the team to enhance the skills of all members. Additionally, I have summarized each team member’s strengths and roles in the diagram below. Post-Retrospective Survey After conducting the 180-degree feedback, we carried out a survey to gather feedback on the process. (out of 7 responses). Change in evaluation Before: 7.29 -> After: 9.19 NPS (What is NPS?) 57 Would you like to conduct 180-degree feedback on a regular basis (e.g. every six months)? 86% answered “Yes” AI summary of "How satisfied did you feel after you participated?" (free text) The survey results indicate that respondents felt they gained a deeper self-awareness and were able to identify their own challenges. Additionally, through feedback from others, they were able to gain new perspectives that they might not have noticed otherwise. By receiving specific evaluations and areas for improvement, they felt that their future course of action become clearer. These results suggest that the survey was an effective tool for self-reflection. Conclusion In conducting the 180-degree feedback, we encountered a few operational challenges. The average scores were generally high, making it difficult to differentiate between responses. The timing coincided with changes in team members, which resulted in failing to provide feedback to certain team members in an appropriate manner. However, overall, I felt that the feedback process was well-received and satisfying for the team, including myself. As evidenced by the survey results, the team members are highly interested in continuing this process regularly, and I plan to carry on with these efforts in the future. Through this feedback, I was able to identify areas for improvement both for myself and the team as a whole, which I intend to leverage for future growth. I also hope that each team members can also recognize their own areas for improvement and use this as an opportunity for growth.
アバター
🎉 We Are Going to Be a Gold Sponsor for iOSDC Japan 2024 Hello! The Obon season is just around the corner now, right? I am planning to take my children someplace fun this year. Hiroya (@___TRAsh) here. Well, this time, I have some news from the iOS team. KINTO Technologies is going to be a Gold Sponsor for iOSDC Japan 2024 🙌 iOSDC Japan 2024 will be our first participation as exhibitors, and we are going to hold a coding quiz. We are also planning to hand out novelty goods, so please do come visit our booth! So, seeing as it was such a great opportunity, for this article, I interviewed some of our iOS team members. I hope it will be interesting for you to see the diverse range of members we have. 🎤 The interviews This time, I interviewed the KINTO Unlimited iOS team. KINTO Unlimited is an international team with lots of members from overseas. Daily work is primarily conducted in English, though most of them also speak Japanese. T.O. —Please briefly introduce yourself. Hello. I am T.O. I am an iOS engineer at KINTO Technologies. I worked on web front-end development up to my previous job, and had never done any mobile development until I came here, or used GitHub either. I have been with the company for about two and a half years now, during which time I have been involved in a variety of projects and learned about a variety of architectures and modern development methods. —What changed for you after joining this company? Acquiring the skills needed to be an iOS engineer. Also, I moved to Tokyo when I joined KINTO Technologies, so my living environment changed as well. Back then, there were not that many people out and about due to the COVID-19 pandemic, and seeing giant pandas for the first time in Ueno Park left a big impression on me. —What do you like about this company? The atmosphere makes it extremely easy to talk to people. You can consult colleagues about both private and technical matters without hesitation. It is a real blessing to be able to feel free to talk to people whether I am in the office or working remotely. Another good thing is how the benefits package has plenty of things that are really helpful for the parenting generation. —What challenges do you want to take on in the future? In the future, I want to do development using AR and ML. I am working on a project that relates to those fields at the moment, so I want to get into them even further. Also, I want to play games with my children. —A few final words for the blog, please! You can work in a wide range of ways, so it is a very accommodating company to work for 👍 V.V. —Please briefly introduce yourself. I am a Russian who was born and raised in Russia, and have around eight years of experience in iOS development. My hobbies are TRPGs and being a parent. My previous work included creating Windows desktop apps in Russia and ambulance-related services in the United States. Then after coming to Japan, I worked for another company for several years before joining KINTO Technologies. —What changed for you after joining this company? Up to then, I had always worked for small companies, so I always felt uneasy on account of being a parent. On the other hand, KINTO Technologies is a Toyota Group company, so I can work free from worry. The basic salary is not all that different, but there are lots of extra allowances, so I think my pay has gotten quite a lot better. I was able to get a double bed with my bonus. —What do you like about this company? Previously, I had always worked in small teams, so there was no one to turn to for technical advice or mentoring. In KINTO Technologies, however, it is easy to discuss technical matters. Also, I get opportunities to share my own knowledge and there are lots of highly experienced team members around, too, so it is very stimulating. —What challenges do you want to take on in the future? I am interested in developing AR and ML functionalities, so I want to delve into those more deeply. I also want to support my family thoroughly. —A few final words for the blog, please! Come join us here, because you will find lots of opportunity to grow ✋ S.C. —Please give us a brief introduction of yourself. I am a Canadian who was born in Korea then moved to Canada, and is now living in Japan. I came to Japan because I was interested in Japanese movies and culture, and had lots of friends from here. I have been here for around 10 years now. In my previous job, I also worked on back-end development. I am currently the leader of the KINTO Unlimited iOS team. —What changed for you after joining this company? It is a group where lots of mobile engineers get involved regardless of the project, so it is easy to improve skills that have an iOS development focus. I am also glad to be spending more time working in Japanese. —What do you like about this company? In my previous job, the system was huge and I was pretty much doing maintenance work, but in KINTO Technologies, I frequently develop new functionalities, and get lots of opportunities to learn about new technologies. Another great thing is how easy it is to incorporate modern technologies. Also, I love how we actively hold study sessions, giving us lots of opportunities to share our knowledge. —What challenges do you want to take on in the future? I just became a team leader, so I want to improve my leadership skills. I am also interested in how the implementation approaches vary depending on the OS, so I want to expand my knowledge of Android as well. Also, I am currently going to grad school, so I want to graduate from that. —A few final words for the blog, please! I am in a modern development environment where I get to experience a wide variety of things that I never had any chance to before, so I am having a great time. 👍 🚙 Summary Our company is still growing, but there are many products that have only just gotten started, so it is a development environment where it is easy to incorporate modern methods. We get to work in diverse teams, so we get a lot of opportunities to learn about new cultures and technologies. If you want to work in an environment like that, please apply to join us! https://www.kinto-technologies.com/recruit/ And on that note... :::message The Challenge Token is here! #KTCでAfterPartyやります ::: On Monday, September 9, we are going to hold iOSDC JAPAN 2024 AFTER PARTY jointly with TimeTree and WealthNavi, marking our first-ever three-company collaboration event with them. 🥳** The place will be our office in Nihonbashi Muromachi. 🗺️ Please do come along to this, too! https://kinto-technologies.connpass.com/event/327743/ It will probably be extremely hot on the day. Please keep yourselves thoroughly hydrated while you are enjoying the event! We are looking forward to seeing you all at our booth ✋
アバター
Introduction Hello, this is Kuwahara @Osaka Tech Lab from the SCoE Group of KINTO Technologies (hereinafter referred to as KTC). SCoE is an abbreviation for Security Center of Excellence, which may not be a familiar term to you yet. At KTC, we restructured our CCoE team into the SCoE Group this past April. To find out more about the SCoE Group, please check our article “SCoE Group: Leading the Evolution of Cloud Security.” To find out more about the Osaka Tech Lab (KTC’s Kansai base), see “Introducing the Osaka Tech Lab.” In this blog, we will provide a report on our participation in the 28th Shirahama Symposium on Cybercrime, which was held from July 4th to 6th, 2024. First of all, for those who are not familiar with the place "Shirahama" Shirahama refers to a town located in the Nishimuro District of Wakayama Prefecture. It’s a picturesque tourist destination, known for its stunning ocean views, beautiful beaches, and relaxing hot springs. Shirahama is also home to Adventure World, which houses the largest number of pandas in Japan, with four pandas in total. I imagine that the symposium participants not only deepened their knowledge of cybersecurity but also enjoyed the many attractions of Shirahama. Symposium Overview The theme was “How can we address the rapidly changing environment and the increasing complexity of cybercrime?” Although the event was mainly focused on cybercrime, it also included talks and panel discussions on recent general security threats and emerging topics. Based on the philosophy that "cybersecurity cannot be protected by a single organization," this symposium values ​​horizontal connections between companies, government agencies, educational institutions, and other organizations. As a result, I got to hear a lot of ideas and opinions directly from the source, that you could only be gained by being present at the event. The daytime session was held at the Wakayama Prefectural Information Exchange Center Big U , while the evening session shifted to Hotel Seamore , located about 8 km away (I won’t delve into the fact that the daytime venue is technically in neighboring Tanabe City rather than Shirahama Town.) There were numerous interesting talks and presentations at the symposium, but I will highlight two key topics that left a lasting impression on me. For a full program listing, please check out the official website. Key topic 1: Cross-organizational collaboration Networking is regarded as extremely important in these symposiums. The greeting address from the symposium organizing committee leader and several speakers emphasized that no single company or organization can effectively counter threats alone. They highlighted the importance of defending against threats in a holistic, surface-level approach rather than a fragmented, point-based one. This highlights the necessity of collaboration that transcends the boundaries of different industries, as well as the public, private, and academic sectors, to address the complexities and diversities of cyberattacks. It is important to have a common understanding that information sharing between companies, collaboration with government agencies and police agencies, and cooperation with educational institutions are key to achieving stronger security measures. Many police representatives also participated and exchanged views with individuals from private companies. In fact, the first person to invite me to exchange business cards at the symposium was a representative from a police force in a certain prefecture. It was also emphasized that it is difficult for a company to deal with security incidents on its own, and that it is important for each organization to share their experience and know-how and implement effective security measures. During the evening's BOF (Birds of a Feather) event, participants with the same concerns from across organizations and industries gathered and engaged in a lively exchange of opinions. Key topic 2: Generative AI and security There were several talks that covered the trend of generative AI security. The most impressive one was the talk by Fujitsu Laboratories, who provided the latest trends and practical knowledge on generative AI security. The presentation by Fujitsu Laboratories emphasized the importance of addressing security in two ways, protecting systems with AI and ensuring the security of AI itself. Protect with AI : AI as a Cybersecurity Defense AI to prevent security incidents In the field of protection through AI, the existing security coverage is expanding massively as a result of being able to use generative AI as a means of protection. Fujitsu Laboratories introduced their efforts to expand security AI components and create a DevSecOps framework. Protecting AI : Threats and attacks against AI Protecting AI from attacks In the "Protecting AI" section, the risks posed by generative AI were explained in detail. Specific methods of cyber attacks against generative AI and countermeasure approaches were also mentioned. Attacks against AI, including "stealing information" and "deceiving AI," were introduced with concrete examples. The talk was very informative, as it systematically summarized the security aspects that should be considered when building products that utilize generative AI.Brazil For instance, we received useful input for formulating security guidelines for the generative AI development process, as well as examples of guardrails and vulnerability scanners, which will be useful in creating concrete guidelines. TIPS for those attending next year Here are some tips for those who will be attending next year. Securing tickets : The hot spring symposiums (Dogo, Echigo Yuzawa, Atami, Kyushu), including this Shirahama Symposium, are very popular and have platinum ticket prices. Be sure to check the sales start date and secure your tickets early. I also recommend buying lunch (bento) tickets as well. This is due to the limited number of lunch options available in and around the venue. Securing means of transportation : There is a shuttle bus provided by the symposium from Shirahama Station to the venue, but the time is not flexible. It is difficult to get to the venue by public transportation, so you need to be careful about the shuttle bus times. Renting a car is also an option. (I got permission from my company to attend by car, which was really helpful.) Choosing your accommodation : Considering the shuttle bus, it is convenient to choose a place to stay close to the venue (hotel) for the night. The area around the venue for the night is a hot spring resort, so there are many accommodations. Networking : It is advisable to bring plenty of business cards. This is a networking-oriented symposium, so the more you interact with others, the more you'll gain. Summary In cybersecurity, connections across organizations and industries are important. The “straight from the horse’s mouth” ideas, opinions, etc. that you can only get to hear by actually being there are truly invaluable. I am very grateful to the organizing committee members, speakers, sponsors, and all other participants for making the symposium so worthwhile. Next year, how about immersing yourselves in cybersecurity while admiring the beautiful Shirahama sunset as well? Finally The SCoE Group I belong to is seeking new team members to join us. We welcome both those with practical experience in cloud security and those who are interested but have no experience. Please feel free to contact us. For additional details, please check here.
アバター
はじめに こんにちは! KINTO ONE(中古車) のフロントエンド開発をしていますRen.Mです。 この度、KINTOテクノロジーズ株式会社は2024年11月23日(土)に九段下坂上KSビルにて開催される「 JSConf JP 2024 」のプレミアムスポンサーを務めます。 ■JSConf JP 2024について JSConf JP 2024は、日本Node.js協会が主催する日本のJavaScriptフェスティバルです。 日本でのJSConfの開催は今回で5回目となります。 スポンサーブース ブースではJavaScriptにまつわるアンケートを用意しています! 回答いただけた方にはガチャガチャを回していただき、オリジナルノベルティをプレゼントします! 写真はノベルティの一部です! 紙クリップ トートバッグ スポンサーワークショップ ワークショップでは「クルマのサブスクサービスをNext.jsで内製化した経験とその1年後(仮)」について発表します!詳細は以下のリンクからご確認ください! https://jsconf.jp/2024/talk/kinto-technologies/ We Are Hiring! KINTOテクノロジーズでは一緒に働く仲間を探しています! まずは気軽にカジュアル面談からの対応も可能です。少しでも興味のある方は以下のリンクからご応募ください! https://hrmos.co/pages/kinto-technologies/jobs/1955878275904303141 おわりに 興味をお持ちの方はぜひブース、ワークショップまでお越しください! 当日みなさまに会場でお会いできるのを楽しみしています!
アバター
​ Introduction Previously in Part 1, I covered the basics of using variables, adjusting product quantities, and setting subtotals. In this article, I’ll continue from where we left off and explain how to increase the number of items in the cart to two, set a subtotal, establish free shipping conditions, calculate the total amount, and modify the message displayed when free shipping is applied. Let's Make a Shopping Cart Mock-Up Using the Functions of Figma Variables! Part 2 ![](/assets/blog/authors/aoshima/figma2/1.webp =300x) Final layout of the shopping cart [Part 1] What Are Variables Part Creation First Is the Count-Up Function How To Create and Assign Variables Creating a Count-Up Function Subtotal Settings [Part 2] Increasing the Number of Products to Two Subtotal Settings Free Shipping Settings Total Settings Changing the Wording to “Free Shipping” Completed Increasing the Number of Products to Two To have two items in the cart, start by copying the product information from Part 1. Then, update the product images, names, prices, and the quantity displayed in the cart. (Of course, you can also add products using the component variant function for duplication.) ![](/assets/blog/authors/aoshima/figma2/2.webp =300x) Duplicate the original product, and while doing so, change the product name, product image, and price In the following explanation, the original product (SPECIAL ORIGINAL BLEND) will be referred to as "Product A" and the newly copied and added product (BLUE MOUNTAIN BLEND) will be referred to as "Product B". Additionally, just like with Product A, assign the variable “Kosu2” to the quantity of Product B. Refer to Part 1 to set up the count-up function for the plus and minus buttons of Product B. Subtotal Settings This is an application of the subtotal settings made in Part 1. Create and Assign a Variable In Part 2, we assume that the cart contains two products, Product A and Product B, each with a quantity of one. Consequently, we update the value of the local variable ‘Shoukei’ to the total amount of ¥250, calculated as follows: Product A (¥100 x 1) + Product B (¥150 x 1). When you make this change, any numbers on your canvas linked to this variable will automatically update to reflect the new total amount. ![](/assets/blog/authors/aoshima/figma2/3.webp =300x) List of local variables. The red box is the variable assigned to the subtotal number. ![](/assets/blog/authors/aoshima/figma2/4.webp =300x) The subtotal is reflecting the value of the local variable "Shoukei". Give an Action to the Button In Part 1, the subtotal was calculated based on the total amount of Product A only, as shown in the figure below. Select the variable "Shoukei" that you want to update when you click on the plus or minus button for Product A. Then, enter the value of the variable "Kosu1" (which represents the number of items) multiplied by 100 (the unit price of Product A) as the formula to indicate what happens at that time. ![](/assets/blog/authors/aoshima/figma2/5.webp =300x) The subtotal formula set in Part 1 Following this basic principle, we will set the formula to the plus and minus buttons for Products A and B as shown below so that the subtotal will be the sum of the quantities of Products A and B. ![](/assets/blog/authors/aoshima/figma2/6.webp =300x) Settings for the plus button of Product A. The area surrounded by the dotted line is the subtotal setting range. The solid red box shows Product A on the left and Product B on the right. This setting will make the subtotal to be calculated and updated each time you press the plus and minus buttons. By trying the button operation on the preview screen, you can see that the subtotal correctly reflects the total price of the two items. ![](/assets/blog/authors/aoshima/figma2/7.gif =300x) Setting up free shipping Next, I will explain how to set up "Free shipping on purchases over ¥1,000!" The shipping conditions to be set are as follows: If the total is less than ¥1,000, a shipping fee of ¥500 will be added. If the total amount is more than ¥1,000, shipping is free. Create and Assign a Variable First, assign a variable to the number that represents the shipping fee. In this mockup, the initial cart contains one item each, the subtotal is ¥250, and the shipping fee is ¥500. Therefore, we will name the newly created variable “Shipping”, set its value to 500, and assign it to the number next to the shipping fee. ![](/assets/blog/authors/aoshima/figma2/8.webp =300x) The variable "Shipping" is assigned to the number next to the shipping fee Give an Action to the Button Next, set up the button action to calculate the subtotal. The shipping fee will depend on whether the subtotal is less than ¥1,000 or not, so we will use an if statement. If the subtotal is less than ¥1,000, the shipping fee is ¥500, which can be expressed as follows: ![](/assets/blog/authors/aoshima/figma2/9.webp =300x) This formula means that if the subtotal is less than ¥1,000 then the value of "Shipping" should be 500. By the way, you may wonder why we need to enter the same value in "Shipping" because we originally set the value to 500. However, this setting ensures that after the subtotal becomes ¥1,000 or more and the shipping fee is set to ¥0, if the subtotal becomes less than ¥1,000 again, the shipping fee will be reset from ¥0 to ¥500. Next, if the subtotal is ¥1,000 or more, the shipping fee will be ¥0. This can be expressed as shown in the red box below. ![](/assets/blog/authors/aoshima/figma2/10.webp =300x) This means that if the subtotal is ¥1,000 or more, the “Shipping” will be set to 0. By the way, "else" refers to any case that does not meet the conditions set by "if". In this case, "if" refers to when the subtotal is less than ¥1,000, so that means "else" covers when the subtotal is ¥1,000 or more. After applying these settings to each button and previewing it, you will see that the shipping fee changes to "¥0" once the subtotal exceeds ¥1,000. By setting it up this way, the shipping fee will be automatically adjusted according to the subtotal amount. ![](/assets/blog/authors/aoshima/figma2/11.webp =300x) Shipping fee will be ¥0 if the subtotal exceeds ¥1,000 Total Settings Next, let’s move on to setting the total amount. Create and Assign a Variable The variable that indicates the total amount will be abbreviated as "T_Am" for "Total Amount". I apologize for repeating myself, but in this mockup, we assume that the cart contains one of each product, A and B, with a subtotal of ¥250 and a shipping fee of ¥500. Therefore, we will set the initial total amount to 750 for "T_Am". By assigning the variable "T_Am" to the number indicating the total amount, the value "750" will be displayed. ![](/assets/blog/authors/aoshima/figma2/12.webp =300x) The variable is assigned to total amount Give an Action to the Button For the total amount, you will also need to set a conditional branch based on whether the subtotal is less than ¥1,000 or not. The conditions will be the same as the shipping fee settings, so we will add the necessary actions. When you hover your mouse over the if statement, a "+" button will appear with the text "Add nested action." And if you click this button, then a space for additional settings will appear. If you want to add multiple actions under one condition, you can add them in this way: ![](/assets/blog/authors/aoshima/figma2/13.webp =300x) If the subtotal is less than ¥1,000, the total amount will be subtotal + shipping fee, as shown in the red box below. ![](/assets/blog/authors/aoshima/figma2/14.webp =300x) On the other hand, if the subtotal is ¥1,000 or more, the total amount will be the subtotal (with a shipping fee of ¥0) as shown in the red box below. Please note that this is within the "else" statement. ![](/assets/blog/authors/aoshima/figma2/15.webp =300x) After applying the settings to each button and previewing them, you will see that when the subtotal reaches ¥1,000, the shipping fee becomes ¥0 and this change is reflected in the total amount. ![](/assets/blog/authors/aoshima/figma2/16.webp =300x) Modifying the text “free shipping” Finally, we will make some changes to the free shipping text. Here, we would like to hide the "free shipping" text (boxed in red) under the header when shipping becomes free. ![](/assets/blog/authors/aoshima/figma2/17.webp =300x) Create and Assign a Variable Boolean variables are often used when switching between show/hide. A Boolean is a data type used to represent binary conditions such as "true/false" or "yes/no." By the way, in cases like this when we switch between show/hide states, Figma automatically sets "true" as shown and "false" as hidden, so we will use these default settings. First, open Local Variables and press the Create Variable button. Select "Boolean" as the data type. Since this variable is related to the shipping text, we named it "Ship_Txt." In the initial state of the cart, the subtotal will be less than ¥1,000, and the text needs to be displayed, so set the initial value to “true”. ![](/assets/blog/authors/aoshima/figma2/18.webp =300x) A Boolean local variable is created with an initial value of true Next, I will explain the procedure for assigning the variables we have created. First, select the object on the canvas to which you want to assign a variable. Then, take a look at the “Layers” section in the panel on the right side of the screen and right-click the “eye” icon next to Passthrough (Transparency). This icon is not directly shown so it may be difficult to find. Right-clicking will reveal a drop-down menu with a list of variables that can be assigned. From there, select the variable we created earlier. ![](/assets/blog/authors/aoshima/figma2/19.webp =300x) Give an Action to the Button We will also add action settings to set up conditional branching for show/hide text based on the subtotal amount. If the subtotal amount is less than ¥1,000, text will be displayed ("Ship_Txt" = true), so add the text as shown below. ![](/assets/blog/authors/aoshima/figma2/20.webp =300x) Description that changes the Boolean variable "Ship_Txt" to "true" On the other hand, if the subtotal is ¥1,000 or more, the text will be hidden ("Ship_Txt" = false), so add the following code. Please note that this is within the "else" statement. ![](/assets/blog/authors/aoshima/figma2/21.webp =300x) Description that changes the Boolean variable "Ship_Txt" to "false" If you configure the settings for each button and run the preview, you will see how the text automatically hide when the subtotal reaches ¥1,000. ![](/assets/blog/authors/aoshima/figma2/22.webp =300x) I was able to successfully hide the text. However, this leaves extra space, which isn’t ideal from a layout perspective. So I would like to try changing the text itself. Modifying the text “free shipping” ver.2 Create and Assign a Variable Assuming there is or isn’t a shipping fee, we will set up the text to switch between the following two types: If the subtotal is less than ¥1,000: "Only ¥X away from Free shipping!" If the subtotal is ¥1,000 or more: “Free shipping!” I created a component for the free shipping text called "Ship_Txt_Panel" and created two variants. Since we want to toggle between them, we'll enter a Boolean value for each property. ![](/assets/blog/authors/aoshima/figma2/23.webp =300x) First, select the variant above and bring up the property change section in the panel on the right side of the screen. This variant is intended to be displayed initially, so set it to "true". ![](/assets/blog/authors/aoshima/figma2/24.webp =300x) Next, set the property of the variant below to false. ![](/assets/blog/authors/aoshima/figma2/25.webp =300x) Once you have set the properties, place the component instance in the design. While selecting the instance, check the right panel, and you will see a Boolean toggle switch in the Instances section. ![](/assets/blog/authors/aoshima/figma2/26.webp =300x) Selecting an instance placed on the design ![](/assets/blog/authors/aoshima/figma2/27.webp =300x) The toggle switch on the right panel is set to true When you switch this toggle, the content of the instance will change, and you can confirm that the Boolean value has been set. ![](/assets/blog/authors/aoshima/figma2/28.webp =300x) Switch the toggle on the right panel to false ![](/assets/blog/authors/aoshima/figma2/29.webp =300x) The content of the instance will be changed. Furthermore, if you hover the cursor over the toggle switch, an icon for assigning a variable will appear along with the float text. Click on it, and candidate variables will appear. Then, select the Boolean variable “Ship_Txt” from the list and assign it to the instance. ![](/assets/blog/authors/aoshima/figma2/30.webp =300x) Click on the icon in the red box to display the candidate variables. ![](/assets/blog/authors/aoshima/figma2/31.webp =300x) The variable is assigned to the instance. Give an Action to the Button The button action description here is the same as the one which we set earlier to show/hide free shipping, so there is no need to modify it. If you preview it now, you can see that the text changes when the subtotal reaches ¥1,000. ![](/assets/blog/authors/aoshima/figma2/32.webp =300x) Finally, we will set up the amount in the text to change according to the subtotal. Create and Assign a Variable Modify the text within the component, and separate the variable amount part from the rest of the text. ![](/assets/blog/authors/aoshima/figma2/33.webp =300x) The variable amount part is highlighted Next, create a variable to assign to the variable part. Select "Number" as the data type and name it "Extra_Fee". The value of this variable represents the remaining amount needed to reach ¥1,000 for free shipping. Since the subtotal of the cart is ¥250, the difference is ¥1,000 - ¥250 = ¥750, so set the value of "Extra_Fee" to "750." ![](/assets/blog/authors/aoshima/figma2/34.webp =300x) When you assign a variable to the number in the variable part, it will look like this: ![](/assets/blog/authors/aoshima/figma2/35.webp =300x) Give an Action to the Button To make this variable part change according to the increase or decrease in the subtotal, set it as follows. Note that if the subtotal is 1,000 or more, this text will change automatically, so no additional setting is needed. ![](/assets/blog/authors/aoshima/figma2/36.webp =300x) Completed If you preview after setting up each button, you will see that the amount in the text changes when you press the plus (or minus) button, and that the text changes when the subtotal reaches ¥1,000. ![](/assets/blog/authors/aoshima/figma2/37.webp =300x) This concludes the explanation of "Let's create a shopping cart mockup using Figma's variable function!" The features introduced in this article can be applied in various situations, so I hope you find them useful.
アバター
Introduction Hey there! I’m Viacheslav Vorona, an iOS engineer. In August this year, I had the opportunity to participate in iOSDC Japan 2024 , a conference for iOS developers held in Tokyo. It was my first time attending a conference where the sessions were conducted (almost) entirely in Japanese, so I was a bit nervous. However, it turned out to be easier than I expected. Thankfully, when looking at code snippets or listening to topics I’m at least partially familiar with, even if I didn’t catch every single word, I found it wasn’t too hard to follow the presenters. Special thanks to those who included English translations on their slides! That was as helpful as it gets ❤️ Now, I have attended several sessions. There were a couple of talks about curious hobby projects their authors are passionate about, like this session by ta.inoue about the principles behind GPS and demonstrated data sniffing of transmitted signals using an iOS device. It always fascinated me how the GPS system is so simple in principle yet tremendously complex in how it is actually built, so I decided to check this session out and wasn't disappointed. There was also the impressive deep dive into the history and purpose of various UIKit ViewControllers by haseken . Even though we encounter ViewControllers all the time in our job, UIKit is so extensive and some view controllers are so niche that it’s possible you haven’t even heard of some of them (there certainly were quite a few unfamiliar ones for me), so that session was really interesting as well. Today, however, I'd like to talk about a couple of things that I thought were worth keeping in the back of my mind for the future, as they might be useful in practice someday. Let’s take a look, shall we? Practical Use of Hidden APIs Every developer, every now and then, finds themselves in a situation where they need to take a closer look at some third-party code they are utilizing in their projects. We do this to figure out whether a library or framework satisfies the needs of our new project, to better understand the tools we are already using, and sometimes even to track down and report bugs in third-party code. There is, however, a special category of frameworks that we all use daily but are still some of the most obscure: the iOS frameworks, such as SwiftUI and UIKit. Along with the well-documented and recommended APIs, these frameworks have a lot of capabilities we aren’t aware of. Finding and using those capabilities can not only be an interesting exercise but also benefit iOS developers in niche situations. This was the focus of the session titled iOSの隠されたAPIを解明し、開発効率を向上させる方法 (How to unlock hidden iOS APIs and improve development efficiency) by noppe . noppe split his presentation into three parts: Perform : This part was a short introduction on how one could expose hidden methods both in ObjC (by replacing the .h files of the classes we are interested in) and in Swift (by fiddling with .tbd or .swiftinterface files). Use Case : In this part, probably the longest, noppe listed scenarios where hidden APIs could potentially be used: Prototyping: useful and safe, as you can cut corners in non-critical code without impacting functionality, even if those APIs change. Testing: useful and relatively safe, as you can more easily cover some testing scenarios, but it is better to cover the undocumented APIs with tests as well to quickly detect any potential changes. Production: obviously unsafe, not only because the APIs are not guaranteed to perform the same way in the future, but also because your app might get rejected from the App Store. Find : The last part was dedicated to finding hidden APIs primarily through checking .h , .tbd , and .swiftinterface files, analyzing stack traces, and engaging with the community to see what others have found. In his presentation, noppe also provided several examples of situations where hidden APIs might be useful. Let’s take a look at them: For the prototyping stage, one memorable example was related to UITextView . As you may know, although having a placeholder in a text view is a common feature, Apple doesn't provide an accessible API for setting a placeholder. This usually means having to create custom solutions, such as adding label subviews. However, it turns out that UITextView has an unexposed method, setAttributedPlaceholder , that does exactly that. Even though it’s not allowed in production, you can still use it during prototyping or proof of concept stages to save time. An example related to testing involved UIDebuggingInformationOverlay , a tool that was easily accessible prior to iOS 11 but now requires some fiddling to access. It is still possible to enable it by utilizing hidden, low-level features of UIKit. UIDebuggingInformationOverlay Learning about undocumented APIs can offer developers a deeper understanding of the tools they use daily. While using these APIs in production is not recommended, knowing they exist expands the possibilities in situations where unconventional solutions are needed. Additionally, understanding how they work is a great way to improve your own API design skills. Overall, it was a really practical and inspiring session, which I’m glad I attended. @ speakerdeck Server-driven UI As developers, we are usually striving to keep up with the latest trends in the industry, either to be the first ones to dive into a promising framework or technology or simply to avoid being left behind by our more grasping colleagues. At iOSDC this year, however, I stumbled upon a session about a design paradigm I knew little about, even though it has been around for some time. The session was Server-Driven UI入門: 画面のStateを直接受け取るアプローチ (Introduction to Server-Driven UI: An approach to directly receive the screen state) by Nade . Server-driven UI appears somewhat niche, but I feel that keeping an eye on it and at least knowing that it exists is worth the effort. Server-driven UI involves receiving the UI state directly from the backend. It enables changes to the client-side UI without releasing a new version of the app and aims to reduce the amount of client-side business logic. This is achieved by implementing a set of predefined UI components within the client application, which should be simple and easily reusable across different parts of the app. Server responses then dictate which of these reusable UI components should be displayed on each screen, in what order, and what content they should include. In the case of iOS, the approach is even more natural when using SwiftUI, as views can adopt the Codable protocol and essentially mirror the server responses. Nade clearly demonstrated this in his presentation. Of course, adopting such a paradigm leads to certain trade-offs compared to traditional implementations. Let’s take a quick look at them: Server-driven UI Pros: Faster release cycles for new features, as you don’t need to release new app versions, and changes can be made on the backend. All business logic is shared between platforms, resulting in DRYer code, with changes propagated immediately across all clients. With minimal (ideally no) business logic on the client side, developers can focus on aspects like polishing the UI/UX to provide a smoother experience. Server-driven UI Cons: The need to define and build a large set of generic UI elements beforehand, which can be overwhelming for small teams. Testing all possible combinations of these generic UI elements can be costly. Server-side architecture becomes more complex with additional "Backend for Frontend" layers. As you can see, Server-driven UI is a solution most suitable for larger teams capable of managing the added backend complexities and infrastructure. However, it can offer significant benefits in terms of client flexibility and delivery speed. @ speakerdeck In the End iOSDC Japan 2024 was both an entertaining and valuable experience for me. Among the sessions I attended, the two I’ve shared today stood out as the most useful in practice. I hope you find them interesting as well, especially now that the iOSDC organizers have published the session recordings. Thank you, and until next time!
アバター
はじめに こんにちは!新車サブスク開発G、Osaka Tech Lab 所属のhigh-g( @high_g_engineer )です。 本記事では、2024/9/18 に開催された Developers Summit 2024 KANSAI(以下、デブサミ関西)の振り返りをお届けします。 デブサミ関西とは 本家のDevelopers Summit(以下、デブサミ)は、2003年から毎年東京およびオンラインで開催されているソフトウェア開発者向けのカンファレンス型イベントです。 デブサミ関西は、デブサミのスピンオフイベントとして2011年より開催され、関西のITエンジニアのためのお祭りとして親しまれています。 2024年のテーマは、「みんなで創ろう、ニュースタンダード」。 セッションでは、セキュリティ、AI、開発手法、開発生産性、DevOps、エンジニアキャリア等といった幅広いテーマが扱われました。 当日は、どのセッションもほぼ満席となっており、スポンサーブースと併せて、イベント全体で賑わいを見せていました。 https://event.shoeisha.jp/devsumi/20240918 Osaka Tech Lab 初協賛 弊社は、スポンサーブースの出展とスポンサーセッションの登壇で参加させていただきました。 今年度からKINTOテクノロジーズは、様々なイベントに対して協賛をさせていただいておりますが、 Osaka Tech Lab (KINTOテクノロジーズ 大阪オフィスの愛称)としては、イベントへの協賛が初の試みだった為、 どういった内容のブースにするか ノベルティはどういったものにするか 当日の案内をどの様に行うか などの打ち合わせを念入りに行い、万全の体制で当日に臨みました。 スポンサーブースについて 完成したブースはこちら! せっかくなので、いくつかのアイテムに触れていこうと思います。 ![KINTOテクノロジーズのスポンサーブースの完成形](/assets/blog/authors/high-g/20241030/img4.jpg =512x) データで見る Osaka Tech Lab 写真中央にあるグラフや数値などが書かれたボードについてです。 これは、Osaka Tech Labの所属メンバーからヒアリングした情報を可視化したものです。 全体がプラモデルのパーツを模したデザインになっていて面白いですね! 弊社のデザイナーに急遽作成いただいたものですが、とても良い仕上がりです。 ![Osaka Tech Labがグラフが可視化されたボード](/assets/blog/authors/high-g/20241030/img5.jpg =512x) アンケートボード 次に写真右側にある、アンケートボードについてです。 これは、ブース来場者からのアンケートを取るためのボードです。 該当する箇所へシールを貼っていただき、どういった属性の方々がいらっしゃるかを可視化します。 ![シールを貼るアンケート用のボード](/assets/blog/authors/high-g/20241030/img6.jpg =512x) アンケート結果 KINTOやKINTOテクノロジーズに対し、現時点で一定の認知があるものの、アプローチが出来ていない層もまだまだ存在することが分かりました。 職種に関しては、「バックエンド」と「フロントエンド」の間にシールを貼られている方が多く、イベントの性質も影響しているかもしれませんが、関西にはスペシャリストよりもジェネラリスト寄りなエンジニアが多く存在している可能性があることが見えてきました。 Osaka Tech Labの認知拡大の為に重要なデータが取れたと思います。アンケートボードにご協力いただきありがとうございました! ![アンケート結果](/assets/blog/authors/high-g/20241030/img7.jpg =512x) くもびぃ人形 写真左側に鎮座している白いふわふわ。 KINTOの公式マスコットキャラクターの「 くもびぃ 」です。とてもかわいいですよね! ブース来場者に非常に好評で、FindyさんやKIKKAKEさんのXでも触れていただきました。 ありがとうございます! ![Twitter画像_Findy](/assets/blog/authors/high-g/20241030/img8.jpg =512x) ![Twitter画像_Kikkake](/assets/blog/authors/high-g/20241030/img9.jpg =512x) ノベルティ 当日はブースへ来ていただいた方の内、先客100名様に、マルチカードツール(1枚で複数の役割を担うアルミ製のツールセット)をプレゼントさせていただきました。 また、弊社のスポンサーセッションをお聞きいただいた方には、くもびぃの紙クリップも併せて配布させていただきました。 ![マルチカードツール](/assets/blog/authors/high-g/20241030/img10.jpg =512x) ![くもびぃの紙クリップ](/assets/blog/authors/high-g/20241030/img11.jpg =512x) スポンサーセッションについて スピーカーは、Osaka Tech Lab 初期メンバーの沖田さん。 セッションテーマは、「めざせ、PM 兼 モバイルアプリエンジニア!モビリティの未来を大阪から〜トヨタグループで叶える、私とOsaka Tech Labの挑戦〜」 セッションの概要は以下です。 沖田さんのこれまでのキャリア紹介 社内前例がない「PM 兼 モバイルアプリエンジニア」というキャリアへの挑戦 Osaka Tech Labでプロダクトの立ち上げ・開発・運用するための種まき 「想いを消さないこと」というフレーズが印象的で、モチベーションが下がる様なときも諦めず、辞めずに続けてきたから今の沖田さんのキャリアがあるのだと思いました。 おわりに 今回、デブサミ関西に初参加させていただきましたが、平日にもかかわらず、多くの方がイベントに参加されていて非常に驚きました。 私自身、自社ブースのお手伝いをしながら、いくつかのセッションを拝聴させていただいきましたが、 学びになることが多く、ネクストアクションに繋がる様な多くの種が生まれて、イベント全体をとても楽しんでおりました。 幅広い技術領域を扱った大規模カンファレンスは関西では珍しいので、この熱量が絶えず、ずっと続いて欲しいと思いました。 デブサミ関西の運営スタッフの皆様に感謝申し上げます。ありがとうございました。
アバター
[[[Link to Amazon]]]( https://amzn.asia/d/06GXK0Fd ) I’ve been thinking about compiling a summary of the key takeaways from Vision , co-authored by Hans P. Bacher and Sanatan Suryavanshi, to help retain its insights. Since it’s such a valuable book, I’d love to share some of those insights with you here. Visual designs that surround us in our daily lives evoke a wide range of emotions. This book reveals why certain visuals leave a strong impression, and how to understand the psychology behind them. The authors offer practical methods for storytelling through visuals, demonstrating how the selection of colors and shapes can affect emotions. This allows us, even those without professional design backgrounds, to enhance our everyday visual experiences. I believe reading Vision will give us a fresh perspective on our daily lives. If you're interested in this blog post, I suggest taking a look at it. This book consists of: Foreword Introduction The Visual Communication Process The Psychology of Images Line Shape Value Color Light Camera Composition Conclusion In this article, I’d like to provide a brief overview of the sections "The Visual Communication Process," "The Psychology of Images," and "Lines." The Visual Communication Process The authors explain that the visual communication process is an automatic response, where whatever enters the eye immediately triggers a variety of emotions. For instance, just by glancing at a movie poster showing "a shadow stretching in a dim alley" and "a terrified person standing there," we instinctively understand that the film is centered around fear and horror. This instantaneous emotional response is triggered automatically. This book states that its goal is to empower readers to break down these automatic processes into elements and to understand why these feelings are triggered. The following chapter immediately explores the psychological aspects of these automatic processes. The Psychology of Images Why do we feel relaxed or fearful when we look at an image? In describing this process, it mentions three elements of the psychological aspect that images exert. (1) Association (2) Mechanics (3) Resonance (1) Association For example, the combination of a dark alley and a shadow is commonly associated with fear. Thus, images and videos are connected to our past memories, and the brain automatically recalls certain emotions when we see them. This is similar to the process of association. Thus, by carefully choosing and combining the appropriate visual elements, the work can leave a strong and lasting impression on the viewer. (2) Mechanics The combination of elements such as lines, shapes, and colors plays an important role in visual design. For example, placing opposing colors*1 next to each other creates contrast and produces a visual stimulus. In this way, visual elements interact to create stimulation and harmony. (3) Resonance "Resonance is what happens when you align what you are saying with how you are saying it." (from page 20) For example, if bright, pop colors are used in a scene portraying the tragic death of a loved one, the visual style will clash with the content, and the sadness won't resonate with the viewer. The authors emphasize that the appeal of an image can be enhanced by actively combining such design elements as color. They also state that these elements should not be random or accidental but deliberately selected to appeal to the viewer's emotions. The Anatomy of an Image This chapter is about anatomy. The authors explain that it is possible to build a way of 'looking' by dissecting the image using the items listed below, and that this is the first step in visual storytelling. They also recommended referring to it constantly. Subject: Literally, the subject. Format: The shape and proportion of an image. Orientation: Horizontal or vertical aspect. Framing: The arrangement in a composition. Line: The linear component. Shape: The shapes within the frame. Value: The degree of brightness or darkness. Color: Literally, the colors. Pattern: A design or repeated elements. Silhouette: A blacked-in outline of an element in the design. Texture: Indication of the tactile quality of a component. Light: The illuminating element. Depth: A sense of space. Edge: The quality of the separations between the shapes. Movement: Any moving element. Line This refers to "structural lines" and "compositional lines" and create a path for the eyes to travel on. Although it seems elementary and is often overlooked, the authors point out that it encompasses various aspects and holds the potential to enable a wide range of creative productions. The diagrams below show examples of the main lines (partial excerpt). Frame borders. Applicable to all 1 to 4. The top, bottom, left and right border lines that are always present in any composition. 1 and 2: Figures in a composition create structural lines through their orientation. 3: The actual and implied movement of the object forms a clear line. 4: The dark mass create structural lines. Orientation Line direction refers to the orientation of a line in relation to the top, bottom, left, and right edges of the frame. Emotions can be conveyed through the direction of lines. When paired with the right motifs, these lines can express a wide range of deep emotions. Examples) Vertical: Represents strength against gravity and elegance, as seen in tall objects like trees and buildings reaching skyward. Diagonal: In contrast to horizontal and vertical lines, diagonals create drama, energy, and a sense of movement, symbolizing broken balance and motion. Horizontal: Symbolizes calm and tranquility, often associated with horizons, oceans, and expansive open spaces. Placement The placement of the lines divides the frame and creates shapes. The balance of the shapes changes the attractiveness of a composition. Equally divided, symmetrical: Unnatural, artificial. Asymmetrical: Balance makes it attractive. Trisection, golden ratio, etc. Quality The quality and characteristics of the lines evoke strong emotions. Straight lines: Tension Curve: Soft Broad lines: Strong and sturdy Ultra-fine lines: Refinement, delicacy Harmony & Contrast The moment a line is drawn within a frame, it establishes either harmony or contrast. In other words, the interaction between lines generates rhythm, harmony, disharmony, balance, imbalance, unity, and more For instance, a horizontal line at the bottom of a frame creates harmony, but turning it into a diagonal line instantly introduces contrast. However, when harmony or contrast is pushed too far, it can result in boredom or excessive complexity. Therefore, it's essential to strike the right balance between the two. Rhythm Repeating lines establish rhythm and introduce a new dimension to the composition. Regular lines at regular intervals: Orderliness, (boredom) Random repetition: Energetic, tense [Conclusion] The thoughtful use of well-coordinated design elements can function as a powerful mechanism to create visuals that deeply resonate with the viewer. Even a basic element like a line can evoke emotions, create tension, provoke boredom, and establish harmony or contrast. The authors repeatedly emphasize the importance of not getting lost in the details, urging readers to "think simple." They add, "By repeating this process, you will develop a deeper understanding of composition and learn to apply it in your own distinct style." I’ve written the above as an introduction to the opening section of the book and I hope that this brief overview broadens your perspective on visual analysis. I look forward to sharing insights from other chapters if the opportunity presents itself.
アバター
Hi! My name is Ryomm and I am developing my route (iOS) at KINTO Technologies. The other day on July 5th, the Muromachi Information Sharing Meeting Lightning Talk (LT) Tournament 🎋Tanabata Special🎋 was held! This time, I bring you a transcribed version of the lightning talk I gave there, "Master Slack! Be 3000 times more efficient with Slack." See the materials here @ speakerdeck (in Japanese) Motivation Are you making the most of of your Slack? With its variety of features, Slack could help resolve some of the minor frustrations you face at work once you get the hang of it. In this quick guide, we will explore the basics of Slack. As you read, try to think, "I could use this feature for that!" or "It might be interesting to combine these two!" Keep these possibilities in mind as we go along. Mastering "Search" First, the search function! Slack's search function can be used in a variety of ways by making full use of queries. In addition to standard phrase and negative searches like on Google, Slack also lets you filter by date range, search within specific channels, look up messages based on reaction emojis, and even search by the source of shared messages. Of course, you can also search by filter using the GUI without having to remember the query, but if it's something you see often, you can make a note of the query and simply paste it into the search bar to search, which will speed things up. https://slack.com/intl/ja-jp/help/articles/202528808-Slack-内で検索する Mastering “Custom responses” Next is the custom response! You can set any response to slackbot. You can set it by opening the Slackbot customization page. If you call one of the phrases you set in the left part, it will randomly return one of the answers next to it. You can take advantage of these properties to spin the dice randomly, as shown on the right. https://slack.com/resources/using-slack/a-guide-to-slackbot-custom-responses Mastering “Mentions” Use channel mentions and here mentions when you want to spread your message widely. By using @everyone you can mention the entire workspace, however, there aren’t many opportunities to use it. These mentions cannot be used when notifications are turned off or in a thread. Also, generally, mass mentions are more likely to clutter notifications, so think about the time and situation before using them. https://slack.com/help/articles/202009646-Notify-a-channel-or-workspace Mastering “User groups” That’s where user groups come in. You can create user groups to mention multiple people at once, or add groups to a channel. Furthermore, you can register channels associated with a group, so even if you want to add someone to multiple channels for onboarding, you can just add them to the user group. https://slack.com/help/articles/212906697-Create-a-user-group Mastering “Stock-type information” Information can be broadly classified into two types: Stock-type and Flow-type. Stock-type information is accumulated information, and flow-type information is transient information. Regular Slack interactions are flow-type, and stock-type information that should be stored is often summarized in Confluence. There are several ways to keep flow-type information in Slack as stock-type. These are Watch Later, Pin, Canvas, Bookmarks, and Lists. They work well with Workflow and Search, so they are easy to combine and work with. Mastering “Notifications” You can also customize your notifications settings quite freely. You can divide channels into sections, mute and display settings for each, set keywords to notify you when a specific term is called, and use the Reacji Channeler app to forward and notify messages to a specific channel when a certain emoji is used. Mastering “Reminder” You can send a reminder to a specified channel. It can also be set on repeat. It's a good idea to use it in conjunction with the Send function after a workflow or message! https://slack.com/intl/ja-jp/help/articles/208423427-set reminder Mastering “Huddle” You can make calls in Slack using Huddle! The best thing about huddles is that you can retain your chats in Slack! Another advantage is that you can join a call without needing to know the URL, making it easy to jump in and participate. You can also create a URL to join the Huddle, so you can jump in from your Outlook calendar. You can also enjoy the Huddle music while working alone. Mastering “Email forwarding” You can also send emails to a Slack channel. On the mailer side, you can filter the emails you want to share with your team and forward them to the email address for the desired channel. Mastering “Workflow” Workflow is the key to automation in Slack! It can be used in many cases, such as when you want to standardize request templates, when you want to consolidate collected data in a spreadsheet, when you want to combine actions, do onboarding for people who join a channel, etc. It can also be combined with spreadsheets and GAS, and the possibilities are even wider. https://slack.com/intl/ja-jp/help/articles/17542172840595-create workflow---create workflow with Slack Mastering “Custom App” If you want to do something that is difficult to achieve in workflow, you can also use the SlackAPI to create a custom app. With the recent introduction of Slack CLI, building custom apps has become much easier. While coding is still required, the increased flexibility allows for a wide range of possibilities on Slack. https://api.slack.com/docs Conclusion I realized many people might not be very familiar with Slack, so I decided to present it during our Lightning Talk (LT). To my surprise, I received requests to turn it into a blog post! So, here it is. How useful did you find it? If there are any features you weren’t aware of, I encourage you to start trying them out today!
アバター
はじめに この記事は、組織の中でこれからリーダーになる人、または最近リーダーになった人に向けて、リーダー業をこなすにあたって役に立ちそうな考え方を、個人的な視点からまとめたものです。 私自身、KTC(KINTOテクノロジーズ)では2023年11月に初めてチームリーダーを任されることになりましたが、前職含めてそれまでまったくと言っていいほどリーダーを経験したことがありませんでした。なので経験のなさを補うため、アサインが決まったタイミングから「リーダーシップ・マネジメントの考え方」を書籍・Web記事・上司に求め、いくつかの考え方を学んできました。 学んだことすべてを網羅的にご紹介できればよかったのですが、理解が追い付かない・当たり前・今は必要ない・興味が湧かないといった理由で、いまの自分には響かなかったものもあります。それは「いまの自分にはインストール不可である」と諦めて、次の巡り合わせに任せることにしました。 そんな中で、いまの私がインストールした考え方を8個ご紹介します。 偏ったリストですが、何かしら皆さんの仕事のヒントになればうれしいです。 集団で狩ったマンモスを各自で山分けする 「組織のメリットは仲間との結束感だ」と言う人もいます。もちろんそういう面もあるでしょうが、それは副次的な利益です。 マンモスを狩った集団は、まさに同じ釜のメシを食べることになり、結果的に仲良くなったことでしょう。 肉が先にあり、仲間意識は、おまけでついてきます。 安藤 広大 『リーダーの仮面——「いちプレーヤー」から「マネジャー」に頭を切り替える思考法』 チームリーダーになることが決まって最初に手に取ったのが『リーダーの仮面』でした。私はリーダーについて、最初「メンバーのモチベーションを上げる」とか「メンバーと心を通わせる」みたいな側面を主にイメージしていたのですが、そんな中で触れた「識学」のドライさに戦慄した記憶があります。 ですがモデルとしての識学、特に、集団でマンモスを狩るから個々人に分け前が入るという 先に「集団の利益アップ」があり、そのあとに「個人の利益アップ」がある。これが正しい順番です。 という考え方には納得し、判断の指針の1つになっています。 管理職の役割は「目標達成」と「集団維持」 いろいろな考え方があると思うんですが、「PM理論」という、パフォーマンスとメンテナンスの機能に着目した理論があります。 それになぞらえて考えてみると、まずは「目標達成機能」。パフォーマンスの機能は目標達成機能です。メンテナンスは「集団維持機能」ですね。チームを維持したり、チームを活性化したりする役割・機能があるということです。 中間管理職の「過剰負担」は、なぜいつまでも解消しないのか? 見逃しがちな“落とし穴”とマネジメント再構築の4ステップ 引用元の記事では、環境と時代の変化によって目標達成・集団維持どちらも難易度が上がってきていること、最近は集団維持に重きが置かれすぎて戦略策定〜目標達成できる管理者が育たないこと、などが述べられています。 が、その辺の難しいことは置いておいて、シンプルに「管理職の仕事は『目標達成』と『集団維持』である」というフレームを得たことで、管理者である自分が何をしたらいいのかがはっきりしたのが精神衛生上よかったです。 目的を伝えて手段は任せる スタッフや部下のトライアンドエラーを「ロス」ととらえ、スピードを速くするために、最初から正解を教えたり、手取り足取り教えたりしてしまう。この考え方は、絶対にNGです。 経験とともにしか人は成長しません。 (中略) 答えを与える組織は、結果として速度が遅くなります。部下が成長しないので、長い目で見ると速度は落ちるのです。 安藤 広大 『リーダーの仮面——「いちプレーヤー」から「マネジャー」に頭を切り替える思考法』 力量が十分にあると思われる人には「目的だけ」を伝えて、あとは任せるのがいいでしょう。 若干、力量不足かと思われる人については、「目的と、自分ならこうやる」という具体的な行動のヒントを与える。 そして力量が足りていない、まだ未熟だという人については、「目的と行動」を一緒に伝えるということです。 山口 周『外資系コンサルが教えるプロジェクトマネジメント』 マイクロマネジメントはたいていの場合悪手である、というのはなんとなく理解していますが、そもそも自分にマイクロマネジメントし続けるようなキャパシティなどないことはチームリーダー初日から自覚しているので、マイクロじゃないマネジメントを(現在進行形で)模索しています。 実現すべきゴール状態と満たすべき要件だけ握ってあとはメンバーに一任する、一任されても進められるようメンバーをサポートする、という関わり方を目指しています。 好きな仕事なら負担に感じない 好きな仕事なら負担に感じない。それは人それぞれで、単純な量では測れない。 それぞれのメンバーがどんな仕事を好きなのかを掴んでおくと良い。 きちんとタスク・工数管理するのもいいが、手間のわりに劇的な効果はない。 「メンバーの負荷状況が把握できていないので、仕事を依頼するキャパがメンバーにあるかどうか判断できない」という相談をマネージャーにした時にもらったアドバイスです。「負荷状況を把握するために各自のタスクを細かく見たほうがいいですかね?」という質問に対して、「見てもいいけど手間に見合う効果はない。厳密なタスクマネジメントではなく、人の好き嫌いを把握して、それに応じた仕事の割り振りができているかを確認するのがが良いよ」とアドバイスをもらいました。負荷状況は残業時間で把握しつつ、適材適所になるように各自の好き嫌いを把握しておけ、ということです。 細かくタスク・工数管理すると、可視化や合理化のための辻褄合わせなど本質的でないところに時間を取られる気がしましたし、そもそも細かくマネジメントできるような力量も自分にはなさそうでした。なのでそれはやめて、基本的にはメンバーの担当領域に応じて仕事をお願いしつつ、「人の好みに応じて仕事の割り振りができているか?」という観点を意識するようになりました。 時速60kmで交差点に突っ込めるようにする 例外をつくってしまうと、チームや組織は、非常に脆くなります。 「急いでいるから赤信号でも走っていいと思ったんです」 そんな車を1台でも許してしまうと、道路は一気に混乱します。 安藤 広大 『リーダーの仮面——「いちプレーヤー」から「マネジャー」に頭を切り替える思考法』 あなたの周りの業務で「決められたことを 100% 守ってくれる」と信用できるメンバーがどれだけいますか?納期、月初データ処理、エスカレーション、ファイル共有などなど、仕事には様々なルールがあるはずです。逆に信用できないとどうなりますか? 暗黙的に誰かがこっそり監視をしていたり、リマインドしてくれたり、裏でデータやモノを手直ししてくれていたりしませんか?結局、誰かがべったりとタスクに張り付くことになるのです。 これが、疎結合化を阻害する大きな要因となります。 仕事を「疎結合化」デキる人(実践編3)|りなる 業務の仕組み化は日々進めていますが、効率化のためには「担当者が誰にも確認せず単独遂行可能」という領域を増やしていきたいです。不確実な部分が1つでもあれば確認が必要になりますし、事故も起きます。確実なら確認は不要です。ルールがあること、そして確実にそのルールが守られていると誰もが信用できることが重要です。 もちろん、ルールに縛られて本来目指す価値から離れてしまっては本末転倒ですが、基本的には可能な限り、ベースとなるルールをたたき台でもいいので設定するようにしています。 定数と変数と「限りなく定数に近い変数」 林先生と森岡さん共に共通していたことが、この定数と変数を見極めて、変数を動かすこと。つまり、自分の力でどうにかできることに対して人生の時間とエネルギーを使うことが大切である点です。 『定数ではなく変数を動かす』 この考え方は社内の打ち合わせで部長から共有されて学びました。 確かに周りのマネージャーたちを見ていると、流れに逆らってなんとかするというよりは、「力学を見極めたうえで自然とそうなるように状況を整えている」ように感じます。 部長からの共有の中で特に印象的だったのは、 本来は変数だけど今は定数に近いこともある。(ここのミキワメが重要) という点です。 会社の中での文化や、制度や、人の考え方がそれにあたります。それはちょっとやそっとじゃ変わらない定数のような存在ですが、本当は変えられる変数なんだ、ということを忘れないでおくことが重要だと思いました。 人は1回言われたぐらいじゃ忘れる 部下は、「仕事ができない上司」よりも、「何を考えているのかわかりにくい上司」のほうが動きづらいです。 たとえ大事なことでも、1回伝えただけでは、日々の情報のなかに埋もれてしまいます。   指示待ち部下がいなくなる「リーダーの伝える技術」 重要なのは、思考プロセスの中でプロジェクトの目的に立ち返って考えるという行為を繰り返させることで、一種の判断基準になるよう仕向けていく、ということです。 部下から質問が来た時、常のプロジェクトの目的に立ち返らせる質問を返す。こうすることで、プロジェクトチームのメンバーはやがて、判断に迷う際にいつもプロジェクトの目的に立ち返るようになります。 山口 周『外資系コンサルが教えるプロジェクトマネジメント』 私自身忘れっぽい性格で、「前言ったじゃん」と言われてぐぬぬとなることも多々あります。反対に自分が言ったことを相手が忘れている時、コミュニケーションは個人ではなく2者間の問題なので、忘れないように伝えきれていなかった自分にも責任はあると考えています。 共有したい想いや考えは、ことあるごとに口にするぐらいがちょうど良いようです。 上機嫌なリーダーと不機嫌なリーダー エドモンドソンは、心理的安全性を「率直に発言したり懸念や疑問やアイデアを話したりすることによる対人リスクを、人々が安心して取れる環境のこと」と定義している。 「心理的安全性」はなぜ混乱を招き続けるのか | Q by Livesense チームの中で流通する情報の量が減ると、必ずといっていいほど、プロジェクトは危険な状況に陥ります。 (中略) 情報を伝えた相手がどのように反応するか、情報の送り手側が判断できない場合、情報の流通量は低下することになります。 (中略) 結局のところ、上機嫌なリーダーが率いるチームではメンバー相互間、あるいはメンバーとリーダーとの間での情報量が増加するのです。 山口 周『外資系コンサルが教えるプロジェクトマネジメント』 たくさんの後輩やスタッフと仕事をしてきた経験から、「みんなのモチベーションを上げる方法」にかぎって言えば、次のひと言に要約できる。リーダーがだれより本気で楽しそうに働くこと。これに勝る育成法はない。 佐久間 宣行『佐久間宣行のずるい仕事術——僕はこうして会社で消耗せずにやりたいことをやってきた』 シンプルに、上司が不機嫌だと、気まずいし気を遣うのでメンバーは仕事に集中できません(少なくとも私は)。なので基本は上機嫌に、なにを言ってもOKの空気を作ることを心掛けています。 とはいえ、常に本心から上機嫌かと言われるとそうではありませんし、不機嫌にもかかわらず上機嫌を演じていれば心は消耗します。あなたの周りでキツそうなリーダー・マネージャーを見かけたらそっとねぎらってあげてください。 おわりに いかがでしたでしょうか?少しでも皆さんのお仕事に役立つ要素があればうれしいです。 ちなみにKTCにおけるリーダーは、メンバーより偉いとかスキルが高いとかではなく、ただの機能・役割です。組織・事業状況に応じた最適なフォーメーションのためつけ外しも発生します。裏を返せば、リーダーがただの機能ならメンバーもただの機能だと思います。 結局はチームで仕事をしていくので、メンバーが動けばいいわけでもなく、リーダーが抱え込めばいいわけでもなく、チームとして解決できればOKなのだと思います。 気負わずやっていきましょう!
アバター
Introduction Nice to meet you! I’m Hyuga, a producer in the Mobile App Development Group. Today, I’m thrilled to share my first blog post featuring some exciting and fun content! AI generation is a trending topic right now, and in this post, I’ll be diving into the world of AI music generation. This AI music generator is truly impressive! Simply put, all you need to do is provide a few basic instructions, and the AI will generate professional-quality music for you. What's more, it doesn’t just create the accompaniment; it also adds vocals with natural-sounding pronunciation. And it only takes a few minutes to generate. It’s truly nothing short of magical. Experience the ultimate feeling of being a famous music creator! In this post, I’ll share how I used the AI music generation to create a company song for KINTO Technologies spontaneously! What is "Suno AI"? There are various AI music generation tools out there, but the one I used is called Suno AI , developed by a startup based in the United States. Suno, Inc. was founded by four people who originally worked at an AI startup called Kensho: Michael Shulman, Georg Kucsko, Martin Camacho, and Keenan Freyberg. Suno AI was first released in December 2023 and has been continuously updated since then. The latest stable version, v3.5, was released in May 2024 (as of August 2024). Below, I’ll briefly outline the steps for generating music with Suno AI. Please note that since AI evolves at an incredible pace, these steps may change in the future. Consider this as a reference and make sure to check for the most up-to-date information. Visit the website ( https://suno.com/ ) Go to the Suno’s official website. ![](/assets/blog/authors/hyuga/20240814/sunoai1.png =630x) Create an account Sign up for a free account. You can use Google, Discord, Microsoft, or other supported accounts to register. ![](/assets/blog/authors/hyuga/20240814/sunoai2.png =630x) Go to the song creation section Navigate to the "Create" section.​ Enter a text prompt Input your desired prompts, such as song lyrics, style (genre), and more. ![](/assets/blog/authors/hyuga/20240814/sunoai3.png =630x) Generate the song Suno AI will take your prompts and generate a song based on the information you provided.​ Download the song Once the song is ready, you can download it for further editing or share it as is. Creating an original company song with Suno AI (lol) Now let's take a look at the power of Suno AI! If I’m going to do it, it might as well be something fun, so I decided to make an unnoficial company anthem for KINTO Technologies! Here’s the plan! Ask the managers of KINTO Technologies to share their thoughts on the company’s strengths! Use the key phrases from their feedback to generate lyrics with ChatGPT! Input the generated lyrics into Suno AI and let it produce an amazing company song! That’s the basic idea, but I thought... hmm, something is missing... Oh, I know! I’ll sing it myself!!! (lol) So, the plan is to remove the AI-generated vocals and have me, Hyuga, sing the song myself! (lol) New theme: "Using Suno AI to create an original company song and singing it myself (lol) "! Comments from the managers We received some incredible feedback about the company’s strengths! A strong sense of speed, and the belief that as long as you have passion, anyone can take on challenges and excel! We have many engineers proactive about sharing their insights. A modern development environment. A rapidly growing development team. A love for communication, a curiosity for new technologies, with a blend of experienced and newer engineers. If you step up, you can take on various initiatives; your scope is the world, surrounded by talented people. Constantly taking on new challenges. And so on! These are really great comments! The perfect lyrics generated by ChatGPT! I carefully input the managers' comments into ChatGPT, and it generated some awesome lyrics! Yeah, yeah, Here we go! KINTO Technologies, let’s go! With speed and soul, anyone can try Feel the potential, reach for the sky Proactive share, paving future's way Modern environment, innovation's stage We are KINTO Technologies! Friends who love to communicate, With passion for new tech, we strive Let's walk the KINTO path, where dreams thrive With soul, any wall can be climbed Chasing dreams, in an endless sky KINTO Technologies, let’s Go! Pioneering the future, let's go forward! Urgent request While I was writing this article, I received a DM from the person responsible for translating the Tech Blog: "Hyuga-san, could you create an English version of the song??” Whoa! What a surprise! (lol) Of course, there's no reason to turn down such a great request! Without a second thought, I replied, "I can do it!" (lol) However, I felt that simply recreating the same vibe as the Japanese version wouldn't be as interesting. Since it's the English version, I thought it should have more of a Western music feel—something a bit more stylish. So, I decided to generate the English version with the following genre specifications: Japanese version: A refreshing rock song with a strong sense of speed. English version: A calm yet uplifting jazz song. Now, I can't wait to see how it will turn out! A masterpiece was born! (lol) The moment I listened to the finished song, a tear ran down my cheek... It was simply too perfect! It exceeded all expectations! Since we've created the ultimate original company song, I'd love to share it with you! Please give it a listen! First, here’s the Japanese version! https://www.youtube.com/watch?v=zmv06e8cTFI Next is the English version! https://www.youtube.com/watch?v=tCIkXdUv9NA Summary How was it? Aren't these songs amazing, even better than expected? My goal moving forward is to have this original company song officially recognized as our company anthem! (lol) By all means, I encourage you to try this inspiring experience with AI music generation for yourself. Even with a free account, you can generate up to 10 songs per day. Even with a free account, you can generate up to 10 songs per day. Let's take a step into the world of AI-driven music! Thank you for reading until the end.
アバター
はじめに 第2回「KINTOテクノロジーズ MeetUp!」の事務局レポートです! イベントページはこちら 【第2回】KINTOテクノロジーズ MeetUp! - connpass 前回の記事はこちら はじめての「KINTOテクノロジーズ MeetUp!」が開催されるまで | KINTO Tech Blog | キントテックブログ (kinto-technologies.com) KINTOテクノロジーズ MeetUp!(運営スタッフver) | KINTO Tech Blog | キントテックブログ (kinto-technologies.com) 第1回はオフライン限定のイベントでしたが、今回はオンラインからもご参加いただけるよう準備してみました。第1回で得たナレッジを活かしつつ、ハイブリッド開催という新しい形式にチャレンジした今回の事務局の様子をご紹介します! 〜イベント前タスク〜 軽食手配 **食べ物で物足りない。**がないように手配をすすめました。 前回はイベント後半では用意していたピザが足らず、参加していただいた方々から「ちょっと物足りないな・・・」というご意見を頂いておりました。 今回も当初はピザ前提で、物足りないがないように予算も増やしていたのですが、途中でまい泉さんのミニバーガーを知り(教えてもらい)、そちらを提供することにしました。 ミニバーガーが素晴らしい点は下記になります。 個包装されており手に取りやすい そのため、紙皿等を用意する必要がない 多少余っても持ち帰りできるため廃棄の手間がない 常温前提の商品なので、配達時間の自由度が上がる 熱いピザを喰らうことに対しての想いはあったものの、上記メリットを勘案し、今回はミニバーガーにしました。 合わせて、気軽に口にできるように個包装のお菓子も用意しました。 結果は、参加いただいた方に数多く取っていただき、また食べ物についても多少余る程度で完結できたので、成功だったと考えております! ノベルティ手配 **「いかにもって帰りたい、使いたいと思うノベルティを提供するか」**ここを目指して調達から取り掛かりました。 いいイベント+いいノベルティはノベルティを見ただけで当時の楽しい思い出がよみがえると思っています。 ノベルティ選定では実用性に加えて、思わず欲しいと思うか?の視点で選び、当日の配布ではどう配布すればもって帰るだろうかの視点で検討しました。 当日全ノベルティの帰宅は叶いませんでしたが、お持ち帰り頂いた皆さまにはふとした瞬間にノベルティを見て思い出して頂ければ幸いです。 タイムテーブル設計 イベントの進行や流れを決めてしまう重要なファクターであるタイムテーブル設計を任され責任重大でプレッシャーに押しつぶされながら設計を進めておりました。。 そんな中で設計をするにあたって一番意識したことは、「 参加していただいた方を退屈させずにイベントを楽しんでいただけるか 」という点です。 前回MeetUpでのタイムテーブルでは、休憩時間が無かったり、参加者の方との全体写真を撮る時間などを考慮に入れておらず、反省点として挙げられていました。 今回は上記の反省点を踏まえ休憩時間や写真撮影の時間を確保しました。また、前回にはなかったLightning Talkをセッションに含めることによって勢いを出し退屈しないような進行としました。 実際に概ねタイムテーブル通りに進行し滞りなく完了し,会も盛り上がって完了し胸をなでおろしております。 ただ、直前にタイムテーブルの設計を変更しており、事前の考慮が足りなかったと反省しております。 資料準備 資料準備は、実際に登壇者の発表者資料のみならず会場にお越しいただいたお客様へのイベントの案内資料や座談会の座席表,イベント前スタート前の資料などMeetupを円滑に進められるような資料を事前に準備しました。前回のイベントの際には、トイレの場所の案内を口頭でしていたり、WifiのQRコードとかあったら良いよねという反省点を踏まえ今回はそれらをカバーできる資料を作成しました。 集客・広報 企業が行うイベントの集客、皆さん苦労されているかと思います。かくいう私達も悩んだ中で、これはやってよかったなという以下2つをお伝えしたいと思います。 広報文章に登壇内で登場する製品名を含めた 情シスSlackに投稿した 広報文章に登壇内で登場する製品名を含めた Xでのイベント開催告知文章に、最初はconnpass公開・イベント開催前の2回を予定していました。しかし、当初思ったよりも次の大切な2要素が伸びないという課題が出てしまいました。 connpassイベントページの閲覧数 イベント参加人数 この対策として、イベントについて知ってもらう機会を増やすという目的で「Xポストを追加する」ことを考えました。しかし、ただイベントを行うことをポストしても目に留まらずイベントの認知度が低いままかもしれません。そこで、次のように思考をドリルダウンしてポスト文章を作成することにしました。 自分が読み手の時、どのようなツイートであれば目に留まる? ↓ 自分が気になる製品名があると見るかも? ↓ つらかったことを入れると、より想像しやすいかも… 等々、単純なドリルダウンではありますが以上のことから「登壇内容で登場する製品名を含め、さらにそれで何をしたのか」まで含めて文章を作成してみました。 ということで、実際に投稿した文章は以下のようなものです。 これらの投稿をした結果、connpassへのアクセス数は増え、さらに参加者も増えるという悩んでいた課題解決をすることができました!いや~本当に良かった!! 情シスSlackに投稿する イベント当日、現地参加された方何名かに「このイベントをなにで知りましたか?」を質問したところその全員が「情シスSlack」と回答いただきました。圧倒的影響力、すごい…!! というわけで、私も普段からお世話になっている情シスSlackですが情シスやコーポレートITに関わるイベントを開催する場合は #share-event で告知をされるとよいと思います。 今回のイベント自体も他社のコーポレートITとつながる目的もあり、情シスSlackも含めて情シス仲間の輪、本当にあったかいなと思います。今回参加いただいた方、connpassやXで当社を知っていただいた方、これからもどうぞよろしくお願いします! タダ飯客対策 実は以前、KTCが主催した別のイベントに「おそらくご飯目的だろうな」という方が参加されたことがありました。ひたすらお酒を飲み続ける、話しかけようとすると嫌な表情を見せる、など下手をすると暴れかねない雰囲気でした。この経験を通じて、対応するための体制やスタンスをしっかりと整備しようと思いました。 他の皆さんはどうやっているんだろう?というのを調べた結果、対応方針として以下がヒットしまして、参考にさせていただきました! 不審なのが入ってきて騒ぎになった時点で事案確定なので、そうなる前に不審者を弾く 不審なのが入ってきた(入ってこようとした)場合でも、正当な参加者への影響を最小限にできるよう、速やかに対処に移れるよう準備する 懇親会付きのイベントに出没する迷惑な人対策の一考察|wakatono (note.com) 不審者の参加を予防しつつ、排除の手段と根拠を用意しておく、という考え方に基づいて準備しました。 会場となるKINTOテクノロジーズ室町オフィス(コレド室町2)のビル側に相談したところ、「一報もらえれば最悪取り押さえるところまでこちらで対応する」という心強い言葉を頂けたので、その連絡先はイベントスタッフで共有し、何かあれば通報できる状態を作りました。connpassのイベント情報ページには、迷惑行為を禁止することと、該当した場合に退出いただく場合があることを明記しました。 幸いにも今回は懸念していたような事態は起きませんでしたが、何かあった時の動き方を事前に決めておけると、余計な心配なくイベント進行に専念できて良いと思います。 〜イベント中タスク〜 会場設営 前回も実施しており、基本は前回同様で進めました。 ですが、今回は「配信」もあったため、その機材の場所も確保しておりました。 場所については、所有するケーブル類の長さの制限があるので、その制限内で、いかに参加いただいた方がゆっくり見るスペースを確保するか。を考えた上で対応しました。 基本レイアウトは事前に用意していたのですが、当日は参加人数に応じた変更が入り、多少ドタバタしましたが、結果としては参加いただいた方がゆっくり過ごせるスペースが確保できたと考えております。 ですが、座談会のレイアウト図面修正が間に合わず、そのときになって多少混乱が生じてしまいました。。。無念。。 機材設営・接続・コントロール 手持ちの機材には限りがあるので、それらを使ってどのように配信していくかを考えました。オフライン・オンラインのハイブリッド開催になるため、色々な面でケアが必要でした。 結果的に特にトラブルもなく、オンラインの皆さんにも勉強会をお届けすることができ、とても良いイベントとなりました! カメラ ワイプの小さな画面への投影となるので、登壇者のお顔がきちんと見えるように画角を調整しました。配信コントロールに使用する「スイッチャー」に接続する必要があり、配信オペレーション卓(通称「オペ卓」)の近くに設置しつつも、登壇者の正面になるように配置を調整しました。基本的には固定!登壇者の入れ替わり時に身長の差による位置ズレを直せば完璧です。 音響 事前にマイクチェック、会場への音量チェック、オンラインへの音量チェックを行いました。ハイブリッド開催になるためここのチェックは超重要!オンライン・オフラインそれぞれに音割れや、逆に小さすぎて聞こえないなんてことがないように入念にチェックしました。また、発表中は常にオンラインでの音声をチェックし、万が一音飛びや突然の音割れ等があった際にすぐ対応できるように気をつけました。 配信 今回は配信実績のある比較的シンプルな構成で配信することに決まりました。できるだけ複雑なことをせずに、配信中に万が一のトラブルが少なくなるようにしました。 配信映像と同じ映像をプロジェクターに投影し、登壇者からも、発表資料やワイプがどのように配信されているか確認することができるようにしました。また、登壇者の資料とワイプが被らないように、発表中はワイプが四隅を縦横無尽に駆け回りました(なお人力)。 登壇していただいた皆さん各自の使い慣れたPCで発表することができ、映像も乱れることなく運営できたので、こちらも文句なし!問題なく進めることができました。 マイク、資料投影、ワイプ、確認OK! 受付・アテンド・退場時対応 事前準備 前回開催の際も同じメンバーでしたので、大体のナレッジはある状態でしたがコンフルでタスクを洗い出し、各々の担当を振り分けて準備をしました。 イベント当日の役割もこの時点で決めてしまうことで当日にバタバタすることを防ぎました。 いよいよ本番当日 募集を締め切った後すぐに入館証の準備を開始。ビルの入館証のみだと見た目が寂しいのでオリジナルの表紙を用意してもらい、アレンジ! 他のイベントでも取り入れてますが、このひと手間がとっても大事だな。と思ってます^^ 受付スタート 帰宅時間帯ということもあるのでイベント参加者ではない方の出入りも多く、参加者が受付を認識してもらえるようにそれらしき方がいれば大きな声で呼びかけをしました。(たまに全然関係ない方にも声をかけてました、、笑) 今回は受付から16階の会場までのアテンド要員は配置してなかったので、受付から参加者が会場に向かう際は「〇人行きま~す!」のような形で会場の運営チームへSlackで連携を都度しておりました。思い付きでやってたのですが結果的に会場で参加者を待ってくれているメンバーには好評だったので、やって良かった!と思いました! 退場対応 正直に話しますと、、あまり細かくチームでは話しておらず、場面で対応できる人で対応しておりました。お帰りになられる方とエレベーターでイベントの感想を聞く時間が個人的にめっちゃくちゃ楽しかったです!!「楽しかったです~」、「また開催してください~」やら「KINTOテクノロジーズさん、めちゃ楽しそうですね!」等、少し興奮ぎみでお答えいただくことが多く、そんなお声を生で聞けるのはとても得した気分でした♬ 司会進行 ノリと切り替えでなんとかしました!8割くらいは本当にこれで何とかしました。 残りの2割、気を付けた点を共有します。 発表者の発表前にコメントを入れる 現地開催だけだと、発表開始前の人の入れ替え等も目に見えることなのでそこまで気にならないかと思いますが今回はハイブリッド開催。オンラインの方には、カメラで撮影されていること以外は見えないため、変な間が生まれてしまいます。そこで、昭和歌謡が始まる前の前口上のように発表内容についての簡単な紹介や前の発表者の発表内容のまとめ等を入れることでスムーズな入れ替えを目指しました。 現地とオフライン区分けして話すのは最初と締めの挨拶だけ これは時間上の問題が一番大きいですが現地、オンラインに向けたコメントは行わないようにしました。オンラインで見ているとき、現地でしかわからないネタばかり話されてもなんだか置いてけぼりになってイベントに参加している没入感がなくなってしまいますよね。それを意識しました。 オンライン終了後はマイクを使ってあまり話さなかった ここは↑とは逆で、現地感を出したい!という目的で行いました。バンドやアイドルのライブ現場の最後、挨拶だけ地声なことあると思います。そしてそれをされたとき、ライブだ~!!!と思うことがあると思います。あれです。 人前で話すのはなかなかハードルが高いかな、と思っていましたが何とか役目を果たすことができて安心しています。これを読んでいる皆さんもぜひ挑戦してみてはいかがでしょうか。 軽食準備・提供 前回ははじめての社外向けイベントでしたが、この数か月でイベントがたくさん開催されたので、手配も慣れたものです! 今回はまい泉のカツサンドを用意しました🐷 どれもおいしそう・・のきんちゃん どれにしようかな・・のたけちゃん ピザとくらべて手軽に食べられるのがいいですね また、受付済んだら持ってってね~ 食べながらmeet up!参加していいよ~ のスタイルでしたが、おなかがすいている時間(恐らく)なので嬉しいポイントになったのでは! 個数多めに頼みましたがヒレカツサンドがいちばんになくなりました( ..)φメモ 次回の個数調整がんばる。 お酒はビールが人気で3種類用意していますが、他社のイベントに参加したら10種類くらいあって感動・・! 次回は種類増やしてみよう。 カイゼンカイゼン。 〜イベント後タスク〜 ふりかえり チーム活動が終わった時にやることと言えば、「ふりかえり(Retrospective)」ですよね! ふりかえりとは 「ふりかえり」は、活動の節目や終了後に実施する、 「うまくいったこと」や、「うまくいかなかったこと」、「起きたこと」をふりかえる そこから「次に向けた具体的なアクションプラン」について皆で考える ための場となっています。 KINTOテクノロジーズでは、ふりかえりが日常的なイベントとして根付いており、部署を問わず「ふりかえり」や「レトロ」の呼称で普段の会話に良く登場しています。 今回のふりかえり 今回われわれが実施したふりかえりは、「MeetUpを終えた時点での、運営スタッフによるふりかえり」です。 「ふりかえり」に具体的な決まりやルールはありませんが、われわれは良く「KPT(Keep/Problem/Try)」のフレームワークを利用したふりかえりを実施しています。 今回のふりかえりも、KPTを利用しました。イベント運営においては多少なりとも「うまくいかなかった事」や「もっと良くできた事」が考えられるため、そういった「カイゼンのタネ」を拾えるように、KPTを利用する事となりました。 「ふりかえり」の準備 参加するメンバーが多く、皆さんの時間も限られている中で「最高のふりかえり体験」を得るためには、事前準備(ダンドリ)が重要になります。今回は、以下の流れで事前準備をおこないました 皆が自由に書き込めるWikiを作成する(われわれはWikiツールとしてConfluenceを常用しています) ページ内に、KPTフレームワークに沿った書き込みできる枠を準備する(今回は「事前準備」「集客・広報」「当日設営」といった形で、事前にカテゴリごとの枠を作り記入しやすくしていました) ふりかえりに参加するメンバーへ、「当日までに気付いたことを書き込んでね」とSlackでアナウンス ファシリテーターは、ふりかえりの直前にページを確認し、皆さんの記入した内容を咀嚼しながら会の進行のダンドリを考えておく(全体の時間枠に対して、何をどの程度ディスカッションするか?等) 当日のふりかえり ~アイスブレイクからのグランドルール~ さて、ふりかえりが始まりました! 時間がたっぷりあれば、アイスブレイクを兼ねて参加者の皆さんに「今回のイベントで最高だった瞬間」を発言してもらって場を盛り上げるところだったのですが、今回は時間が限られていた事もあり、運営リーダーのポジティブ総評でキックオフさせてもらいました。 アイスブレイクの次は、今回を最高の場にするために、最初に「意見が出やすくなるおまじない(グランドルール)」の説明をします。以下のルールを皆の前で読み上げました。 積極的に会話に参加しましょう! どんなにくだらないことでも、気兼ねなく発言してね! 一人で話しすぎない! 人の発言をさえぎらないこと 話してない人にも思いがある事を理解すること 我々は最善を尽くした事を疑わない! 原因の追究はしても、責任の追及はしない!! 「問題」VS「私たち」の構図を取ること 失敗できたことを良しとして、学びを得られた事を祝いましょう! グランドルールを読み上げたら、いよいよふりかえりの本番です。 当日のふりかえり ~KPTの実施~ 事前に参加者の皆さんが色々と記入してくださったので、進行のイメージが付きやすい状態で始める事ができました。 まずは、上から順に、記載してくださった内容を確認していきます。 ここで重要なのが「記載してくださった方に、内容を読み上げてもらう」です。ファシリテーターが読み上げてしまっても良いのですが、それでは「書いた言葉に込められた想い」まで皆に共有する事はできません。そのため、なるべく「ご自身での読み上げ」を重要視しています。 記載内容の読み上げ その内容を反芻する形で整理し、他の方からの感想や付け足し、フィードバックを受け取る 受け取った内容を整理し、Wikiに追記して整理 アクション提案が出た場合は、皆の合意を得ながらTry項目として整理する といった流れで、時間の許す限りディスカッションが盛り上がる状態を続けます。 最終的には、以下のような形でアクションアイテム(Try)を含めた形でWikiが充実し、最後に皆でイベントの完了を祝いました! 皆で作り上げたふりかえり ふりかえりのふりかえり 今回のふりかえりにより、「次に同じようなイベントを実施する際のアクションアイテム」が作り上げられて、未来の自分たちに託すことができました。 同時に、参加された皆さんの「関係の質」や「思考の質」を向上するための場としても活用できたのでは、と考えます。 このような協調型のイベントを繰り返すことで、「行動の質」や「結果の質」に変化が生まれ、ますます組織として強くなっていく「成功の循環」が回っていく事に期待をしています。 おわりに 各担当者が自律して活動してくれた結果、前回に引き続き大きなトラブルなく、我々にとっても楽しいイベントにすることができたと思います!オフライン・オンラインのハイブリッド開催の実績ができたので、今後も機会があれば今回のナレッジを活用して開催していきます。 今回は、第1回のやり方を踏襲し、省力化しつつ同じ結果を得ることをテーマに活動してみましたが、「標準化」と「創意工夫」のバランスについては考えさせられました。工夫の余地なく「やるだけ」の仕事ならどんどんマニュアル化すればいいです(し、今回もそのつもりでした)が、受付にしても軽食手配にしても、KINTOテクノロジーズが開催するイベントの回を重ねるたびに、創意工夫でどんどん魅力的・効率的になっていっているのを目の当たりにしています。下手にまとめようとするよりも、担当者の自主性と工夫に任せて育てていってもらえるような環境が大切なのかも?と考えさせられました。 そして、「できるだけ多くの人に届けたい」という思いでオンライン開催も取り入れましたが、やはり現地の懇親会で他社の情シスの皆さんと課題を共有する機会は非常に魅力的だと感じました。今後もハイブリッドでやるのか、またオフラインのみのイベントにしてみるのか、色々と悩みつつ引き続き開催していきたいと思います!
アバター
Introduction My name is K. Kane and I am an assistant manager in the Mobile App Development Group. I typically work as a project leader (PL) for the My Route project (PJ) and as an iOS engineer. Recently, we released the My Route iOS app, which can now be launched as a navigation app from the pre-installed Maps app on the iPhone (referred to as the standard Maps). Although many navigation apps offer route settings, there appear to be surprisingly few Japanese websites that explain how to configure this feature. For that reason, I decided to write this article. Differences from ShareExtension On iOS, when you want to share data with other apps, it is common to use ShareExtension. When using ShareExtension to share data that matches the format supported by another app, that app will appear as an option in the share menu's list of available apps. In the case of the standard Maps app, the results of location searches are provided as universal links that begin with https://maps.app/com/? . These links are shared through the regular share menu, allowing you to receive them by setting up the appropriate ShareExtension. On the other hand, when sharing a route, since it involves sharing both the starting point and destination data, the normal sharing menu will not appear. Instead, the route can only be shared with apps configured as route apps. How to set up as a route app To set up a route app, you simply need to add a Capability. There's no need to implement complex logic like ShareExtension (though you will need to handle the processing of the received data, which will be explained later). In the project, select the app's TARGETS, then choose "Signing & Capabilities", and click "+Capability" in the upper left. *Xcode version in the image: 15.4 In the separate window that appears, type “Maps”. From the two options displayed, double-click "iOS, watchOS" to add it. "Maps" will be added under "Signing & Capabilities". Then, select the transportation you want to use for receiving routes. By configuring these settings, your app will appear in the list of route apps. After making these changes, the item shown in the image below will be added to Info.plist. How to extract the data you receive Next, I will explain how to receive the data that is passed when the app is launched through the list of route apps. Data reception is handled by the SceneDelegate class. If the SceneDelegate class does not exist in your project, please add it. I won’t go into detail here, but you can specify the added class in the “Delegate Class Name” in Info.plist. For a SwiftUI app, you can set it within the AppDelegate class specified using @UIApplicationDelegateAdaptor in the struct that inherits from App. import UIKit import MapKit class SceneDelegate: UIResponder, UIWindowSceneDelegate { func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { if let context = connectionOptions.urlContexts.first, MKDirections.Request.isDirectionsRequest(context.url) { printMKDirectionsData(context.url) } } func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) { if let url = URLContexts.first?.url, MKDirections.Request.isDirectionsRequest(url) { printMKDirectionsData(url) } } private func printMKDirectionsData(_ url: URL?) { guard let url else { return } let request = MKDirections.Request(contentsOf: url) if let source = request.source, let destination = request.destination { if !source.isCurrentLocation { print("dep_lat: " + String(source.placemark.coordinate.latitude)) print("dep_lng: " + String(source.placemark.coordinate.longitude)) print("dep_name: " + (source.name ?? "")) } if !destination.isCurrentLocation { print("des_lat: " + String(destination.placemark.coordinate.latitude)) print("des_lng: " + String(destination.placemark.coordinate.longitude)) print("des_name: " + (destination.name ?? "")) } } } } Data is passed from the standard Maps as an instance of the MKDirections.Request class. For details on the MKDirections.Request class, please refer to this link . While the class has properties like departureDate, these do not seem to be set in the data passed from the standard Maps. For simplicity, we are extracting the data within the SceneDelegate class this time. However, in a real-world scenario, the data would be passed to the screen that needs it and processed there. Additional action for Apple review When submitting your app for review by Apple as a routing app, you must include a GeoJSON file in the "Routing App Coverage File" section under the Distribution tab in App Store Connect. This file should specify the geographical areas that your app covers. For more information about GeoJSON files, click the ? button next to the "Routing App Coverage File" and check the linked page that appears. When you upload a GeoJSON file in the correct format, the file name will be displayed as shown below. Once it appears in this state, you can proceed with submitting it for review. Released safely...? In fact, after configuring the settings mentioned above, the My Route iOS app was submitted for review and successfully approved. As a result, we released the app in this state. The published app was successfully linked, and with that, we can conclude by saying, "This is how to receive data as a routing app.” However, the story doesn’t end there—there’s actually more to it Soon after, an unfamiliar warning message started appearing… Just recently, when I uploaded the app to App Store Connect to comply with the Privacy Manifests, I received an email containing a warning message that was completely unrelated to the Privacy Manifests! Below is the actual warning email that was sent: As stated in each warning, it was necessary to add the following settings to Info.plist. Set the Handler rank in MKDirectionsRequest settings Enable “Supports opening documents in place” After making these settings, the Info.plist content will look like the image below. After applying these settings, the warning message disappeared. Conclusion The My Route iOS app receives the starting point and destination from the standard Maps app and then searches for the corresponding route within the My Route app. It appears that other navigation apps function in a similar way, but even apps without built-in map features can be registered as routing apps. By linking with the standard Maps app, they can utilize departure and destination data, potentially broadening the app's capabilities and use cases. I hope this article proves helpful to anyone considering implementing or using route apps.
アバター
👋自己紹介 こんにちは、ふりかえりマイスターを目指している佐々木です。 KINTOテクノロジーズでプロジェクトマネージャ(PjM)をしています。 前職ではPLをしており、アジャイル開発(スクラムやカンバン)にチームで取り組んでいました。 私はふりかえりがとても好きです。前職では、ふりかえりを通じてミニマムな設計ドキュメントを整えたり、CIを推進したり、はたまた新人さんとシニアの間のわだかまりを取り除いたり・・・と、開発にもメンタルケアにも使えてとても助けられました。 はじめに 入社して1年経ち、プロジェクトマネージャとしていくつかリリースとふりかえりを行いました。 イテレーティブな開発サイクルの中で行うスクラムチームのふりかえりと違い、プロジェクトのふりかえりはメンバが毎回違う有期での開発・リリースになります。スプリント単位のふりかえりに比べ、実施タイミング、観点やゴール設定が難しいなと感じました。 また、チームメンバほどの関係性が構築できていない状況でいかに本音を引き出すか、参加メンバにフィットするふりかえりで使用するツールは?フレームワークは?面着でやるの?といった運用面でも気を遣う必要がありました。 今回は、複数のチームが横断で取り組む「プロジェクトのふりかえり」に採用した手法とその理由、および具体的なふりかえり手順と得られた結果について言語化していきたいと思います 🙌 目次 プロジェクトのふりかえり ふりかえりのカタ ふりかえりの設計 ふりかえりの実践 ::: message この記事はこんな人に役立ちます プロジェクトのふりかえりについて課題、解決方法が知りたい ふりかえりの基本形(カタ)について知りたい ふりかえりのカタの使い方・応用を知りたい ::: プロジェクトのふりかえり KINTOテクノロジーズにおける“プロジェクト” KINTOテクノロジーズには、お客さん向けのフロントを担うプロダクト、車を注文する販売店向けのプロダクト、カスタマーセンターを支えるプロダクトなどなど、エンドユーザー向け・バックオフィス向けの様々なプロダクトが存在しています。 契約プラン に関わる変更、 取り扱いブランドの追加 など複数のプロダクトが横ぐしで協調してリリースする必要があったり、ステークホルダーが多いような開発の場合、KINTOテクノロジーズでは プロジェクト という単位で開発を進めます。 プロジェクト進行 各プロダクトはスクラムなどチームごとに違ったスタイルで日々の開発を行っています。 プロジェクトとしては大きな工程・マイルストーンを計画し、要求分析、要件定義など固めたうえで、設計・開発工程はアジャイルに作りこみを実施します。 俗にいう、ハイブリッド開発手法(ウォーターフォール+スクラム)の進め方でプロジェクトを進めていきます。 プロダクトとしてはイテレーティブな開発サイクルで日々の開発を行い、大枠はウォーターフォールでマイルストーンごとの品質や期限を担保するイメージです。 引用元: ハイブリッド開発とは何か? “アジャイル型”との違いや推進体制を解説 今回のプロジェクト これまでKINTO ONEの解約金フリープランでは、契約途中で解約をお申込みする際、電話でのお申込みとなっていました。お客様の使い勝手向上のため、こちらをWEBから申し込みできるようにします。 これとは別にバックオフィスのプロダクトでは、ハンドで行っていた中途解約業務を半自動化して改善するプロジェクトを1年がかりで行っていました。 WEBから解約申し込みできるようになると受付数が増大するため、自動化がセットで必要です。 今回はこの2つのテーマの開発を1つのプロジェクトとしてリリースします。 期間は4か月で、直接関係するチームリーダーや企画メンバ(KINTOメンバ)は総勢20名程度です。 https://corp.kinto-jp.com/news/service_20240219/ 🧙‍♂️ふりかえりの「カタ」 より効果的なふりかえりにするために、私の大好きな本「アジャイルレトロスペクティブズ」で推奨されているやり方を参考にしたいと思います。以下の5つのセクションにわけてふりかえりを進めていきます。 1. 場を設定する アイスブレイク、グランドルール読み合わせなどで意見を出しやすくする 2. データを収集する ふりかえりのもととなる情報を読み込む、ホワイトボードに付箋を貼る 3. アイディアを出す ブレーンストーミングなどのエクササイズでアイディアを言語化する 4. 何をすべきか決定する(アクションアイテムの決定) ドット投票など用いて、参加者で何のアクションに取り組むべきかを決定する 5. クロージング アクションアイテムなどについてまとめ、感謝を伝えてふりかえりを終了する ざっくり内容 ざっくり要約すると、話しやすくしてホワイトボードなどで感じたことを伝えてもらい、それらについてディスカッションしてアクション・改善につなげます。これをなぞる形で当日は進行します。 この”カタ”は主にアジェンダ作成に用いられますが、この本には「開発期間に応じた時間設定」など、ふりかえりに関する細かいTipsなどが載ってるので、要所要所で参考にしながらふりかえりの設計を進めていきます。 興味を持った方は、ぜひアジャイルレトロスペクティブズを読んでみてください! アジャイルレトロスペクティブズ(Amazon) 🏗️ふりかえりの設計 ふりかえりの内容はプロジェクトの性質や参加メンバなどコンテクストにも応じて変えていく必要があります。 私のふりかえりの設計過程を順番に言語化してみます。 前提・制約の確認 目標の設定 進め方の設計・検討 1.前提・制約 まずはふりかえりの前提・制約を整理します。本プロジェクトにはさまざまなチームが参加しています。進行が滞らないようにポイントを整理します。 チームごとのふりかえり文化の違い ふりかえりは定期的に実施してるチーム、そうでないチームがある KPTはやったことがあるがほかのやり方はしらない人もいる ツールの習熟度の違い ホワイトボードを使い慣れていないチームもある Miroを知らない人もいる コンフルなど新たに権限追加が必要な人もいる 参加者の拠点の違い 東京、名古屋、大阪 その他 有期のチーム横断開発となり、プロジェクト後は解散する 💭思ったこと ふりかえり文化の違い 会議予定など見ると、スプリントふりかえりを実施してるチーム/実施していないチーム等、それぞれの文化の違いが顕著でした。以前のプロジェクトではKPTを実施したそうなので、KPTに関しては皆さんご存じのようです。 ツール選定 複数のチームが参加するため、チームによってはツールの習熟度に違いがありました。よくわからないまま参加する会議は心地いいものではありませんから、全員がツールの操作で滞ったりせず、前向きに参加できるようにしたいです。 会議時間の設定 会社全体はわからないですが、前職から比べると私の関係者は会議時間が短めな気がします。 長くて30分で、1時間を超える会議は長いと感じる方が多そうです。 また、チームによっては、プロジェクトのふりかえり自体に積極的じゃないメンバがいる可能性もあるかもしれません(チームでやってるし…的な)。これらを考慮するとなるべく必要最低限でハレーションがおきにくい時間に設定したいです。 実施場所(オンサイト・オフサイト) 拠点が違う方もいるので、面着でやるのかオンラインでやるのかも重要です。面着でやる場合はオンラインのメンバが疎外感を感じないようにする必要があります。 社内のアジャイルチャンネルで質問したところ、皆さんが過去に経験したやり方とその際の注意点を共有してくれました(ハイブリッド開催、Jamboard利用などなど。皆さんありがとう!) 心理的安全性 また、心理的な面の不安もあります。チーム横断で参加するメンバ同士はコミュニケーションが醸成されていないため、本音を引き出すのが難しいです。心理的な安全性をなるべく確保したいと考えました。 さてどうやってすすめよう。 2.目標の設定 自分がPjM・ファシリテーターとしてこのふりかえりで達成したい目標を設定します。 💭思ったこと 私は、ふりかえりを通じて組織を超えた改善につなげたり、サービス自体の横断的な機能改善ができたらいいなと考えていますが、まだまだ関係者との信頼関係を作り始めたところなのでむやみに風呂敷を広げにくいなと思いました。 そこで、 今回はプロジェクトとしての成果の共有や、自分でコントロール可能な範囲(プロジェクト運営)の課題解決にフォーカスしたふりかえり を行っていこうと思います。ディスカッションの中で出た組織横断的な課題・問題点については、いつかの改善のため共通認識とするのにとどめようと思います。 他、組織全体としてインタラクティブなふりかえりに慣れていきたいので、ホワイトボードは絶対に使いたいと思いました。 メインミッション プロジェクトの成果を確認・共有する プロジェクト運営としての改善タスクを確認する サブミッション 主語の大きい課題に対して企画・開発間で共通認識を得る ホワイトボードを使ったインタラクティブなふりかえりの導入 3.進め方の設計・検討 前述の制約を考慮して目標を達成するため、当日のふりかえりの進め方を考えてみます。 1.場を設定する 心理的安全性 ふりかえりは多数のメンバが参加するため、ある程度決まった流れにそって進めていきます。 それらの説明と、この場の心理的安全性を確保するために冒頭にグランドルールを宣言します。 少しずつ伝えたいので、さりげなくホワイトボード上の目に入るところにも置いておきます。 時間設定 アジャイルレトロスペクティブを参考にすると、リリースふりかえりの場合は1日~4日近くの時間を使ってもよいとされていますが、前述の通り1時間だと長く感じる人が多そうですので、めちゃ圧縮して45分程度に設定したいと思います。 2.3 所要時間の決定 レトロスペクティブにはどれだけ時間をかけるか?それは、場合によりけりである。 ~ 中略 ~ 1週間のイテレーションを行うチームなら、1時間のレトロスペクティブで十分だろう。 30日間のイテレーションを行うチームなら、半日で十分だ。 時間を短くすると、いい加減な結果になる。 (リリースおよびプロジェクトのレトロスペクティブは少なくとも1日はかかる。場合によっては4日かかることもある。) 引用:アジャイルレトロスペクティブ 2章より 2.データを収集する ふりかえり文化の違い / ツール選定 KPTはKTC内でもポピュラーな手法であったこと、業務上の基本ツールとしてコンフルを使うことが多いので、アカウントなど準備の手間をクリアしてる コンフルのホワイトボード を使います。 データを収集するエクササイズとしては以下の2つを使用します。 タイムラインについては聞きなれない方もいるでしょうか。それぞれの内容について、詳しく説明します。 タイムライン KPT タイムライン 準備無しでふりかえりをした場合、直近で印象深いことに注目が向くことが多いのではないでしょうか。 タイムラインは過去にあったことを思い出すためのエクササイズです。 期間内で起きた事実やその時の感情を時系列に並べる ことで当時の状況を思い出せるようにしておきます。 引用:タイムラインとは https://anablava.medium.com/a-timeline-retrospective-easy-guide-6385fce0affd 今回、タイムラインはがっつり記載してもらうのではなく、あらかじめPjMが書いたものをさりげなく置いておき、思うところがあれば追加で付箋を貼ってもらうことにします。ドットも使わないことにします。 ※タイムラインを置いておくのは、アジャイルチャンネルのきんちゃんのアイディアを拝借しました。 リリースレトロなので、本当はもっとしっかり感情の情報を集めたいところではありますが、45分という限られた時間なのであっさりめとします。 KPT やったことがある人が多い&仮にやったことが無い人がいてもわかりやすいので、KPTで実施します。 学生時代のオリエンや企業の集合研修などなど、どこかで触れた方が多いのではないでしょうか。 Keep、Problem、Tryを上げていき、それぞれのトピックについて改善点を探すフレームワークです。それぞれの頭文字をとってKTP(ケプト/ケーピーティ)といいます。私はケプトと呼びます。 K eep / できたこと・継続したいこと P roblem / 課題・問題点・改善したいこと T ry / 挑戦したいこと KPTの注意点 ふりかえりの手法として最もメジャーなKPTですが、主語が最初から"問題点"になるのでカドが立ちやすく、ちょっとしたモヤモヤが出しづらかったりします。 また、個人的な意見がハナっから問題点として扱われてしまったりします。 私は、KPTのファシリをする際にはいつもに増して客観的&言葉遣いに気を付けて実施しています。 ※完全に個人的な好みですが、デモなど自分たちの成果のお披露目後に使うなどがおすすめです! (プロダクト機能観点の問題点が開発メンバ自身から出やすくなるため) 4.アイディアを出す KPTのTryでアイディアを出してもらいます。 忙しい人が多いので、事前に書いてもOKとします。 事前に書いておいてもらう場合、KPとTryの関連性が薄れる可能性がありますのでふりかえり当日にも確認する時間を設けてTryの内容を深堀するようにします。 5.何をすべきか決定する(アクションアイテムの決定) スクラムチームのふりかえりではドット投票などでコミットメントを得ますが、今回は限られた時間(45分)で行いますので、ファシリテーションしながらアクションアイテムを選別します。 プロジェクト範囲外の組織課題なども議題に上がるかもしれません。 主語の大きい課題は受け止めつつ、プロジェクト運営としての改善を具体化するように心の準備をします。 🎯ふりかえりの実践 上記の設計を経て、実際におこなったふりかえりをまとめます。 ※ ちょっと細かいですが、新たにふりかえりを導入したい方向けに心がけたことも書いておきます。 1. ふりかえり開催の案内・フォロー(事前準備) 今回のプロジェクト成果の収集についてのお願い ホワイトボードを使う旨の周知、お断り ※ 個別に席で話せたり、会議終わりに頭出しできるならしておくようにします。 忙しい人、事前に書きたい人向けにホワイトボードを事前展開しておきます。 2. 場の設定 グランドルールをあっさり読みあげて話しやすい雰囲気を作ります。 ※ 「ちくちく言葉はだめで~す!」のように、やんわりと注意を呼びかけます。 グランドルール ここは、フィードバックを共有できる安全なスペースです。 - チクチク言葉はつかわない - 共有してもよいと思うものをすべて共有する - 非難ではなく改善に焦点を合わせる - 誰かの付箋を真似したり、付け足すことを歓迎します 3. データの収集 各部署から、プロジェクトとしての具体的な成果を発表していただきました。 電話で受け付けていた解約がWebで申し込めるようになったため、相当な工数削減になったようです! a. タイムラインの記載 モヤモヤしたことやその時の感情について、タイムライン上に任意で記載をお願いしました。 感想としてリリース後も大変だったことがわかります。 こうしたフィードバックはKPTでは出にくいので拾えてよかったです。 b. Keep、Problem、Tryの記載 事前に書いてくれた方、その場で書いた方様々ですがいろいろな意見が集まりました。 忙しい方が多いのでTryまで書いてOKとし、KeepとProblemとセットでTryを書いてもらいました。 ※業務に関わる内容が多いので字をつぶしています 4. アイディアを出す 全ての付箋を簡単によみあげ、あらためてこれまでにあがったKPTの印象を参加者の方に聞きます。 印象を話す中でディスカッションが発生しますので、ファシリしつつ、新しくtryにつながるアイディアがあればふせんにまとめて貼っていきます。 5. アクションアイテムの決定 PjM運営で改善できること・次のプロジェクトで取り組めるようなTryをアクションに落とします。 ※ 業務上見せられるものを抜粋しています 6. クロージング 上記をまとめ、感謝を伝えて解散します。 今回のふりかえりの成果 ふりかえりを通じて以下のような収穫が得られました。 プロジェクトとしての成果 プロジェクトの効果について、関係者で具体的な数値で工数削減を実感できた。 プロジェクトリリースを参加者で喜び合うことができた。 プロジェクトの課題について改善アクションが生まれた。 組織を跨いだ課題(デザイン資料の扱い方など)について共通認識を得ることができた。 その他の成果 結構勇気をだしてホワイトボードを提案したが、すんなり受け入れてもらえた タイムラインでリリース後の苦労などがうかがえ、リリース後運用の安定の重要度を再確認した 上記から、ファシリテーターとして計画していた目標を達成できました 🎉 メインミッション プロジェクトの成果を確認・共有する:達成 プロジェクト運営としての改善タスクを確認する:達成 サブミッション 主語の大きい課題に対して企画・開発間で共通認識を得る:達成 ホワイトボードを使ったインタラクティブなふりかえりの導入:達成 今後に向けて やってみたらホワイトボードやタイムラインなど、皆さんにすんなり受け入れてもらえました。 タイムラインもお披露目できましたので、しばらくしたら4Lなど取り入れてみたいと思います。 時間の制約については、もしかしたら私が遠慮してただけで長めに設定できるかもしれません。 もしくは、リリースのふりかえりだけでなくプロジェクトの節目でふりかえりをとりいれると、時間は45分のままでも程よいタイミングでふりかえりを設定していけるかもしれません。問題が起きたタイミングで改善できるしね! 感想 今回はプロジェクトでのふりかえりについて、私の考えや実施方法をまとめてみました。 同じようにプロジェクトのふりかえりで悩まれてる方がいれば、お力になれると幸いです! ふりかえりはイテレーティブな検査・適応を体現したアジャイルの申し子のような存在です。 みなさんもよいふりかえりライフを!
アバター
Overview We are Mori, Maya S, and Flo from the Global Development Group Business Enhancement Team. This is the second article in a series on KINTO Global Innovation Days, hosted by the Global Development Group. click here for the previous article 👈 In this article, we will report on the three pre-events held over the four days from December 14th to December 19th, as well as the actual Innovation Days. The full schedule of events was as follows: Design Dash Workshop As an organization expands, the tasks of each member are subdivided, and it becomes difficult to see how each member is thinking about how to complete a task if their role is different, even within the same team. To address this issue, we conducted a workshop focused on developing solutions to the challenges faced by the target. In this workshop, participants conducted interviews based on a particular topic, developed a product to solve the interviewee’s problem, and then proposed and demonstrated the solution. This workshop has four objectives: Ideation Rapid Decision Making Discovery Practice Improve Communication We intentionally did not state the objectives at the outset because we wanted participants to discover the learning points for themselves. However, 72% of the participants expressed satisfaction in a survey conducted afterward. Feedback included comments such as, "I gained the ability to identify issues," "I learned how to find solutions within a limited time," "I learned how to design user-centric products," and "I realized the importance of teamwork." This feedback indicates that the objectives were naturally achieved. Communication Workshop As tasks become more subdivided, opportunities for presentations and output also decrease. Some participants rarely had such opportunities in their regular work. While the final pitch of this event provided an opportunity to present, we believed that understanding what others need is a critical skill for the preparation phase. The needs vary depending on the stakeholder’s position, and failing to grasp this can lead to off-target outputs. Therefore, we conducted a communication workshop as part of the preparation, focusing on thoroughly understanding the stakeholder’s positions and situations and identifying their current needs. In this workshop, participants were divided into different roles: copywriters, designers, developers, directors and sales. They shared their concerns within the project and converted them into actionable to-do lists based on their respective roles. This workshop also received a 56% satisfaction rate. Feedback included comments such as, "I learned the importance of sharing essential information," "I learned how to consolidate opinions from people with different focus points and deliver them as a well-integrated deliverable," and "I was able to see the perspectives of different roles." Toyota Way Workshop One of the benefits of holding the Innovation days at KINTO Technologies was the opportunity to learn from the unique practices of the Toyota Group. To this end, we organized a session on the Toyota Production System, which is also the origin of Agile methodologies. While we will omit the specific methods here, the session provided a chance to learn about the Toyota Way and the Toyota Production System, guided by Toyota’s history and the founder’s philosophy. Rather than just receiving information passively, participants were encouraged to share their insights with their teams and make a pledge to uphold the critical mindsets during the following Innovation Days. This also achieved an extremely high level of satisfaction at 72%, with some participants saying, "I was able to understand the Toyota Way not just as words, but also through its history." Innovation Days Building on what we learned in the workshops leading up to the event, the day of Innovation Days has finally arrived. Schedule for the Day 🔻🔻 Opening Ceremony We started with a pre-recorded message from our CEO, followed by a detailed explanation of the rules and an icebreaker activity. Code of Conduct We established the rules by referencing various case studies and emphasized the importance of adhering to the Code of Conduct ✨ Presentation content Presentation time: pitch 5 minutes + Q&A 2 minutes) Approved tools for development Submission method for deliverables Evaluation criteria and points Advice from the organizing team ![code-of-conduct](/assets/blog/authors/M.Mori/20230314/code-of-conduct.png =450x) Icebreaker For the icebreaker, we used Telestration, a drawing-based telephone game. It turned out to be quite challenging for the participants. Ideathon We began by nurturing the initial ideas participants had considered beforehand. Using the Value Proposition Canvas, they analyzed their target, identified the challenges, and explored the value their solutions could offer. Typically, this type of analysis is conducted by product managers (PdMs) in the Global Development G. However, this event provided a rare opportunity for the entire team, including engineers, to participate in the process. Hack Start!!! Now, the actual development started. Each team was assigned to different rooms in the office to start their development work. They had a varied group of members, so some focused not only on coding but also on preparing for the next day's pitch or working on design tasks. The actual development time was about 7.5 hours out of the two days. Within this limited time, each team considered where to prioritize their efforts, how much development to complete, and what key points to emphasize during the Final Pitch. During the two-day Innovation Days, we also had lunch sessions. On Day #1, teams went to lunch together to deepen their ideas. On Day #2, one member from each team joined another team’s lunch to provide feedback on ideas and development content. While these sessions were intended for interaction, the informal discussions also sparked ideas that could benefit not only Innovation Days, but also our regular work. The Final Pitch!!! On the evening of Day #2, everyone gathered for the final pitch. Each team was allotted 5 minutes plus 2 minutes for Q&A. Although we will omit the details of each idea, the pitches ranged from proposals for improving existing products and suggesting new features to introducing new services. Each team delivered unique pitches and demos. The presentation order was decided by drawing lots on the spot to ensure fairness. Not knowing when their turn would come added an element of excitement! Final Jury Review After all the pitches were finished, it was time for the group manager and four assistant managers to evaluate the teams. Although two of them were participating remotely, it left an impression on me to see the four of them concentrating as they judged the teams. Evaluation criteria for judgement is as follows 🔻🔻 Evaluation criteria Ratio Originality 10% UI/UX 10% Tech Skill 30% Team Work 20% Practicality, Feasibility 20% Excitement factor 10% As a result of the evaluation, the winning team was awarded an original smartphone stand and a cake. It was great that even the teams that didn’t win seemed to enjoy participating, creating a great atmosphere in the venue. We removed our masks only during the photo shoot. Summary As KINTO Technologies’ first event, organized by the Global Development G, we not only achieved our primary goal of enhancing communication but also generated new ideas for KINTO and explored new technologies that we hadn’t been able to use in our daily work. The event was well-received by all stakeholders, including participants, managers, and executives. Although we were on the organizing side, we gained various skills as an organizing team, such as responding to emergencies, facilitation, time management, and coordination skills. Most importantly, the bonds within our team were strengthened ✨ So far, we have written about the planning stage and the event itself from the perspective of the organizing team, but we will also be publishing an interview with the winning team from the perspective of the participants. Stay tuned!
アバター
Hi! I’m Ryomm, developing the iOS app my route at KINTO Technologies. I think there are still many scenarios where UITextView is needed, particularly when you want to use TextKit. I tried integrating UITextView with SwiftUI using UIViewRepresentable, but I ran into difficulties adjusting the height. This article details how I resolved that issue. Approach Here’s how you can resolve the issue. import UIKit struct TextView: UIViewRepresentable { var text: NSAttributedString func makeCoordinator() -> Coordinator { Coordinator(self) } func makeUIView(context: Context) -> UITextView { let view = UITextView() view.delegate = context.coordinator view.isScrollEnabled = false view.isEditable = false view.isUserInteractionEnabled = false view.isSelectable = false view.backgroundColor = .clear view.textContainer.lineFragmentPadding = 0 view.textContainerInset = .zero return view } func updateUIView(_ uiView: UITextView, context: Context) { uiView.attributedText = text } func sizeThatFits(_ proposal: ProposedViewSize, uiView: UITextView, context: Context) -> CGSize? { guard let width = proposal.width else { return nil } let dimensions = text.boundingRect( with: CGSize(width: width, height: CGFloat.greatestFiniteMagnitude), options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil) return .init(width: width, height: ceil(dimensions.height)) } } extension TextView { final class Coordinator: NSObject, UITextViewDelegate { private var textView: TextView init(_ textView: TextView) { self.textView = textView super.init() } func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { return true } func textViewDidChange(_ textView: UITextView) { self.textView.text = textView.attributedText } } } Background color is added for clarity Explanation In the makeUIView() function, setting view.isScrollEnabled to false caused an issue. By using setContentHuggingPriority() and setContentCompressionResistancePriority() , line breaks were restored even when scrolling was disabled. However, the vertical display area was not adjusting correctly. When displaying text with more than two lines, any text that exceeded the vertical area was cut off. func makeUIView(context: Context) -> UITextView { let view = UITextView() view.delegate = context.coordinator view.isScrollEnabled = false view.isEditable = false view.isUserInteractionEnabled = false view.isSelectable = true view.backgroundColor = .clear // For example like this? view.setContentHuggingPriority(.defaultHigh, for: .vertical) view.setContentHuggingPriority(.defaultHigh, for: .horizontal) view.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) view.setContentCompressionResistancePriority(.required, for: .vertical) view.textContainer.lineFragmentPadding = 0 view.textContainerInset = .zero return view } (・〜・) So I decided to use sizeThatFits() . This is a method available from iOS 16 that can be overridden in UIViewRepresentable. By using this method, you can specify the size of the view based on the proposed size from the parent view. In this case, I wanted to use NSAttributedString for the text passed to the view, so I calculated the height of the provided text. For the method to calculate the height, I referred to this article . func sizeThatFits(_ proposal: ProposedViewSize, uiView: UITextView, context: Context) -> CGSize? { guard let width = proposal.width else { return nil } let dimensions = text.boundingRect( with: CGSize(width: width, height: CGFloat.greatestFiniteMagnitude), options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil) return .init(width: width, height: ceil(dimensions.height)) } If this is all, the view’s area becomes larger than the size calculated by sizeThatFits() , so I added the following two settings to makeUIView() to remove the padding: textView.textContainer.lineFragmentPadding = 0 textView.textContainerInset = .zero Completed ◎ Conclusion After quite a bit of trial and error, I discovered that using sizeThatFits() gives me the correct size. That insight inspired me to write this article🤓
アバター