Skip to content

Commit

Permalink
Merge pull request #3 from RaunaqMalhotra/replace-api
Browse files Browse the repository at this point in the history
change summary to display 3 lines of blog content
  • Loading branch information
michaeldacanay authored Jun 12, 2023
2 parents 34caefa + d073d41 commit ce32795
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 132 deletions.
Binary file not shown.
23 changes: 12 additions & 11 deletions BlogSmart/BlogSmart/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21678"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21679"/>
<capability name="Image references" minToolsVersion="12.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
Expand Down Expand Up @@ -253,13 +253,13 @@
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" textAlignment="natural" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Wcj-3m-xFZ" userLabel="content">
<rect key="frame" x="0.0" y="32.666666666666686" width="353" height="612.33333333333326"/>
<mutableString key="text">This is the best chocolate chip cookies recipe ever! No funny ingredients, no chilling time, etc. Just a simple, straightforward, amazingly delicious, doughy yet still fully cooked, chocolate chip cookie that turns out perfectly every single time!
<string key="text">This is the best chocolate chip cookies recipe ever! No funny ingredients, no chilling time, etc. Just a simple, straightforward, amazingly delicious, doughy yet still fully cooked, chocolate chip cookie that turns out perfectly every single time!

Everyone needs a classic chocolate chip cookie recipe in their repertoire, and this is mine. It is seriously the Best Chocolate Chip Cookie Recipe Ever! I have been making these for many, many years and everyone who tries them agrees they’re out-of-this-world delicious!

Plus, there’s no funny ingredients, no chilling, etc. Just a simple, straightforward, amazingly delicious, doughy yet still fully cooked, chocolate chip cookie that turns out perfectly every single time!

These are everything a chocolate chip cookie should be. Crispy and chewy. Doughy yet fully baked. Perfectly buttery and sweet.</mutableString>
These are everything a chocolate chip cookie should be. Crispy and chewy. Doughy yet fully baked. Perfectly buttery and sweet.</string>
<fontDescription key="fontDescription" type="system" pointSize="19"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
Expand Down Expand Up @@ -323,15 +323,15 @@ These are everything a chocolate chip cookie should be. Crispy and chewy. Doughy
<rect key="frame" x="0.0" y="103" width="393" height="617"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="PostCell" rowHeight="252" id="mjm-Yl-AqA" customClass="PostCell" customModule="BlogSmart" customModuleProvider="target">
<rect key="frame" x="0.0" y="50" width="393" height="252"/>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="PostCell" rowHeight="184" id="mjm-Yl-AqA" customClass="PostCell" customModule="BlogSmart" customModuleProvider="target">
<rect key="frame" x="0.0" y="50" width="393" height="184"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="mjm-Yl-AqA" id="3UO-qa-6I4">
<rect key="frame" x="0.0" y="0.0" width="393" height="252"/>
<rect key="frame" x="0.0" y="0.0" width="393" height="184"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" alignment="top" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="mJc-oy-y6X" userLabel="Main Stack View">
<rect key="frame" x="16" y="16" width="361" height="220"/>
<rect key="frame" x="16" y="16" width="361" height="152"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="qXA-mI-coS" userLabel="Image Stack View">
<rect key="frame" x="0.0" y="0.0" width="120" height="148.33333333333334"/>
Expand All @@ -352,21 +352,22 @@ These are everything a chocolate chip cookie should be. Crispy and chewy. Doughy
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="top" spacing="7" translatesAutoresizingMaskIntoConstraints="NO" id="BmH-4i-x5v" userLabel="Title Stack View">
<rect key="frame" x="136" y="0.0" width="225" height="217.33333333333334"/>
<rect key="frame" x="136" y="0.0" width="225" height="145.66666666666666"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="How to bake the best cookies" textAlignment="natural" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zrx-gq-EI5" userLabel="Title">
<rect key="frame" x="0.0" y="0.0" width="225" height="67"/>
<constraints>
<constraint firstAttribute="height" constant="67" id="4ZC-Iq-bVw"/>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="67" id="HyN-Tq-biB"/>
</constraints>
<fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="28"/>
<color key="textColor" red="0.86260194690000003" green="0.55305580330000004" blue="0.19676201569999999" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="T2J-SM-SpK" userLabel="Summary">
<rect key="frame" x="0.0" y="74.000000000000014" width="219.66666666666666" height="143.33333333333337"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="T2J-SM-SpK" userLabel="Summary">
<rect key="frame" x="0.0" y="74" width="219" height="71.666666666666686"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="143.33000000000001" id="Vnu-77-PX9"/>
<constraint firstAttribute="height" relation="lessThanOrEqual" constant="143.33000000000001" id="Vnu-77-PX9"/>
</constraints>
<string key="text">This is the AI generated summary. Read this blog to learn how to make the best cookies ever. It will teach you the basics of perfect cookie baking!</string>
<fontDescription key="fontDescription" type="system" pointSize="20"/>
Expand Down
161 changes: 40 additions & 121 deletions BlogSmart/BlogSmart/Write/WriteViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,45 +90,6 @@ class WriteViewController: UIViewController {
post.title = blogTitleField.text
post.content = blogContent.text

// ############################################################
// Load API key
guard let keysFileUrl = Bundle.main.url(forResource: "Keys", withExtension: "plist") else {
fatalError("Couldn't find Keys.plist in the app bundle.")
}
guard let keysData = try? Data(contentsOf: keysFileUrl) else {
fatalError("Couldn't read data from Keys.plist.")
}
guard let keys = try? PropertyListSerialization.propertyList(from: keysData, options: [], format: nil) as? [String: Any] else {
fatalError("Couldn't parse Keys.plist.")
}
guard let apiKey = keys["OPENAI_API_KEY"] as? String else {
fatalError("Couldn't find OPENAI_API_KEY in Keys.plist.")
}


// Create a URL for the request
// In this case, the custom search URL you created in in part 1
let endpoint = "https://api.openai.com/v1/chat/completions"

let headers = [
"Content-Type": "application/json",
"Authorization": "Bearer \(apiKey)"
]

let request = NSMutableURLRequest(url: NSURL(string: endpoint)! as URL)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers

let json: [String: Any] = [
"model": "gpt-3.5-turbo",
"messages": [["role": "user", "content": "\(String(describing: blogContent.text)). \nSummarize this in a 3 sentence paragraph."]],
"temperature": 0.7
]
let jsonData = try? JSONSerialization.data(withJSONObject: json)

// Use the URL to instantiate a request
request.httpBody = jsonData

// loading icon
let activityIndicator = UIActivityIndicatorView(style: .medium)
activityIndicator.center = view.center
Expand All @@ -138,95 +99,53 @@ class WriteViewController: UIViewController {

// Start animating the activity indicator before the network request starts.
activityIndicator.startAnimating()

// Create a URLSession using a shared instance and call its dataTask method
// The data task method attempts to retrieve the contents of a URL based on the specified URL asynchronously.
// When finished, it calls it's completion handler (closure) passing in optional values for data (the data we want to fetch), response (info about the response like status code) and error (if the request was unsuccessful)

let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: { data, response, error in

// Handle any errors
if let error = error {
print("❌ Network error: \(error.localizedDescription)")
}

// Make sure we have data
guard let data = data else {
print("❌ Data is nil")
return
}

// The `JSONSerialization.jsonObject(with: data)` method is a "throwing" function (meaning it can throw an error) so we wrap it in a `do` `catch`
// We cast the resultant returned object to a dictionary with a `String` key, `Any` value pair.
do {
let _ = try JSONSerialization.jsonObject(with: data) as? [String: Any]

// Create a JSON Decoder
let decoder = JSONDecoder()

// Use the JSON decoder to try and map the data to our custom model.
// GPTResponse.self is a reference to the type itself, tells the decoder what to map to.
let response = try decoder.decode(GPTResponse.self, from: data)

// Access the array of tracks from the `results` property
print("\(response.choices[0].message.content)")
post.summary = response.choices[0].message.content

// Set the user as the current user
post.user = User.current

// Save post (async)
post.save { [weak self] result in

// Switch to the main thread for any UI updates
DispatchQueue.main.async {
switch result {
case .success(let post):
print("✅ Post Saved! \(post)")

// Get the current user
if var currentUser = User.current {

// Update the `lastPostedDate` property on the user with the current date.
currentUser.lastPostedDate = Date()

// Save updates to the user (async)
currentUser.save { [weak self] result in
switch result {
case .success(let user):
print("✅ User Saved! \(user)")

// Switch to the main thread for any UI updates
DispatchQueue.main.async {
activityIndicator.stopAnimating()

// Return to previous view controller
self?.navigationController?.popViewController(animated: true)

NotificationCenter.default.post(name: Notification.Name("Go back to the initial screen"), object: nil)
}

case .failure(let error):
self?.showAlert(description: error.localizedDescription)
}
post.summary = blogContent.text

// Set the user as the current user
post.user = User.current

// Save post (async)
post.save { [weak self] result in
// Switch to the main thread for any UI updates
DispatchQueue.main.async {
switch result {
case .success(let post):
print("✅ Post Saved! \(post)")

// Get the current user
if var currentUser = User.current {

// Update the `lastPostedDate` property on the user with the current date.
currentUser.lastPostedDate = Date()

// Save updates to the user (async)
currentUser.save { [weak self] result in
switch result {
case .success(let user):
print("✅ User Saved! \(user)")

// Switch to the main thread for any UI updates
DispatchQueue.main.async {
activityIndicator.stopAnimating()

// Return to previous view controller
self?.navigationController?.popViewController(animated: true)

NotificationCenter.default.post(name: Notification.Name("Go back to the initial screen"), object: nil)
}

case .failure(let error):
self?.showAlert(description: error.localizedDescription)
}

case .failure(let error):
self?.showAlert(description: error.localizedDescription)
}
}

case .failure(let error):
self?.showAlert(description: error.localizedDescription)
}

} catch {
print("❌ Error parsing JSON: \(error.localizedDescription)")
}
})

// Initiate the network request
task.resume()
// ############################################################

}
}
}

Expand Down

0 comments on commit ce32795

Please sign in to comment.